Skip to content

Commit

Permalink
Merge pull request #3962 from riemannulus/imp/use-bitfaster-caching
Browse files Browse the repository at this point in the history
🔴 refactor: use `Bitfaster.Caching` instead of `Libplanet.LruCahceNet`
  • Loading branch information
riemannulus authored Oct 10, 2024
2 parents bfd304b + 90c524a commit 1fba38e
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 64 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ To be released.
- (Libplanet.Net) Changed to no longer report `BlockHashDownloadState`
and `BlockDownloadState` during preloading. It is strongly advised
not to rely on these to track the progress of preloading. [[#3943]]
- (Libplanet.Store) Optimized LRU Cache for `HashNode` and `BlockSet`.
[[#3962]]

### Bug fixes

Expand All @@ -69,6 +71,7 @@ To be released.
[#3949]: https://github.com/planetarium/libplanet/pull/3949
[#3950]: https://github.com/planetarium/libplanet/pull/3950
[#3960]: https://github.com/planetarium/libplanet/pull/3960
[#3962]: https://github.com/planetarium/libplanet/pull/3962


Version 5.2.2
Expand Down
16 changes: 10 additions & 6 deletions src/Libplanet.Store/BlockSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BitFaster.Caching;
using BitFaster.Caching.Lru;
using Caching;
using Libplanet.Types.Blocks;

Expand All @@ -10,12 +12,14 @@ namespace Libplanet.Store
public class BlockSet : IReadOnlyDictionary<BlockHash, Block>
{
private readonly IStore _store;
private readonly LRUCache<BlockHash, Block> _cache;
private readonly ICache<BlockHash, Block> _cache;

public BlockSet(IStore store, int cacheSize = 4096)
{
_store = store;
_cache = new LRUCache<BlockHash, Block>(cacheSize, Math.Max(cacheSize / 64, 8));
_cache = new ConcurrentLruBuilder<BlockHash, Block>()
.WithCapacity(cacheSize)
.Build();
}

public IEnumerable<BlockHash> Keys =>
Expand Down Expand Up @@ -68,7 +72,7 @@ public Block this[BlockHash key]

value.ValidateTimestamp();
_store.PutBlock(value);
_cache.AddReplace(value.Hash, value);
_cache.AddOrUpdate(value.Hash, value);
}
}

Expand All @@ -82,7 +86,7 @@ public bool Remove(BlockHash key)
{
bool deleted = _store.DeleteBlock(key);

_cache.Remove(key);
_cache.TryRemove(key);

return deleted;
}
Expand Down Expand Up @@ -162,14 +166,14 @@ public IEnumerator<KeyValuePair<BlockHash, Block>> GetEnumerator()
else
{
// The cached block had been deleted on _store...
_cache.Remove(key);
_cache.TryRemove(key);
}
}

Block? fetched = _store.GetBlock(key);
if (fetched is { })
{
_cache.AddReplace(key, fetched);
_cache.AddOrUpdate(key, fetched);
}

return fetched;
Expand Down
68 changes: 10 additions & 58 deletions src/Libplanet.Store/HashNodeCache.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using System.Diagnostics;
using System;
using System.Security.Cryptography;
using System.Threading;
using Bencodex.Types;
using BitFaster.Caching;
using BitFaster.Caching.Lru;
using Libplanet.Common;
using Libplanet.Store.Trie;
using LruCacheNet;
using Serilog;

namespace Libplanet.Store
{
Expand All @@ -16,73 +15,26 @@ public class HashNodeCache
{
// FIXME: Tuned to 9c mainnet. Should be refactored to accept cache size as an argument.
private const int _cacheSize = 524_288;
private const int _reportPeriod = 60_000;

private LruCache<HashDigest<SHA256>, IValue> _cache;
private Stopwatch _stopwatch;
private int _attempts;
private int _hits;
private object _reportLock;
private ICache<HashDigest<SHA256>, IValue> _cache;

internal HashNodeCache()
{
_cache = new LruCache<HashDigest<SHA256>, IValue>(_cacheSize);
_stopwatch = new Stopwatch();
_attempts = 0;
_hits = 0;
_reportLock = new object();
_stopwatch.Start();
_cache = new ConcurrentLruBuilder<HashDigest<SHA256>, IValue>()
.WithMetrics()
.WithExpireAfterAccess(TimeSpan.FromMinutes(10))
.WithCapacity(_cacheSize)
.Build();
}

public bool TryGetValue(HashDigest<SHA256> hash, out IValue? value)
{
lock (_reportLock)
{
Report();
}

Interlocked.Increment(ref _attempts);
if (_cache.TryGetValue(hash, out value))
{
Interlocked.Increment(ref _hits);
return true;
}
else
{
value = null;
return false;
}
return _cache.TryGet(hash, out value);
}

public void AddOrUpdate(HashDigest<SHA256> hash, IValue value)
{
_cache.AddOrUpdate(hash, value);
}

private void Report()
{
long period = _stopwatch.ElapsedMilliseconds;
if (period > _reportPeriod)
{
Log
.ForContext("Source", nameof(HashNodeCache))
.ForContext("Tag", "Metric")
.ForContext("Subtag", "HashNodeCacheReport")
.Debug(
"Successfully fetched {HitCount} cached values out of last " +
"{AttemptCount} attempts with hitrate of {HitRate} and " +
"{CacheUsed}/{CacheSize} cache in use during last {PeriodMs} ms",
_hits,
_attempts,
(double)_hits / _attempts,
_cache.Count,
_cache.Capacity,
period);

_stopwatch.Restart();
Interlocked.Exchange(ref _attempts, 0);
Interlocked.Exchange(ref _hits, 0);
}
}
}
}
1 change: 1 addition & 0 deletions src/Libplanet.Store/Libplanet.Store.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BitFaster.Caching" Version="2.5.2" />
<PackageReference Include="System.Collections.Immutable" Version="1.*" />
<PackageReference Include="Bencodex" Version="0.16.0" />
<PackageReference Include="Caching.dll" Version="1.4.0.1" />
Expand Down

0 comments on commit 1fba38e

Please sign in to comment.