Beispiel #1
0
        public IncrementQueryObject Combine(IncrementQueryObject rightAdjacentObject)
        {
            var combinedQueryObject = new IncrementQueryObject();

            combinedQueryObject.SubsumeRemainders(this);
            combinedQueryObject.SubsumeRemainders(rightAdjacentObject);

            return(combinedQueryObject);
        }
Beispiel #2
0
    // Instead of returning the children object directly, we have to add on the parent's range addition. The
    // children query object knows the subset of the parent segment it intersects with, and everything in
    // there needs the additions that were applied to the parent segment as a whole. It's kind of weird, any
    // pending range additions specifically for the children object gets brought out and added to the sum when
    // we do .Combine or .Sum, but recursively it makes sense: the children object has a sum but still needs
    // to know about the parent's range additions.
    public IncrementQueryObject Query(
        int treeArrayIndex, int segmentStartIndex, int segmentEndIndex,
        int queryStartIndex, int queryEndIndex)
    {
        var parentQueryObject = _treeArray[treeArrayIndex];

        if (queryStartIndex <= segmentStartIndex && queryEndIndex >= segmentEndIndex)
        {
            return(parentQueryObject);
        }

        int leftChildTreeArrayIndex  = (treeArrayIndex << 1) | 1;
        int rightChildTreeArrayIndex = leftChildTreeArrayIndex + 1;
        int leftChildSegmentEndIndex = (segmentStartIndex + segmentEndIndex) >> 1;
        IncrementQueryObject childrenQueryObject;

        if (queryStartIndex <= leftChildSegmentEndIndex && queryEndIndex > leftChildSegmentEndIndex)
        {
            childrenQueryObject = Query(
                leftChildTreeArrayIndex, segmentStartIndex, leftChildSegmentEndIndex,
                queryStartIndex, queryEndIndex)
                                  .Combine(Query(
                                               rightChildTreeArrayIndex, leftChildSegmentEndIndex + 1, segmentEndIndex,
                                               queryStartIndex, queryEndIndex));
        }
        else if (queryStartIndex <= leftChildSegmentEndIndex)
        {
            childrenQueryObject = Query(
                leftChildTreeArrayIndex, segmentStartIndex, leftChildSegmentEndIndex,
                queryStartIndex, queryEndIndex);
        }
        else
        {
            childrenQueryObject = Query(
                rightChildTreeArrayIndex, leftChildSegmentEndIndex + 1, segmentEndIndex,
                queryStartIndex, queryEndIndex);
        }

        var queryObject = new IncrementQueryObject
        {
            RangeIncrements = parentQueryObject.RangeIncrements
        };

        queryObject.SubsumeRemainders(childrenQueryObject);

        return(queryObject);
    }