Ejemplo n.º 1
0
        public IBTreeNode RemappingIterate(long transactionId, BTreeRemappingIterateAction action)
        {
            var result   = this;
            var children = _children;

            for (var i = 0; i < children.Length; i++)
            {
                var child    = children[i];
                var newChild = child.RemappingIterate(transactionId, action);
                if (newChild == child)
                {
                    continue;
                }
                if (result.TransactionId != transactionId)
                {
                    var newKeys = new byte[_keys.Length][];
                    Array.Copy(_keys, newKeys, newKeys.Length);
                    var newChildren = new IBTreeNode[_children.Length];
                    Array.Copy(_children, newChildren, newChildren.Length);
                    var newPairCounts = new long[_pairCounts.Length];
                    Array.Copy(_pairCounts, newPairCounts, newPairCounts.Length);
                    result   = new BTreeBranch(transactionId, newKeys, newChildren, newPairCounts);
                    children = newChildren;
                }
                children[i] = newChild;
            }
            return(result);
        }
Ejemplo n.º 2
0
        public IBTreeNode ReplaceValues(ReplaceValuesCtx ctx)
        {
            var result   = this;
            var children = _children;
            var i        = 0;

            if (ctx._restartKey != null)
            {
                for (; i < _keys.Length; i++)
                {
                    var compRes = BitArrayManipulation.CompareByteArray(_keys[i], 0, _keys[i].Length, ctx._restartKey, 0, ctx._restartKey.Length);
                    if (compRes > 0)
                    {
                        break;
                    }
                }
            }
            for (; i < children.Length; i++)
            {
                var child    = children[i];
                var newChild = child.ReplaceValues(ctx);
                if (newChild != child)
                {
                    if (result.TransactionId != ctx._transactionId)
                    {
                        var newKeys = new byte[_keys.Length][];
                        Array.Copy(_keys, newKeys, newKeys.Length);
                        var newChildren = new IBTreeNode[_children.Length];
                        Array.Copy(_children, newChildren, newChildren.Length);
                        var newPairCounts = new long[_pairCounts.Length];
                        Array.Copy(_pairCounts, newPairCounts, newPairCounts.Length);
                        result   = new BTreeBranch(ctx._transactionId, newKeys, newChildren, newPairCounts);
                        children = newChildren;
                    }
                    children[i] = newChild;
                }
                if (ctx._interrupt)
                {
                    break;
                }
                ctx._restartKey = null;
                var now = DateTime.UtcNow;
                if (i < _keys.Length && (now > ctx._iterationTimeOut || ctx._cancellation.IsCancellationRequested))
                {
                    ctx._interrupt  = true;
                    ctx._restartKey = _keys[i];
                    break;
                }
            }
            return(result);
        }
Ejemplo n.º 3
0
        public void CreateOrUpdate(CreateOrUpdateCtx ctx)
        {
            var index = Find(ctx.KeyPrefix, ctx.Key);

            ctx.Stack.Add(new NodeIdxPair {
                Node = this, Idx = index
            });
            ctx.Depth++;
            _children[index].CreateOrUpdate(ctx);
            ctx.Depth--;
            var newBranch = this;

            if (ctx.Split)
            {
                ctx.Split = false;
                var newKeys       = new byte[_children.Length][];
                var newChildren   = new IBTreeNode[_children.Length + 1];
                var newPairCounts = new long[_children.Length + 1];
                Array.Copy(_keys, 0, newKeys, 0, index);
                newKeys[index] = ctx.Node2.GetLeftMostKey();
                Array.Copy(_keys, index, newKeys, index + 1, _keys.Length - index);
                Array.Copy(_children, 0, newChildren, 0, index);
                newChildren[index]     = ctx.Node1;
                newChildren[index + 1] = ctx.Node2;
                Array.Copy(_children, index + 1, newChildren, index + 2, _children.Length - index - 1);
                Array.Copy(_pairCounts, newPairCounts, index);
                var previousPairCount = index > 0 ? newPairCounts[index - 1] : 0;
                for (var i = index; i < newPairCounts.Length; i++)
                {
                    previousPairCount += newChildren[i].CalcKeyCount();
                    newPairCounts[i]   = previousPairCount;
                }
                ctx.Node1 = null;
                ctx.Node2 = null;
                if (_children.Length < MaxChildren)
                {
                    if (TransactionId != ctx.TransactionId)
                    {
                        newBranch  = new BTreeBranch(ctx.TransactionId, newKeys, newChildren, newPairCounts);
                        ctx.Node1  = newBranch;
                        ctx.Update = true;
                    }
                    else
                    {
                        _keys       = newKeys;
                        _children   = newChildren;
                        _pairCounts = newPairCounts;
                    }
                    if (ctx.SplitInRight)
                    {
                        index++;
                    }
                    ctx.Stack[ctx.Depth] = new NodeIdxPair {
                        Node = newBranch, Idx = index
                    };
                    return;
                }
                if (ctx.SplitInRight)
                {
                    index++;
                }
                ctx.Split = true;

                var keyCountLeft  = (newChildren.Length + 1) / 2;
                var keyCountRight = newChildren.Length - keyCountLeft;

                var splitKeys       = new byte[keyCountLeft - 1][];
                var splitChildren   = new IBTreeNode[keyCountLeft];
                var splitPairCounts = new long[keyCountLeft];
                Array.Copy(newKeys, splitKeys, splitKeys.Length);
                Array.Copy(newChildren, splitChildren, splitChildren.Length);
                Array.Copy(newPairCounts, splitPairCounts, splitPairCounts.Length);
                ctx.Node1 = new BTreeBranch(ctx.TransactionId, splitKeys, splitChildren, splitPairCounts);

                splitKeys       = new byte[keyCountRight - 1][];
                splitChildren   = new IBTreeNode[keyCountRight];
                splitPairCounts = new long[keyCountRight];
                Array.Copy(newKeys, keyCountLeft, splitKeys, 0, splitKeys.Length);
                Array.Copy(newChildren, keyCountLeft, splitChildren, 0, splitChildren.Length);
                for (int i = 0; i < splitPairCounts.Length; i++)
                {
                    splitPairCounts[i] = newPairCounts[keyCountLeft + i] - newPairCounts[keyCountLeft - 1];
                }
                ctx.Node2 = new BTreeBranch(ctx.TransactionId, splitKeys, splitChildren, splitPairCounts);

                if (index < keyCountLeft)
                {
                    ctx.Stack[ctx.Depth] = new NodeIdxPair {
                        Node = ctx.Node1, Idx = index
                    };
                    ctx.SplitInRight = false;
                }
                else
                {
                    ctx.Stack[ctx.Depth] = new NodeIdxPair {
                        Node = ctx.Node2, Idx = index - keyCountLeft
                    };
                    ctx.SplitInRight = true;
                }
                return;
            }
            if (ctx.Update)
            {
                if (TransactionId != ctx.TransactionId)
                {
                    var newKeys       = new byte[_keys.Length][];
                    var newChildren   = new IBTreeNode[_children.Length];
                    var newPairCounts = new long[_children.Length];
                    Array.Copy(_keys, newKeys, _keys.Length);
                    Array.Copy(_children, newChildren, _children.Length);
                    newChildren[index] = ctx.Node1;
                    Array.Copy(_pairCounts, newPairCounts, _pairCounts.Length);
                    newBranch = new BTreeBranch(ctx.TransactionId, newKeys, newChildren, newPairCounts);
                    ctx.Node1 = newBranch;
                }
                else
                {
                    _children[index] = ctx.Node1;
                    ctx.Update       = false;
                    ctx.Node1        = null;
                }
                ctx.Stack[ctx.Depth] = new NodeIdxPair {
                    Node = newBranch, Idx = index
                };
            }
            Debug.Assert(newBranch.TransactionId == ctx.TransactionId);
            if (!ctx.Created)
            {
                return;
            }
            var pairCounts = newBranch._pairCounts;

            for (var i = index; i < pairCounts.Length; i++)
            {
                pairCounts[i]++;
            }
        }
Ejemplo n.º 4
0
        public void CreateOrUpdate(CreateOrUpdateCtx ctx)
        {
            var index = Find(ctx.KeyPrefix, ctx.Key);
            ctx.Stack.Add(new NodeIdxPair { Node = this, Idx = index });
            ctx.Depth++;
            _children[index].CreateOrUpdate(ctx);
            ctx.Depth--;
            var newBranch = this;
            if (ctx.Split)
            {
                ctx.Split = false;
                var newKeys = new byte[_children.Length][];
                var newChildren = new IBTreeNode[_children.Length + 1];
                var newPairCounts = new long[_children.Length + 1];
                Array.Copy(_keys, 0, newKeys, 0, index);
                newKeys[index] = ctx.Node2.GetLeftMostKey();
                Array.Copy(_keys, index, newKeys, index + 1, _keys.Length - index);
                Array.Copy(_children, 0, newChildren, 0, index);
                newChildren[index] = ctx.Node1;
                newChildren[index + 1] = ctx.Node2;
                Array.Copy(_children, index + 1, newChildren, index + 2, _children.Length - index - 1);
                Array.Copy(_pairCounts, newPairCounts, index);
                var previousPairCount = index > 0 ? newPairCounts[index - 1] : 0;
                for (var i = index; i < newPairCounts.Length; i++)
                {
                    previousPairCount += newChildren[i].CalcKeyCount();
                    newPairCounts[i] = previousPairCount;
                }
                ctx.Node1 = null;
                ctx.Node2 = null;
                if (_children.Length < MaxChildren)
                {
                    if (TransactionId != ctx.TransactionId)
                    {
                        newBranch = new BTreeBranch(ctx.TransactionId, newKeys, newChildren, newPairCounts);
                        ctx.Node1 = newBranch;
                        ctx.Update = true;
                    }
                    else
                    {
                        _keys = newKeys;
                        _children = newChildren;
                        _pairCounts = newPairCounts;
                    }
                    if (ctx.SplitInRight) index++;
                    ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = newBranch, Idx = index };
                    return;
                }
                if (ctx.SplitInRight) index++;
                ctx.Split = true;

                var keyCountLeft = (newChildren.Length + 1) / 2;
                var keyCountRight = newChildren.Length - keyCountLeft;

                var splitKeys = new byte[keyCountLeft - 1][];
                var splitChildren = new IBTreeNode[keyCountLeft];
                var splitPairCounts = new long[keyCountLeft];
                Array.Copy(newKeys, splitKeys, splitKeys.Length);
                Array.Copy(newChildren, splitChildren, splitChildren.Length);
                Array.Copy(newPairCounts, splitPairCounts, splitPairCounts.Length);
                ctx.Node1 = new BTreeBranch(ctx.TransactionId, splitKeys, splitChildren, splitPairCounts);

                splitKeys = new byte[keyCountRight - 1][];
                splitChildren = new IBTreeNode[keyCountRight];
                splitPairCounts = new long[keyCountRight];
                Array.Copy(newKeys, keyCountLeft, splitKeys, 0, splitKeys.Length);
                Array.Copy(newChildren, keyCountLeft, splitChildren, 0, splitChildren.Length);
                for (int i = 0; i < splitPairCounts.Length; i++)
                {
                    splitPairCounts[i] = newPairCounts[keyCountLeft + i] - newPairCounts[keyCountLeft - 1];
                }
                ctx.Node2 = new BTreeBranch(ctx.TransactionId, splitKeys, splitChildren, splitPairCounts);

                if (index < keyCountLeft)
                {
                    ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = ctx.Node1, Idx = index };
                    ctx.SplitInRight = false;
                }
                else
                {
                    ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = ctx.Node2, Idx = index - keyCountLeft };
                    ctx.SplitInRight = true;
                }
                return;
            }
            if (ctx.Update)
            {
                if (TransactionId != ctx.TransactionId)
                {
                    var newKeys = new byte[_keys.Length][];
                    var newChildren = new IBTreeNode[_children.Length];
                    var newPairCounts = new long[_children.Length];
                    Array.Copy(_keys, newKeys, _keys.Length);
                    Array.Copy(_children, newChildren, _children.Length);
                    newChildren[index] = ctx.Node1;
                    Array.Copy(_pairCounts, newPairCounts, _pairCounts.Length);
                    newBranch = new BTreeBranch(ctx.TransactionId, newKeys, newChildren, newPairCounts);
                    ctx.Node1 = newBranch;
                }
                else
                {
                    _children[index] = ctx.Node1;
                    ctx.Update = false;
                    ctx.Node1 = null;
                }
                ctx.Stack[ctx.Depth] = new NodeIdxPair { Node = newBranch, Idx = index };
            }
            Debug.Assert(newBranch.TransactionId == ctx.TransactionId);
            if (!ctx.Created) return;
            var pairCounts = newBranch._pairCounts;
            for (var i = index; i < pairCounts.Length; i++)
            {
                pairCounts[i]++;
            }
        }
Ejemplo n.º 5
0
 public IBTreeNode RemappingIterate(long transactionId, BTreeRemappingIterateAction action)
 {
     var result = this;
     var children = _children;
     for (var i = 0; i < children.Length; i++)
     {
         var child = children[i];
         var newChild = child.RemappingIterate(transactionId, action);
         if (newChild == child) continue;
         if (result.TransactionId != transactionId)
         {
             var newKeys = new byte[_keys.Length][];
             Array.Copy(_keys, newKeys, newKeys.Length);
             var newChildren = new IBTreeNode[_children.Length];
             Array.Copy(_children, newChildren, newChildren.Length);
             var newPairCounts = new long[_pairCounts.Length];
             Array.Copy(_pairCounts, newPairCounts, newPairCounts.Length);
             result = new BTreeBranch(transactionId, newKeys, newChildren, newPairCounts);
             children = newChildren;
         }
         children[i] = newChild;
     }
     return result;
 }