public TreeId parent() { Preconditions.checkState(depthLength() > 0, "already at root tree id"); int parentDepthLength = depthIndex(); byte[] parentIndices = new byte[parentDepthLength]; System.arraycopy(this.bucketIndicesByDepth, 0, parentIndices, 0, parentDepthLength); return new TreeId(parentIndices); }
public int leafBucket() { return depthLength() == 0 ? -1 : bucketIndex(depthIndex()).intValue(); }
public LinkedList<TreeId> deglose() { LinkedList<TreeId> path = new LinkedList<>(); { TreeId child = this; while (child.depthLength() > 0) { path.addFirst(child); child = child.parent(); } } return path; }
public boolean contains(final int bucketIndex) { for (int i = 0; i < depthLength(); i++) { if (bucketIndex == bucketIndex(i)) { return true; } } return false; }
/** * Factory method to create a child tree id of this one at with the given bucket id */ public TreeId newChild(int bucketId) { int depthLength = depthLength(); byte[] childIndices = new byte[depthLength + 1]; System.arraycopy(this.bucketIndicesByDepth, 0, childIndices, 0, depthLength); childIndices[depthLength] = (byte) bucketId; return new TreeId(childIndices); }
final List<Integer> quadrantsByDepth = bucketsByDepth(treeBounds, maxDepth); TreeId targetId; if (quadrantsByDepth.size() <= dagId.depthLength()) { targetId = dagId; } else { targetId = TreeId.valueOf(quadrantsByDepth); boolean overflown = size > normalizedSizeLimit(); if (overflown) { int unpromotableBucketIndex = unpromotableBucketIndex(); if (targetId.leafBucket() != unpromotableBucketIndex) { targetId = targetId.newChild(unpromotableBucketIndex);
public static TreeId valueOf(List<Integer> quadrantsByDepth) { byte[] quadpath = new byte[quadrantsByDepth.size()]; for (int i = 0; i < quadrantsByDepth.size(); i++) { quadpath[i] = quadrantsByDepth.get(i).byteValue(); } return new TreeId(quadpath); }
/** * @param quadKey e.g. {@code "[0, 1, 2, 3]"} for quads {@code [SW, NW, NE, SE]} * @return */ public Envelope createBounds(String quadKey) { TreeId id = TreeId.fromString(quadKey); Quadrant[] quads = new Quadrant[id.depthLength()]; for (int i = 0; i < id.depthLength(); i++) { quads[i] = Quadrant.VALUES[id.bucketIndex(i)]; } return createBounds(quads); }
final Envelope treeBounds = RevObjects.boundsOf(original); final int childDepthIndex = rootId.depthLength(); if (quadrant == null) { final int unpromotableBucketIndex = unpromotableBucketIndex(); final boolean rootIsCanonical = rootId.contains(unpromotableBucketIndex); final int normalizedSizeLimit; if (rootIsCanonical) { expandsTo = rootId.newChild(unpromotableBucketIndex); } else { expandsTo = rootId; expandsTo = rootId.newChild(quadrant.getBucketNumber());
public int depthIndex() { return depthLength() - 1; }
private void shrinkIfUnderflow(final DAG dag) { if (dag.numBuckets() == 0) { return; } final long childCount = dag.getTotalChildCount(); // TODO: in the case of quadtrees would need to check if it's an unpromotables bucket and // use canonical's normalized size limit instead? final int depth = dag.getId().depthLength(); final int normalizedSizeLimit = normalizedSizeLimit(depth); if (childCount > normalizedSizeLimit) { return; } Set<NodeId> childrenRecursive = getChildrenRecursiveAndClearBuckets(dag); int collectedSize = childrenRecursive.size(); if (dag.getId().equals(failingDag)) { System.err.printf("expected: %d, collected: %d\n", childCount, collectedSize); } if (collectedSize != childCount) { throw new IllegalStateException(String.format("expected %s, got %s, at: %s", childCount, childrenRecursive.size(), dag)); } dag.clearBuckets(); childrenRecursive.forEach((id) -> dag.addChild(id)); }
/** * Parent becomes child */ private void setParent(DAG child, DAG parent) { // find deepest 1-bucket child while (child.numBuckets() == 1) { child = getOrCreateDAG(child.bucketList().get(0)); } // replace contents of parent with the contents of child parent.init(child); if (LOG.isDebugEnabled()) { LOG.debug("{} collapsed to {}", child.getId(), parent.getId()); } // System.err.println(child.getId() + " collapsed to " + parent.getId()); List<TreeId> buckets = parent.bucketList(); parent.clearBuckets(); for (TreeId id : buckets) { DAG deepChild = getOrCreateDAG(id); TreeId newChildId = parent.getId().newChild(id.leafBucket()); DAG newChild = getOrCreateDAG(newChildId); parent.addBucket(newChildId); setParent(deepChild, newChild); } }
final TreeId sourceBucketId = TreeId.valueOf(builder.bucketsByDepth(geomBounds, maxDepth)); final TreeId targetBucketId = TreeId .valueOf(builder.bucketsByDepth(updateBounds, maxDepth)); TreeId expectedSource = TreeId.fromString( "[2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"); TreeId expectedTarget = TreeId.fromString( "[2, 0, 0, 0, 0, 0, 0, 1, 3, 1, 2, 3, 1, 2, 3, 0, 0, 0, 0, 1, 3, 1, 2, 3]"); assertEquals(expectedSource, sourceBucketId);
final TreeId dagBucketId = bucketDAG.getId(); final Integer bucketIndex = dagBucketId.bucketIndex(depth); TreeBuildTask subtask = new TreeBuildTask(state, bucketDAG, this.depth + 1); subtasks.put(bucketIndex, subtask);
/** * Returns all the DAG's for the argument ids, which must already exist */ public List<DAG> getAll(Set<TreeId> ids) { List<DAG> all = new ArrayList<>(); Set<TreeId> missing = new HashSet<>(); for (TreeId id : ids) { DAG dag; if (ROOT_ID.equals(id)) { dag = ClusteringStrategy.this.root; } else { dag = treeBuff.get(id); } if (dag == null) { missing.add(id); } else { all.add(dag); } } List<DAG> uncached = store.getTrees(missing); all.addAll(uncached); return all; }
for (Entry<Integer, Bucket> e : buckets.entrySet()) { Integer bucketIndex = e.getKey(); TreeId dagBucketId = root.getId().newChild(bucketIndex.intValue()); ObjectId bucketId = e.getValue().getObjectId();
public @Override int bucket(Node node, int depth) { NodeId nodeId = computeId(node); TreeId bucketId = computeBucketId(nodeId, depth); int leafBucket = bucketId.leafBucket(); return leafBucket; }
final List<Integer> quadrantsByDepth = bucketsByDepth(treeBounds, maxDepth); TreeId targetId; if (quadrantsByDepth.size() <= dagId.depthLength()) { targetId = dagId; } else { targetId = TreeId.valueOf(quadrantsByDepth); boolean overflown = size > normalizedSizeLimit(); if (overflown) { int unpromotableBucketIndex = unpromotableBucketIndex(); if (targetId.leafBucket() != unpromotableBucketIndex) { targetId = targetId.newChild(unpromotableBucketIndex);
public static TreeId valueOf(List<Integer> quadrantsByDepth) { byte[] quadpath = new byte[quadrantsByDepth.size()]; for (int i = 0; i < quadrantsByDepth.size(); i++) { quadpath[i] = quadrantsByDepth.get(i).byteValue(); } return new TreeId(quadpath); }
/** * @param quadKey e.g. {@code "[0, 1, 2, 3]"} for quads {@code [SW, NW, NE, SE]} * @return */ public Envelope createBounds(String quadKey) { TreeId id = TreeId.fromString(quadKey); Quadrant[] quads = new Quadrant[id.depthLength()]; for (int i = 0; i < id.depthLength(); i++) { quads[i] = Quadrant.VALUES[id.bucketIndex(i)]; } return createBounds(quads); }