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); })); }
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)); }
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; } }
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; } }
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); }); }
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); }
internal BTreeLeaf(long transactionId, BTreeLeafMember[] newKeyValues) { TransactionId = transactionId; _keyvalues = newKeyValues; }
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); }