Skip to content

Commit 2552c85

Browse files
committed
New SpanByteLruCache and BonBuilder speedup.
1 parent 9b0394c commit 2552c85

File tree

6 files changed

+628
-14
lines changed

6 files changed

+628
-14
lines changed

BTDB/Bon/Bon.cs

+21-11
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,9 @@ enum State
358358
StructList<ulong> _objKeys = new();
359359
MemWriter _topData;
360360
uint _items = 0;
361-
readonly LruCache<string, ulong> _strCache = new(512);
362-
readonly LruCache<(bool IsClass, StructList<ulong> ObjKeys), ulong> _objKeysCache = new(64);
361+
LruCache<string, ulong>? _strCache = null;
362+
SpanByteLruCache<ulong>? _u8Cache = null;
363+
LruCache<(bool IsClass, StructList<ulong> ObjKeys), ulong>? _objKeysCache = null;
363364
HashSet<string>? _objKeysSet;
364365

365366
public BonBuilder(in MemWriter memWriter)
@@ -640,16 +641,16 @@ public void FinishObject()
640641
rootData = ref _stack[0].Item2;
641642
}
642643

643-
if (!_objKeysCache.TryGetValue((false, objKeys), out var posKeys))
644+
_objKeysCache ??= new();
645+
ref var posKeys = ref _objKeysCache.GetOrAddValueRef((false, objKeys), out var added);
646+
if (added)
644647
{
645648
posKeys = (ulong)rootData.GetCurrentPosition();
646649
rootData.WriteVUInt32(items);
647650
foreach (var keyOfs in objKeys)
648651
{
649652
rootData.WriteVUInt64(keyOfs);
650653
}
651-
652-
_objKeysCache[(false, objKeys)] = posKeys;
653654
}
654655

655656
var pos = rootData.GetCurrentPosition();
@@ -695,16 +696,16 @@ public void FinishClass()
695696
rootData = ref _stack[0].Item2;
696697
}
697698

698-
if (!_objKeysCache.TryGetValue((true, objKeys), out var posKeys))
699+
_objKeysCache ??= new();
700+
ref var posKeys = ref _objKeysCache.GetOrAddValueRef((true, objKeys), out var added);
701+
if (added)
699702
{
700703
posKeys = (ulong)rootData.GetCurrentPosition();
701704
rootData.WriteVUInt32(items);
702705
foreach (var keyOfs in objKeys)
703706
{
704707
rootData.WriteVUInt64(keyOfs);
705708
}
706-
707-
_objKeysCache[(true, objKeys)] = posKeys;
708709
}
709710

710711
var pos = rootData.GetCurrentPosition();
@@ -846,7 +847,9 @@ void ThrowWrongState()
846847

847848
ulong WriteDedupString(string value)
848849
{
849-
if (_strCache.TryGetValue(value, out var pos))
850+
_strCache ??= new(512);
851+
ref var pos = ref _strCache.GetOrAddValueRef(value, out var added);
852+
if (!added)
850853
{
851854
return pos;
852855
}
@@ -859,21 +862,28 @@ ulong WriteDedupString(string value)
859862

860863
pos = (ulong)writer.GetCurrentPosition();
861864
writer.WriteStringInUtf8(value);
862-
_strCache[value] = pos;
863865
return pos;
864866
}
865867

866868
ulong WriteDedupString(ReadOnlySpan<byte> value)
867869
{
870+
_u8Cache ??= new(512);
871+
ref var pos = ref _u8Cache.GetOrAddValueRef(value, out var added);
872+
if (!added)
873+
{
874+
return pos;
875+
}
876+
868877
ref var writer = ref _topData;
869878
if (_stack.Count > 0)
870879
{
871880
writer = ref _stack[0].Data;
872881
}
873882

874-
var pos = (ulong)writer.GetCurrentPosition();
883+
pos = (ulong)writer.GetCurrentPosition();
875884
writer.WriteVUInt32((uint)value.Length);
876885
writer.WriteBlock(value);
886+
_u8Cache[value] = pos;
877887
return pos;
878888
}
879889

BTDB/Collections/LruCache.cs

+14-2
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,20 @@ public bool Remove(TKey key)
181181
return false;
182182
}
183183

184-
public ref TValue this[TKey key] => ref GetOrAddValueRef(key);
184+
public void Clear()
185+
{
186+
Array.Clear(_buckets);
187+
Array.Clear(_entries, 0, _count);
188+
_count = 0;
189+
_freeList = -1;
190+
UsageHead = -1;
191+
UsageTail = -1;
192+
}
193+
194+
public ref TValue this[TKey key] => ref GetOrAddValueRef(key, out _);
185195

186196
// Not safe for concurrent _reads_ (at least, if either of them add)
187-
public ref TValue GetOrAddValueRef(TKey key)
197+
public ref TValue GetOrAddValueRef(TKey key, out bool added)
188198
{
189199
if (key == null) HashHelpers.ThrowKeyArgumentNullException();
190200
var entries = _entries;
@@ -216,6 +226,7 @@ public ref TValue GetOrAddValueRef(TKey key)
216226
UsageHead = i;
217227
}
218228

229+
added = false;
219230
return ref entries[i].Value;
220231
}
221232

@@ -229,6 +240,7 @@ public ref TValue GetOrAddValueRef(TKey key)
229240
collisionCount++;
230241
}
231242

243+
added = true;
232244
return ref AddKey(key, bucketIndex, hash);
233245
}
234246

0 commit comments

Comments
 (0)