in spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/PrefixTree.java [116:153]
private Node putImpl(Node node, String key, int offset, Query.KeyQuery value) {
final int prefixLength = node.prefix.length();
final int keyLength = key.length() - offset;
final int commonLength = commonPrefixLength(node.prefix, key, offset);
if (commonLength == 0 && prefixLength > 0) {
// No common prefix
Node n = addQuery(new Node(key.substring(offset), EMPTY), value);
return new Node("", new Node[] {n, node});
} else if (keyLength == prefixLength && commonLength == prefixLength) {
// Fully matches, add the value to this node
addQuery(node, value);
return node;
} else if (keyLength > prefixLength && commonLength == prefixLength) {
// key.startsWith(prefix), put the value into a child
int childOffset = offset + commonLength;
int pos = find(node.children, key, childOffset);
if (pos >= 0) {
Node n = putImpl(node.children[pos], key, childOffset, value);
return node.replaceChild(n, pos);
} else {
Node n = addQuery(new Node(key.substring(childOffset), EMPTY), value);
return node.addChild(n);
}
} else if (prefixLength > keyLength && commonLength == keyLength) {
// prefix.startsWith(key), make new parent node and add this node as a child
int childOffset = offset + commonLength;
Node n = new Node(node.prefix.substring(commonLength), node.children, node.inQueries, node.otherQueries);
return addQuery(new Node(key.substring(offset, childOffset), new Node[] {n}), value);
} else {
// Common prefix is a subset of both
int childOffset = offset + commonLength;
Node[] children = {
new Node(node.prefix.substring(commonLength), node.children, node.inQueries, node.otherQueries),
addQuery(new Node(key.substring(childOffset), EMPTY), value)
};
return new Node(node.prefix.substring(0, commonLength), children);
}
}