Пример #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;
  }
Пример #2
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;
      }
    }
  }
Пример #3
0
  /**
   * Remove the node if possible or set its count to 0 if it has children and it needs to be kept
   * around
   */
  private Node tryRemove(Node node) {
    if (node == null) {
      return null;
    }

    if (node.weightedCount >= ZERO_WEIGHT_THRESHOLD) {
      --nonZeroNodeCount;
    }

    weightedCount -= node.weightedCount;

    Node result = null;
    if (node.isLeaf()) {
      --totalNodeCount;
    } else if (node.hasSingleChild()) {
      result = node.getSingleChild();
      --totalNodeCount;
    } else {
      node.weightedCount = 0;
      result = node;
    }

    return result;
  }