Example #1
0
  private Node merge(Node node, Node other) {
    if (node == null) {
      return copyRecursive(other);
    } else if (other == null) {
      return node;
    } else if (!inSameSubtree(node.bits, other.bits, Math.max(node.level, other.level))) {
      return makeSiblings(node, copyRecursive(other));
    } else if (node.level > other.level) {
      long branch = other.bits & node.getBranchMask();

      if (branch == 0) {
        node.left = merge(node.left, other);
      } else {
        node.right = merge(node.right, other);
      }
      return node;
    } else if (node.level < other.level) {
      Node result = createNode(other.bits, other.level, other.weightedCount);

      long branch = node.bits & other.getBranchMask();
      if (branch == 0) {
        result.left = merge(node, other.left);
        result.right = copyRecursive(other.right);
      } else {
        result.left = copyRecursive(other.left);
        result.right = merge(node, other.right);
      }

      return result;
    }

    // else, they must be at the same level and on the same path, so just bump the counts
    double oldWeight = node.weightedCount;

    weightedCount += other.weightedCount;
    node.weightedCount = node.weightedCount + other.weightedCount;
    node.left = merge(node.left, other.left);
    node.right = merge(node.right, other.right);

    if (oldWeight < ZERO_WEIGHT_THRESHOLD && node.weightedCount >= ZERO_WEIGHT_THRESHOLD) {
      nonZeroNodeCount++;
    }

    return node;
  }
Example #2
0
  private Node makeSiblings(Node node, Node sibling) {
    int parentLevel = MAX_BITS - Long.numberOfLeadingZeros(node.bits ^ sibling.bits);

    Node parent = createNode(node.bits, parentLevel, 0);

    // the branch is given by the bit at the level one below parent
    long branch = sibling.bits & parent.getBranchMask();
    if (branch == 0) {
      parent.left = sibling;
      parent.right = node;
    } else {
      parent.left = node;
      parent.right = sibling;
    }

    return parent;
  }
Example #3
0
  private void insert(long bits, double weight) {
    long lastBranch = 0;
    Node parent = null;
    Node current = root;

    while (true) {
      if (current == null) {
        setChild(parent, lastBranch, createLeaf(bits, weight));
        return;
      } else if (!inSameSubtree(bits, current.bits, current.level)) {
        // if bits and node.bits are not in the same branch given node's level,
        // insert a parent above them at the point at which branches diverge
        setChild(parent, lastBranch, makeSiblings(current, createLeaf(bits, weight)));
        return;
      } else if (current.level == 0 && current.bits == bits) {
        // found the node

        double oldWeight = current.weightedCount;

        current.weightedCount += weight;

        if (current.weightedCount >= ZERO_WEIGHT_THRESHOLD && oldWeight < ZERO_WEIGHT_THRESHOLD) {
          ++nonZeroNodeCount;
        }

        weightedCount += weight;

        return;
      }

      // we're on the correct branch of the tree and we haven't reached a leaf, so keep going down
      long branch = bits & current.getBranchMask();

      parent = current;
      lastBranch = branch;

      if (branch == 0) {
        current = current.left;
      } else {
        current = current.right;
      }
    }
  }