in src/main/java/com/google/firebase/database/snapshot/RangeMerge.java [66:122]
private Node updateRangeInNode(Path currentPath, Node node, Node updateNode) {
int startComparison =
(optExclusiveStart == null) ? 1 : currentPath.compareTo(optExclusiveStart);
int endComparison = (optInclusiveEnd == null) ? -1 : currentPath.compareTo(optInclusiveEnd);
boolean startInNode = optExclusiveStart != null && currentPath.contains(optExclusiveStart);
boolean endInNode = optInclusiveEnd != null && currentPath.contains(optInclusiveEnd);
if (startComparison > 0 && endComparison < 0 && !endInNode) {
// child is completely contained
return updateNode;
} else if (startComparison > 0 && endInNode && updateNode.isLeafNode()) {
return updateNode;
} else if (startComparison > 0 && endComparison == 0) {
assert endInNode;
assert !updateNode.isLeafNode();
if (node.isLeafNode()) {
// Update node was not a leaf node, so we can delete it
return EmptyNode.Empty();
} else {
// Unaffected by range, ignore
return node;
}
} else if (startInNode || endInNode) {
// There is a partial update we need to do
// Collect all relevant children
Set<ChildKey> allChildren = new HashSet<>();
for (NamedNode child : node) {
allChildren.add(child.getName());
}
for (NamedNode child : updateNode) {
allChildren.add(child.getName());
}
List<ChildKey> inOrder = new ArrayList<>(allChildren.size() + 1);
inOrder.addAll(allChildren);
// Add priority last, so the node is not empty when applying
if (!updateNode.getPriority().isEmpty() || !node.getPriority().isEmpty()) {
inOrder.add(ChildKey.getPriorityKey());
}
Node newNode = node;
for (ChildKey key : inOrder) {
Node currentChild = node.getImmediateChild(key);
Node updatedChild =
updateRangeInNode(
currentPath.child(key),
node.getImmediateChild(key),
updateNode.getImmediateChild(key));
// Only need to update if the node changed
if (updatedChild != currentChild) {
newNode = newNode.updateImmediateChild(key, updatedChild);
}
}
return newNode;
} else {
// Unaffected by this range
assert endComparison > 0 || startComparison <= 0;
return node;
}
}