prefixSum(index) {
    /*
     * This function goes up the tree adding the required nodes to sum the
     * prefix.
     *
     * The key here is to sum every node that isn't in the same subtree as an
     * already seen node. In practice we proceed always getting a node's uncle
     * (the sibling of the node's parent). So, if we start at the index 7, we
     *  must go to 6 (7's uncle), then to 4 (6's uncle), then we stop, because
     * 4 has no uncle.
     *
     * Binary-wise, this is the same as erasing the rightmost bit of the index.
     * E.g. 7 (111) -> 6 (110) -> 4 (100).
     *
     *  Note: (index&-index) finds the rightmost bit in index.
     */

    let sum = 0;
    for (; index > 0; index -= index & -index) {
      sum += this._elements[index];
    }
    return sum;
  }
Returns the sum of all values up to specified index in O(log n)