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); }
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); }
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]++; } }
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]++; } }
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; }