@Override public NodeId computeId(Node node) { String name = node.getName(); return new NodeId(name); }
@VisibleForTesting List<Quadrant> quadrantsByDepth(NodeId node, final int maxDepth) { final Envelope nodeBounds = node.value(); List<Integer> bucketsByDepth = bucketsByDepth(nodeBounds, maxDepth); List<Quadrant> quads = new ArrayList<>(bucketsByDepth.size()); for (int depthIndex = 0; depthIndex < bucketsByDepth.size(); depthIndex++) { int bucket = bucketsByDepth.get(depthIndex).intValue(); if (bucket == unpromotableBucketIndex(depthIndex)) { break; } Quadrant quad = Quadrant.VALUES[bucket]; quads.add(quad); } return quads; }
private byte[] toKey(NodeId nodeId) { byte[] key = nodeId.name().getBytes(Charsets.UTF_8); return key; }
public static void write(NodeId id, DataOutput out) throws IOException { checkNotNull(id); checkNotNull(out); final String name = id.name(); @Nullable final Object value = id.value(); final FieldType valueType = FieldType.forValue((Object) id.value()); out.writeUTF(name); out.writeByte(valueType.ordinal()); DataStreamValueSerializerV2.INSTANCE.encode(valueType, value, out); }
@Test public void testEncodeCanonicalNodeIds() throws Exception { ByteArrayDataOutput out = ByteStreams.newDataOutput(); List<NodeId> nodes = new ArrayList<>(); int size = 10; for (int i = 0; i < size; i++) { NodeId n = new NodeId("node-" + i); nodes.add(n); NodeId.write(n, out); } ByteArrayDataInput in = ByteStreams.newDataInput(out.toByteArray()); List<NodeId> decoded = new ArrayList<>(); for (int i = 0; i < size; i++) { NodeId n = NodeId.read(in); decoded.add(n); } assertEquals(nodes, decoded); }
public static DAG deserialize(TreeId id, DataInput in) throws IOException { final ObjectId treeId = ObjectId.readFrom(in); final STATE state = STATE.values()[in.readByte() & 0xFF]; final long childCount = Varint.readUnsignedVarLong(in); final int childrenSize = Varint.readUnsignedVarInt(in); final int bucketSize = Varint.readUnsignedVarInt(in); Set<NodeId> children = ImmutableSet.of(); Set<TreeId> buckets = ImmutableSet.of(); if (childrenSize > 0) { children = new HashSet<>(); for (int i = 0; i < childrenSize; i++) { NodeId nid = NodeId.read(in); children.add(nid); } } if (bucketSize > 0) { buckets = new HashSet<>(); for (int i = 0; i < bucketSize; i++) { final int len = Varint.readUnsignedVarInt(in); final byte[] bucketIndicesByDepth = new byte[len]; in.readFully(bucketIndicesByDepth); buckets.add(new TreeId(bucketIndicesByDepth)); } } DAG dag = new DAG(id, treeId, childCount, state, children, buckets); return dag; }
public static void serialize(DAG dag, DataOutput out) throws IOException { final ObjectId treeId = dag.originalTreeId; final STATE state = dag.getState(); final long childCount = dag.getTotalChildCount(); final Collection<NodeId> children = dag.children.values(); final Set<TreeId> buckets = dag.buckets; treeId.writeTo(out); out.writeByte(state.ordinal()); Varint.writeUnsignedVarLong(childCount, out); Varint.writeUnsignedVarInt(children.size(), out); Varint.writeUnsignedVarInt(buckets.size(), out); for (NodeId nodeid : children) { NodeId.write(nodeid, out); } for (TreeId tid : buckets) { byte[] bucketIndicesByDepth = tid.bucketIndicesByDepth; Varint.writeUnsignedVarInt(bucketIndicesByDepth.length, out); out.write(bucketIndicesByDepth); } }
@Test public void testEncodeQuadTreeNodeIds() throws Exception { ByteArrayDataOutput out = ByteStreams.newDataOutput(); List<NodeId> nodes = new ArrayList<>(); int size = 10; for (int i = 0; i < size; i++) { Envelope env = new Envelope(i, i + 1, i, i + 1); NodeId n = new NodeId("node-" + i, env); nodes.add(n); NodeId.write(n, out); } ByteArrayDataInput in = ByteStreams.newDataInput(out.toByteArray()); List<NodeId> decoded = new ArrayList<>(); for (int i = 0; i < size; i++) { NodeId n = NodeId.read(in); decoded.add(n); } assertEquals(nodes, decoded); } }
public static void write(NodeId id, DataOutput out) { checkNotNull(id); checkNotNull(out); final String name = id.name(); @Nullable final Object value = id.value(); final FieldType valueType = FieldType.forValue((Object) id.value()); try { out.writeUTF(name); out.writeByte(valueType.ordinal()); DataStreamValueSerializerV2.INSTANCE.encode(valueType, value, out); } catch (IOException e) { throw new RuntimeException(e); } }
@Override public NodeId computeId(Node node) { String name = node.getName(); return new NodeId(name); }
public boolean containsNode(NodeId node) { return children.containsKey(node.name()); }
@VisibleForTesting List<Quadrant> quadrantsByDepth(NodeId node, final int maxDepth) { final Envelope nodeBounds = node.value(); List<Integer> bucketsByDepth = bucketsByDepth(nodeBounds, maxDepth); List<Quadrant> quads = new ArrayList<>(bucketsByDepth.size()); for (int depthIndex = 0; depthIndex < bucketsByDepth.size(); depthIndex++) { int bucket = bucketsByDepth.get(depthIndex).intValue(); if (bucket == unpromotableBucketIndex(depthIndex)) { break; } Quadrant quad = Quadrant.VALUES[bucket]; quads.add(quad); } return quads; }
public static NodeId read(DataInput in) throws IOException { final String name = in.readUTF(); FieldType type = FieldType.valueOf(in.readUnsignedByte()); final Object val = DataStreamValueSerializerV2.INSTANCE.decode(type, in); return new NodeId(name, val); } }
private byte[] toKey(NodeId nodeId) { byte[] key = nodeId.name().getBytes(Charsets.UTF_8); return key; }
/** * Returns the bucket index in the range 0-3 corresponding to this node at the specified depth * (i.e. the bucket index represents a quadrant), or {@code -1} if the spatial bounds of this * node don't fit on a single child quadrant and hence the node shall be kept at the current * tree node (hence creating a mixed {@link RevTree} with both direct children and buckets). */ public @Override int bucket(final NodeId nodeId, final int depthIndex) { final Envelope nodeBounds = nodeId.value(); final Quadrant quadrantAtDepth = computeQuadrant(nodeBounds, depthIndex); if (quadrantAtDepth == null) { return -1; } return quadrantAtDepth.ordinal(); }
/** * @return a {@link NodeId} whose {@link NodeId#value() value} is the node's * {@link Node#bounds() bounds} {@link Envelope} or {@code null} */ @Override public NodeId computeId(final Node node) { @Nullable Envelope bounds = node.bounds().orNull(); return new NodeId(node.getName(), bounds); }
public boolean containsNode(NodeId node) { return children.containsKey(node.name()); }
/** * Returns the bucket index in the range 0-3 corresponding to this node at the specified depth * (i.e. the bucket index represents a quadrant), or {@code -1} if the spatial bounds of this * node don't fit on a single child quadrant and hence the node shall be kept at the current * tree node (hence creating a mixed {@link RevTree} with both direct children and buckets). */ @Override public int bucket(final NodeId nodeId, final int depthIndex) { final Envelope nodeBounds = nodeId.value(); final Quadrant quadrantAtDepth = computeQuadrant(nodeBounds, depthIndex); if (quadrantAtDepth == null) { return -1; } return quadrantAtDepth.ordinal(); }
public static NodeId read(DataInput in) throws IOException { final String name = in.readUTF(); FieldType type = FieldType.valueOf(in.readUnsignedByte()); final Object val = DataStreamValueSerializerV2.INSTANCE.decode(type, in); return new NodeId(name, val); } }