Skip to content

Commit 4497a52

Browse files
committed
Speed up Constraint Scan.
1 parent bac8cbe commit 4497a52

File tree

6 files changed

+27
-25
lines changed

6 files changed

+27
-25
lines changed

BTDB/BTreeLib/BTreeImpl12.cs

+12-12
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ internal static bool MoveToLast(IntPtr root, ref StructList<CursorItem> stack)
941941
internal IntPtr CloneNode(IntPtr nodePtr)
942942
{
943943
var size = NodeUtils12.NodeSize(nodePtr);
944-
var newNode = _allocator.Allocate((IntPtr)size);
944+
var newNode = _allocator.Allocate(size);
945945
TreeNodeUtils.CopyMemory(nodePtr, newNode, size);
946946
ref var header = ref NodeUtils12.Ptr2NodeHeader(newNode);
947947
header._referenceCount = 1;
@@ -970,9 +970,9 @@ void ReferenceAllChildren(IntPtr node)
970970
{
971971
if (NodeUtils12.Ptr2NodeHeader(node).IsNodeLeaf) return;
972972
var ptrs = NodeUtils12.GetBranchValuePtrs(node);
973-
for (var i = 0; i < ptrs.Length; i++)
973+
foreach (var t in ptrs)
974974
{
975-
NodeUtils12.Reference(ptrs[i]);
975+
NodeUtils12.Reference(t);
976976
}
977977
}
978978

@@ -991,18 +991,18 @@ internal void Dereference(IntPtr node)
991991
if (nodeHeader.HasLongKeys)
992992
{
993993
var ptrs = NodeUtils12.GetLongKeyPtrs(node);
994-
for (var i = 0; i < ptrs.Length; i++)
994+
foreach (var t in ptrs)
995995
{
996-
FreeLongKey(ptrs[i]);
996+
FreeLongKey(t);
997997
}
998998
}
999999

10001000
if (!nodeHeader.IsNodeLeaf)
10011001
{
10021002
var ptrs = NodeUtils12.GetBranchValuePtrs(node);
1003-
for (var i = 0; i < ptrs.Length; i++)
1003+
foreach (var t in ptrs)
10041004
{
1005-
Dereference(ptrs[i]);
1005+
Dereference(t);
10061006
}
10071007
}
10081008

@@ -1057,7 +1057,7 @@ void WritePtrInNode(in CursorItem stackItem, IntPtr newNode)
10571057
ptr = newNode;
10581058
}
10591059

1060-
internal unsafe bool FindExact(RootNode12 rootNode, ref StructList<CursorItem> stack, ReadOnlySpan<byte> key)
1060+
internal static unsafe bool FindExact(RootNode12 rootNode, ref StructList<CursorItem> stack, ReadOnlySpan<byte> key)
10611061
{
10621062
stack.Clear();
10631063
var top = rootNode.Root;
@@ -1083,15 +1083,15 @@ internal unsafe bool FindExact(RootNode12 rootNode, ref StructList<CursorItem> s
10831083
return false;
10841084
}
10851085

1086-
var comp = key.Slice(0, header._keyPrefixLength).SequenceCompareTo(prefix);
1086+
var comp = key[..header._keyPrefixLength].SequenceCompareTo(prefix);
10871087
if (comp != 0)
10881088
{
10891089
stack.Clear();
10901090
return false;
10911091
}
10921092
}
10931093

1094-
var keyRest = key.Slice(header._keyPrefixLength);
1094+
var keyRest = key[header._keyPrefixLength..];
10951095
if (header.HasLongKeys)
10961096
{
10971097
var keys = NodeUtils12.GetLongKeyPtrs(top);
@@ -1439,14 +1439,14 @@ internal static bool IsKeyPrefix(IntPtr nodePtr, int idx, ReadOnlySpan<byte> pre
14391439
if (header.HasLongKeys)
14401440
{
14411441
var keys = NodeUtils12.GetLongKeyPtrs(nodePtr);
1442-
return TreeNodeUtils.IsPrefix(NodeUtils12.LongKeyPtrToSpan(keys[idx]), prefix);
1442+
return ((ReadOnlySpan<byte>)NodeUtils12.LongKeyPtrToSpan(keys[idx])).StartsWith(prefix);
14431443
}
14441444
else
14451445
{
14461446
var keyOffsets = NodeUtils12.GetKeySpans(nodePtr, out var keySuffixes);
14471447
var ofs = keyOffsets[idx];
14481448
var lenSuffix = keyOffsets[idx + 1] - ofs;
1449-
return TreeNodeUtils.IsPrefix(keySuffixes.Slice(ofs, lenSuffix), prefix);
1449+
return ((ReadOnlySpan<byte>)keySuffixes.Slice(ofs, lenSuffix)).StartsWith(prefix);
14501450
}
14511451
}
14521452

BTDB/BTreeLib/Cursor12.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public long EraseTo(ICursor to)
9191

9292
public bool FindExact(in ReadOnlySpan<byte> key)
9393
{
94-
return _rootNode.Impl.FindExact(_rootNode, ref _stack, key);
94+
return BTreeImpl12.FindExact(_rootNode, ref _stack, key);
9595
}
9696

9797
public FindResult Find(in ReadOnlySpan<byte> key)
@@ -328,6 +328,8 @@ public bool KeyHasPrefix(in ReadOnlySpan<byte> prefix)
328328
{
329329
if (_stack.Count == 0)
330330
return false;
331+
if (prefix.Length == 0)
332+
return true;
331333
ref var stackItem = ref _stack[_stack.Count - 1];
332334
return BTreeImpl12.IsKeyPrefix(stackItem._node, stackItem._posInNode, prefix);
333335
}

BTDB/Buffer/TreeNodeUtils.cs

-7
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,6 @@ internal static unsafe void CopyMemory(IntPtr src, IntPtr dst, int size)
7777
Unsafe.CopyBlockUnaligned(dst.ToPointer(), src.ToPointer(), (uint)size);
7878
}
7979

80-
internal static bool IsPrefix(in ReadOnlySpan<byte> data, in ReadOnlySpan<byte> prefix)
81-
{
82-
if (data.Length < prefix.Length)
83-
return false;
84-
return data[..prefix.Length].SequenceEqual(prefix);
85-
}
86-
8780
internal static int FindFirstDifference(in ReadOnlySpan<byte> buf1, in ReadOnlySpan<byte> buf2)
8881
{
8982
return buf1.CommonPrefixLength(buf2);

BTDB/KVDBLayer/ReadOnly/ReadOnlyKeyValueDBTransaction.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ bool KeyMatchesPrefix(ReadOnlySpan<byte> prefix)
244244
prefix = prefix[nodePrefix.Length..];
245245
}
246246

247-
return TreeNodeUtils.IsPrefix(GetKeySuffixSpan(ownerBegin, top, top._pos), prefix);
247+
return GetKeySuffixSpan(ownerBegin, top, top._pos).StartsWith(prefix);
248248
}
249249

250250
static ReadOnlySpan<byte> GetKeySuffixSpan(nuint ownerBegin, in StackItem top, uint topPos)

BTDB/ODBLayer/RelationEnumerator.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public bool MoveNext()
105105
[SkipLocalsInit]
106106
unsafe bool FindNextKey(bool first = false)
107107
{
108-
Span<byte> buf = stackalloc byte[512];
108+
Span<byte> buf = stackalloc byte[1024];
109109
ref var writer = ref _key;
110110
var i = 0;
111111
if (first)
@@ -165,6 +165,8 @@ unsafe bool FindNextKey(bool first = false)
165165
writer.UpdateBuffer(key);
166166
return true;
167167
}
168+
169+
var dataDidntChangedForConstraint = i;
168170
for (var j = i; j < _constraints.Length; j++) _constraints[j].Offset = -1;
169171
var offsetPrefix = i > 0 ? _constraints[i - 1].Offset : _keyBytesCount;
170172
fixed (void* _ = key)
@@ -206,6 +208,11 @@ unsafe bool FindNextKey(bool first = false)
206208
}
207209
}
208210

211+
if (dataDidntChangedForConstraint < i && _skipNextOn == -1)
212+
{
213+
goto goNextKey;
214+
}
215+
209216
switch (_constraints[i].MatchType)
210217
{
211218
case IConstraint.MatchType.NoPrefix:

SimpleTester/GatherSpeedTest.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ public void Run()
7676
for (int i = 0; i < 2; i++)
7777
{
7878
var sw = System.Diagnostics.Stopwatch.StartNew();
79-
t.GatherById(coll, 0, 100, Constraint<ulong>.Any, Constraint<ulong>.Any, Constraint<ulong>.Any,
80-
Constraint.String.Exact("nonexistent"));
79+
var count = t.GatherById(coll, 0, 100, Constraint<ulong>.Any, Constraint<ulong>.Any, Constraint<ulong>.Any,
80+
Constraint.String.Contains("@"));
8181
sw.Stop();
82-
Console.WriteLine("GatherById took " + sw.ElapsedMilliseconds + "ms");
82+
Console.WriteLine("GatherById took " + sw.ElapsedMilliseconds + "ms Found " + count);
8383
}
8484
}
8585
}

0 commit comments

Comments
 (0)