public void CreateOrUpdate(CreateOrUpdateCtx ctx) { ctx.TransactionId = _transactionId; if (ctx.Stack == null) ctx.Stack = new List<NodeIdxPair>(); else ctx.Stack.Clear(); if (_rootNode == null) { _rootNode = ctx.WholeKeyLen > BTreeLeafComp.MaxTotalLen ? BTreeLeaf.CreateFirst(ctx) : BTreeLeafComp.CreateFirst(ctx); _keyValueCount = 1; ctx.Stack.Add(new NodeIdxPair { Node = _rootNode, Idx = 0 }); ctx.KeyIndex = 0; ctx.Created = true; return; } ctx.Depth = 0; _rootNode.CreateOrUpdate(ctx); if (ctx.Split) { _rootNode = new BTreeBranch(ctx.TransactionId, ctx.Node1, ctx.Node2); ctx.Stack.Insert(0, new NodeIdxPair { Node = _rootNode, Idx = ctx.SplitInRight ? 1 : 0 }); } else if (ctx.Update) { _rootNode = ctx.Node1; } if (ctx.Created) { _keyValueCount++; } }
internal static IBTreeNode CreateFirst(CreateOrUpdateCtx ctx) { var result = new BTreeLeaf(ctx.TransactionId, 1); result._keyvalues[0] = NewMemberFromCtx(ctx); return(result); }
static BTreeLeafMember NewMemberFromCtx(CreateOrUpdateCtx ctx) { return(new BTreeLeafMember { Key = ctx.WholeKey(), Value = ctx.Value.ToByteArray() }); }
internal static IBTreeNode CreateFirst(CreateOrUpdateCtx ctx) { Debug.Assert(ctx.WholeKeyLen <= MaxTotalLen); var result = new BTreeLeafComp(ctx.TransactionId, 1); result._keyBytes = ctx.WholeKey(); result._keyvalues[0] = new Member { KeyOffset = 0, KeyLength = (ushort)result._keyBytes.Length, Value = ctx.Value.ToByteArray() }; return result; }
internal static IBTreeNode CreateFirst(ref CreateOrUpdateCtx ctx) { Debug.Assert(ctx.Key.Length <= MaxTotalLen); var result = new BTreeLeafComp(ctx.TransactionId, 1); result._keyBytes = ctx.Key.ToArray(); result._keyValues[0] = new Member { KeyOffset = 0, KeyLength = (ushort)result._keyBytes.Length, Value = ctx.Value.ToArray() }; return(result); }
public bool CreateOrUpdateKeyValue(ByteBuffer key, ByteBuffer value) { MakeWrittable(); var ctx = new CreateOrUpdateCtx { KeyPrefix = _prefix, Key = key, Value = value, Stack = _stack }; BtreeRoot.CreateOrUpdate(ctx); _keyIndex = ctx.KeyIndex; if (ctx.Created && _prefixKeyCount >= 0) _prefixKeyCount++; return ctx.Created; }
public void CreateOrUpdate(CreateOrUpdateCtx ctx) { ctx.TransactionId = _transactionId; if (ctx.Stack == null) { ctx.Stack = new List <NodeIdxPair>(); } else { ctx.Stack.Clear(); } if (_rootNode == null) { _rootNode = ctx.WholeKeyLen > BTreeLeafComp.MaxTotalLen ? BTreeLeaf.CreateFirst(ctx) : BTreeLeafComp.CreateFirst(ctx); _keyValueCount = 1; ctx.Stack.Add(new NodeIdxPair { Node = _rootNode, Idx = 0 }); ctx.KeyIndex = 0; ctx.Created = true; return; } ctx.Depth = 0; _rootNode.CreateOrUpdate(ctx); if (ctx.Split) { _rootNode = new BTreeBranch(ctx.TransactionId, ctx.Node1, ctx.Node2); ctx.Stack.Insert(0, new NodeIdxPair { Node = _rootNode, Idx = ctx.SplitInRight ? 1 : 0 }); } else if (ctx.Update) { _rootNode = ctx.Node1; } if (ctx.Created) { _keyValueCount++; } }
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; } }
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]++; } }
static BTreeLeafMember NewMemberFromCtx(CreateOrUpdateCtx ctx) { return new BTreeLeafMember { Key = ctx.WholeKey(), Value = ctx.Value.ToByteArray() }; }
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); }
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]++; } }
internal static IBTreeNode CreateFirst(CreateOrUpdateCtx ctx) { var result = new BTreeLeaf(ctx.TransactionId, 1); result._keyvalues[0] = NewMemberFromCtx(ctx); return result; }