private Node updateRangeInNode()

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;
    }
  }