Example #1
0
        /// <summary>Called by DoSingleOperation to split a full node, then retry the add operation.</summary>
        /// <remarks>Same arguments and return value as DoSingleOperation.</remarks>
        internal virtual int SplitAndAdd(ref AListSingleOperation <K, T> op, out AListNode <K, T> splitLeft, out AListNode <K, T> splitRight)
        {
            // Tell DoSingleOperation not to send notifications to the observer
            op.AggregateChanged |= 2;

            int divAt = _list.Count >> 1;
            var mid   = _list[divAt];
            var left  = new BListLeaf <K, T>(_maxNodeSize, _list.CopySection(0, divAt));
            var right = new BListLeaf <K, T>(_maxNodeSize, _list.CopySection(divAt, _list.Count - divAt));
            int sizeChange;

            if (op.CompareToKey(mid, op.Key) >= 0)
            {
                sizeChange = left.DoSingleOperation(ref op, out splitLeft, out splitRight);
            }
            else
            {
                op.BaseIndex += left.TotalCount;
                sizeChange    = right.DoSingleOperation(ref op, out splitLeft, out splitRight);
            }

            op.AggregateChanged &= unchecked ((byte)~2);

            // (splitLeft may be non-null, meaning that the highest key changed, which doesn't matter here.)
            Debug.Assert(splitRight == null);
            Debug.Assert(sizeChange == 1);
            splitLeft  = left;
            splitRight = right;
            return(sizeChange);
        }