示例#1
0
        IBTreeNode BuildTreeNode(long keyCount, Func <BTreeLeafMember> memberGenerator)
        {
            var leafs = (keyCount + BTreeLeafComp.MaxMembers - 1) / BTreeLeafComp.MaxMembers;
            var order = 0L;
            var done  = 0L;

            return(BuildBranchNode(leafs, () =>
            {
                order++;
                var reach = keyCount * order / leafs;
                var todo = (int)(reach - done);
                done = reach;
                var keyvalues = new BTreeLeafMember[todo];
                long totalKeyLen = 0;
                for (int i = 0; i < keyvalues.Length; i++)
                {
                    keyvalues[i] = memberGenerator();
                    totalKeyLen += keyvalues[i].Key.Length;
                }
                if (totalKeyLen > BTreeLeafComp.MaxTotalLen)
                {
                    return new BTreeLeaf(_transactionId, keyvalues);
                }
                return new BTreeLeafComp(_transactionId, keyvalues);
            }));
        }
示例#2
0
        public IBTreeNode EraseRange(long transactionId, long firstKeyIndex, long lastKeyIndex)
        {
            var newKeyValues = new BTreeLeafMember[_keyvalues.Length + firstKeyIndex - lastKeyIndex - 1];

            Array.Copy(_keyvalues, 0, newKeyValues, 0, (int)firstKeyIndex);
            Array.Copy(_keyvalues, (int)lastKeyIndex + 1, newKeyValues, (int)firstKeyIndex, newKeyValues.Length - (int)firstKeyIndex);
            if (TransactionId == transactionId)
            {
                _keyvalues = newKeyValues;
                return(this);
            }
            return(new BTreeLeaf(transactionId, newKeyValues));
        }
示例#3
0
 internal BTreeLeafComp(long transactionId, BTreeLeafMember[] newKeyValues)
 {
     Debug.Assert(newKeyValues.Length > 0 && newKeyValues.Length <= MaxMembers);
     TransactionId = transactionId;
     _keyBytes = new byte[newKeyValues.Sum(m => m.Key.Length)];
     _keyvalues = new Member[newKeyValues.Length];
     ushort ofs = 0;
     for (var i = 0; i < newKeyValues.Length; i++)
     {
         _keyvalues[i] = new Member
             {
                 KeyOffset = ofs,
                 KeyLength = (ushort)newKeyValues[i].Key.Length,
                 Value = newKeyValues[i].Value
             };
         Array.Copy(newKeyValues[i].Key, 0, _keyBytes, ofs, _keyvalues[i].KeyLength);
         ofs += _keyvalues[i].KeyLength;
     }
 }
示例#4
0
        public void CreateOrUpdate(CreateOrUpdateCtx ctx)
        {
            var index = Find(ctx.KeyPrefix, ctx.Key);

            if ((index & 1) == 1)
            {
                index        = index / 2;
                ctx.Created  = false;
                ctx.KeyIndex = index;
                var m = _keyvalues[index];
                m.Value = ctx.Value.ToByteArray();
                var leaf = this;
                if (ctx.TransactionId != TransactionId)
                {
                    leaf = new BTreeLeaf(ctx.TransactionId, _keyvalues.Length);
                    Array.Copy(_keyvalues, leaf._keyvalues, _keyvalues.Length);
                    ctx.Node1  = leaf;
                    ctx.Update = true;
                }
                leaf._keyvalues[index] = m;
                ctx.Stack.Add(new NodeIdxPair {
                    Node = leaf, Idx = index
                });
                return;
            }
            index        = index / 2;
            ctx.Created  = true;
            ctx.KeyIndex = index;
            if (_keyvalues.Length < MaxMembers)
            {
                var newKeyValues = new BTreeLeafMember[_keyvalues.Length + 1];
                Array.Copy(_keyvalues, 0, newKeyValues, 0, index);
                newKeyValues[index] = NewMemberFromCtx(ctx);
                Array.Copy(_keyvalues, index, newKeyValues, index + 1, _keyvalues.Length - index);
                var leaf = this;
                if (ctx.TransactionId != TransactionId)
                {
                    leaf       = new BTreeLeaf(ctx.TransactionId, newKeyValues);
                    ctx.Node1  = leaf;
                    ctx.Update = true;
                }
                else
                {
                    _keyvalues = newKeyValues;
                }
                ctx.Stack.Add(new NodeIdxPair {
                    Node = leaf, Idx = index
                });
                return;
            }
            ctx.Split = true;
            var keyCountLeft  = (_keyvalues.Length + 1) / 2;
            var keyCountRight = _keyvalues.Length + 1 - keyCountLeft;
            var leftNode      = new BTreeLeaf(ctx.TransactionId, keyCountLeft);
            var rightNode     = new BTreeLeaf(ctx.TransactionId, keyCountRight);

            ctx.Node1 = leftNode;
            ctx.Node2 = rightNode;
            if (index < keyCountLeft)
            {
                Array.Copy(_keyvalues, 0, leftNode._keyvalues, 0, index);
                leftNode._keyvalues[index] = NewMemberFromCtx(ctx);
                Array.Copy(_keyvalues, index, leftNode._keyvalues, index + 1, keyCountLeft - index - 1);
                Array.Copy(_keyvalues, keyCountLeft - 1, rightNode._keyvalues, 0, keyCountRight);
                ctx.Stack.Add(new NodeIdxPair {
                    Node = leftNode, Idx = index
                });
                ctx.SplitInRight = false;
            }
            else
            {
                Array.Copy(_keyvalues, 0, leftNode._keyvalues, 0, keyCountLeft);
                Array.Copy(_keyvalues, keyCountLeft, rightNode._keyvalues, 0, index - keyCountLeft);
                rightNode._keyvalues[index - keyCountLeft] = NewMemberFromCtx(ctx);
                Array.Copy(_keyvalues, index, rightNode._keyvalues, index - keyCountLeft + 1, keyCountLeft + keyCountRight - 1 - index);
                ctx.Stack.Add(new NodeIdxPair {
                    Node = rightNode, Idx = index - keyCountLeft
                });
                ctx.SplitInRight = true;
            }
        }
示例#5
0
文件: BTreeRoot.cs 项目: Bobris/BTDB
 IBTreeNode BuildTreeNode(long keyCount, Func<BTreeLeafMember> memberGenerator)
 {
     var leafs = (keyCount + BTreeLeafComp.MaxMembers - 1) / BTreeLeafComp.MaxMembers;
     var order = 0L;
     var done = 0L;
     return BuildBranchNode(leafs, () =>
         {
             order++;
             var reach = keyCount * order / leafs;
             var todo = (int)(reach - done);
             done = reach;
             var keyvalues = new BTreeLeafMember[todo];
             long totalKeyLen = 0;
             for (int i = 0; i < keyvalues.Length; i++)
             {
                 keyvalues[i] = memberGenerator();
                 totalKeyLen += keyvalues[i].Key.Length;
             }
             if (totalKeyLen > BTreeLeafComp.MaxTotalLen)
             {
                 return new BTreeLeaf(_transactionId, keyvalues);
             }
             return new BTreeLeafComp(_transactionId, keyvalues);
         });
 }
示例#6
0
 public void CreateOrUpdate(CreateOrUpdateCtx ctx)
 {
     var index = Find(ctx.KeyPrefix, ctx.Key);
     if ((index & 1) == 1)
     {
         index = index / 2;
         ctx.Created = false;
         ctx.KeyIndex = index;
         var m = _keyvalues[index];
         m.Value = ctx.Value.ToByteArray();
         var leaf = this;
         if (ctx.TransactionId != TransactionId)
         {
             leaf = new BTreeLeafComp(ctx.TransactionId, _keyvalues.Length);
             Array.Copy(_keyvalues, leaf._keyvalues, _keyvalues.Length);
             leaf._keyBytes = _keyBytes;
             ctx.Node1 = leaf;
             ctx.Update = true;
         }
         leaf._keyvalues[index] = m;
         ctx.Stack.Add(new NodeIdxPair { Node = leaf, Idx = index });
         return;
     }
     if ((long)_keyBytes.Length + ctx.WholeKeyLen > MaxTotalLen)
     {
         var currentKeyValues = new BTreeLeafMember[_keyvalues.Length];
         for (int i = 0; i < currentKeyValues.Length; i++)
         {
             var member = _keyvalues[i];
             currentKeyValues[i] = new BTreeLeafMember
                 {
                     Key = ByteBuffer.NewAsync(_keyBytes, member.KeyOffset, member.KeyLength).ToByteArray(),
                     Value = member.Value
                 };
         }
         new BTreeLeaf(ctx.TransactionId - 1, currentKeyValues).CreateOrUpdate(ctx);
         return;
     }
     index = index / 2;
     ctx.Created = true;
     ctx.KeyIndex = index;
     var newKey = ctx.WholeKey();
     if (_keyvalues.Length < MaxMembers)
     {
         var newKeyValues = new Member[_keyvalues.Length + 1];
         var newKeyBytes = new byte[_keyBytes.Length + newKey.Length];
         Array.Copy(_keyvalues, 0, newKeyValues, 0, index);
         var ofs = (ushort)(index == 0 ? 0 : newKeyValues[index - 1].KeyOffset + newKeyValues[index - 1].KeyLength);
         newKeyValues[index] = new Member
             {
                 KeyOffset = ofs,
                 KeyLength = (ushort)newKey.Length,
                 Value = ctx.Value.ToByteArray()
             };
         Array.Copy(_keyBytes, 0, newKeyBytes, 0, ofs);
         Array.Copy(newKey, 0, newKeyBytes, ofs, newKey.Length);
         Array.Copy(_keyBytes, ofs, newKeyBytes, ofs + newKey.Length, _keyBytes.Length - ofs);
         Array.Copy(_keyvalues, index, newKeyValues, index + 1, _keyvalues.Length - index);
         RecalculateOffsets(newKeyValues);
         var leaf = this;
         if (ctx.TransactionId != TransactionId)
         {
             leaf = new BTreeLeafComp(ctx.TransactionId, newKeyBytes, newKeyValues);
             ctx.Node1 = leaf;
             ctx.Update = true;
         }
         else
         {
             _keyvalues = newKeyValues;
             _keyBytes = newKeyBytes;
         }
         ctx.Stack.Add(new NodeIdxPair { Node = leaf, Idx = index });
         return;
     }
     ctx.Split = true;
     var keyCountLeft = (_keyvalues.Length + 1) / 2;
     var keyCountRight = _keyvalues.Length + 1 - keyCountLeft;
     var leftNode = new BTreeLeafComp(ctx.TransactionId, keyCountLeft);
     var rightNode = new BTreeLeafComp(ctx.TransactionId, keyCountRight);
     ctx.Node1 = leftNode;
     ctx.Node2 = rightNode;
     if (index < keyCountLeft)
     {
         Array.Copy(_keyvalues, 0, leftNode._keyvalues, 0, index);
         var ofs = (ushort)(index == 0 ? 0 : _keyvalues[index - 1].KeyOffset + _keyvalues[index - 1].KeyLength);
         leftNode._keyvalues[index] = new Member
         {
             KeyOffset = ofs,
             KeyLength = (ushort)newKey.Length,
             Value = ctx.Value.ToByteArray()
         };
         Array.Copy(_keyvalues, index, leftNode._keyvalues, index + 1, keyCountLeft - index - 1);
         Array.Copy(_keyvalues, keyCountLeft - 1, rightNode._keyvalues, 0, keyCountRight);
         var leftKeyBytesLen = _keyvalues[keyCountLeft - 1].KeyOffset + newKey.Length;
         var newKeyBytes = new byte[leftKeyBytesLen];
         Array.Copy(_keyBytes, 0, newKeyBytes, 0, ofs);
         Array.Copy(newKey, 0, newKeyBytes, ofs, newKey.Length);
         Array.Copy(_keyBytes, ofs, newKeyBytes, ofs + newKey.Length, leftKeyBytesLen - (ofs + newKey.Length));
         leftNode._keyBytes = newKeyBytes;
         newKeyBytes = new byte[_keyBytes.Length + newKey.Length - leftKeyBytesLen];
         Array.Copy(_keyBytes, leftKeyBytesLen - newKey.Length, newKeyBytes, 0, newKeyBytes.Length);
         rightNode._keyBytes = newKeyBytes;
         ctx.Stack.Add(new NodeIdxPair { Node = leftNode, Idx = index });
         ctx.SplitInRight = false;
         RecalculateOffsets(leftNode._keyvalues);
     }
     else
     {
         Array.Copy(_keyvalues, 0, leftNode._keyvalues, 0, keyCountLeft);
         var leftKeyBytesLen = _keyvalues[keyCountLeft].KeyOffset;
         var newKeyBytes = new byte[leftKeyBytesLen];
         Array.Copy(_keyBytes, 0, newKeyBytes, 0, leftKeyBytesLen);
         leftNode._keyBytes = newKeyBytes;
         newKeyBytes = new byte[_keyBytes.Length + newKey.Length - leftKeyBytesLen];
         var ofs = (index == _keyvalues.Length ? _keyBytes.Length : _keyvalues[index].KeyOffset) - leftKeyBytesLen;
         Array.Copy(_keyBytes, leftKeyBytesLen, newKeyBytes, 0, ofs);
         Array.Copy(newKey, 0, newKeyBytes, ofs, newKey.Length);
         Array.Copy(_keyBytes, ofs + leftKeyBytesLen, newKeyBytes, ofs + newKey.Length, _keyBytes.Length - ofs - leftKeyBytesLen);
         rightNode._keyBytes = newKeyBytes;
         Array.Copy(_keyvalues, keyCountLeft, rightNode._keyvalues, 0, index - keyCountLeft);
         rightNode._keyvalues[index - keyCountLeft] = new Member
         {
             KeyOffset = 0,
             KeyLength = (ushort)newKey.Length,
             Value = ctx.Value.ToByteArray(),
         };
         Array.Copy(_keyvalues, index, rightNode._keyvalues, index - keyCountLeft + 1, keyCountLeft + keyCountRight - 1 - index);
         ctx.Stack.Add(new NodeIdxPair { Node = rightNode, Idx = index - keyCountLeft });
         ctx.SplitInRight = true;
     }
     RecalculateOffsets(rightNode._keyvalues);
 }
示例#7
0
文件: BTreeLeaf.cs 项目: Xamarui/BTDB
 public void CreateOrUpdate(CreateOrUpdateCtx ctx)
 {
     var index = Find(ctx.KeyPrefix, ctx.Key);
     if ((index & 1) == 1)
     {
         index = index / 2;
         ctx.Created = false;
         ctx.KeyIndex = index;
         var m = _keyvalues[index];
         m.Value = ctx.Value.ToByteArray();
         var leaf = this;
         if (ctx.TransactionId != TransactionId)
         {
             leaf = new BTreeLeaf(ctx.TransactionId, _keyvalues.Length);
             Array.Copy(_keyvalues, leaf._keyvalues, _keyvalues.Length);
             ctx.Node1 = leaf;
             ctx.Update = true;
         }
         leaf._keyvalues[index] = m;
         ctx.Stack.Add(new NodeIdxPair { Node = leaf, Idx = index });
         return;
     }
     index = index / 2;
     ctx.Created = true;
     ctx.KeyIndex = index;
     if (_keyvalues.Length < MaxMembers)
     {
         var newKeyValues = new BTreeLeafMember[_keyvalues.Length + 1];
         Array.Copy(_keyvalues, 0, newKeyValues, 0, index);
         newKeyValues[index] = NewMemberFromCtx(ctx);
         Array.Copy(_keyvalues, index, newKeyValues, index + 1, _keyvalues.Length - index);
         var leaf = this;
         if (ctx.TransactionId != TransactionId)
         {
             leaf = new BTreeLeaf(ctx.TransactionId, newKeyValues);
             ctx.Node1 = leaf;
             ctx.Update = true;
         }
         else
         {
             _keyvalues = newKeyValues;
         }
         ctx.Stack.Add(new NodeIdxPair { Node = leaf, Idx = index });
         return;
     }
     ctx.Split = true;
     var keyCountLeft = (_keyvalues.Length + 1) / 2;
     var keyCountRight = _keyvalues.Length + 1 - keyCountLeft;
     var leftNode = new BTreeLeaf(ctx.TransactionId, keyCountLeft);
     var rightNode = new BTreeLeaf(ctx.TransactionId, keyCountRight);
     ctx.Node1 = leftNode;
     ctx.Node2 = rightNode;
     if (index < keyCountLeft)
     {
         Array.Copy(_keyvalues, 0, leftNode._keyvalues, 0, index);
         leftNode._keyvalues[index] = NewMemberFromCtx(ctx);
         Array.Copy(_keyvalues, index, leftNode._keyvalues, index + 1, keyCountLeft - index - 1);
         Array.Copy(_keyvalues, keyCountLeft - 1, rightNode._keyvalues, 0, keyCountRight);
         ctx.Stack.Add(new NodeIdxPair { Node = leftNode, Idx = index });
         ctx.SplitInRight = false;
     }
     else
     {
         Array.Copy(_keyvalues, 0, leftNode._keyvalues, 0, keyCountLeft);
         Array.Copy(_keyvalues, keyCountLeft, rightNode._keyvalues, 0, index - keyCountLeft);
         rightNode._keyvalues[index - keyCountLeft] = NewMemberFromCtx(ctx);
         Array.Copy(_keyvalues, index, rightNode._keyvalues, index - keyCountLeft + 1, keyCountLeft + keyCountRight - 1 - index);
         ctx.Stack.Add(new NodeIdxPair { Node = rightNode, Idx = index - keyCountLeft });
         ctx.SplitInRight = true;
     }
 }
示例#8
0
文件: BTreeLeaf.cs 项目: Xamarui/BTDB
 internal BTreeLeaf(long transactionId, BTreeLeafMember[] newKeyValues)
 {
     TransactionId = transactionId;
     _keyvalues = newKeyValues;
 }
示例#9
0
文件: BTreeLeaf.cs 项目: Xamarui/BTDB
 public IBTreeNode EraseRange(long transactionId, long firstKeyIndex, long lastKeyIndex)
 {
     var newKeyValues = new BTreeLeafMember[_keyvalues.Length + firstKeyIndex - lastKeyIndex - 1];
     Array.Copy(_keyvalues, 0, newKeyValues, 0, (int)firstKeyIndex);
     Array.Copy(_keyvalues, (int)lastKeyIndex + 1, newKeyValues, (int)firstKeyIndex, newKeyValues.Length - (int)firstKeyIndex);
     if (TransactionId == transactionId)
     {
         _keyvalues = newKeyValues;
         return this;
     }
     return new BTreeLeaf(transactionId, newKeyValues);
 }