5
5
#include " bucket/LiveBucketIndex.h"
6
6
#include " bucket/BucketIndexUtils.h"
7
7
#include " bucket/BucketManager.h"
8
+ #include " bucket/BucketUtils.h"
8
9
#include " bucket/DiskIndex.h"
9
10
#include " util/Fs.h"
10
11
#include " util/GlobalChecks.h"
@@ -65,21 +66,6 @@ LiveBucketIndex::LiveBucketIndex(BucketManager& bm,
65
66
pageSize, filename);
66
67
mDiskIndex = std::make_unique<DiskIndex<LiveBucket>>(
67
68
bm, filename, pageSize, hash, ctx, hasher);
68
-
69
- auto percentCached = bm.getConfig ().BUCKETLIST_DB_CACHED_PERCENT ;
70
- if (percentCached > 0 )
71
- {
72
- auto const & counters = mDiskIndex ->getBucketEntryCounters ();
73
- auto cacheSize = (counters.numEntries () * percentCached) / 100 ;
74
-
75
- // Minimum cache size of 100 if we are going to cache a non-zero
76
- // number of entries
77
- // We don't want to reserve here, since caches only live as long as
78
- // the lifetime of the Bucket and fill relatively slowly
79
- mCache = std::make_unique<CacheT>(std::max<size_t >(cacheSize, 100 ),
80
- /* separatePRNG=*/ false ,
81
- /* reserve=*/ false );
82
- }
83
69
}
84
70
}
85
71
@@ -95,6 +81,50 @@ LiveBucketIndex::LiveBucketIndex(BucketManager const& bm, Archive& ar,
95
81
releaseAssertOrThrow (pageSize != 0 );
96
82
}
97
83
84
+ void
85
+ LiveBucketIndex::maybeInitializeCache (size_t bucketListTotalAccounts,
86
+ size_t maxBucketListAccountsToCache) const
87
+ {
88
+ // Everything is already in memory, no need for a redundant cache.
89
+ if (mInMemoryIndex )
90
+ {
91
+ return ;
92
+ }
93
+
94
+ // Cache is already initialized
95
+ if (std::shared_lock<std::shared_mutex> lock (mCacheMutex ); mCache )
96
+ {
97
+ return ;
98
+ }
99
+
100
+ releaseAssert (mDiskIndex );
101
+
102
+ auto accountsInThisBucket =
103
+ mDiskIndex ->getBucketEntryCounters ().entryTypeCounts .at (
104
+ LedgerEntryTypeAndDurability::ACCOUNT);
105
+
106
+ // Nothing to cache
107
+ if (accountsInThisBucket == 0 )
108
+ {
109
+ return ;
110
+ }
111
+
112
+ std::unique_lock<std::shared_mutex> lock (mCacheMutex );
113
+ if (bucketListTotalAccounts < maxBucketListAccountsToCache)
114
+ {
115
+ // We can cache the entire bucket
116
+ mCache = std::make_unique<CacheT>(bucketListTotalAccounts);
117
+ }
118
+ else
119
+ {
120
+ double percentAccountsInBucket =
121
+ static_cast <double >(accountsInThisBucket) / bucketListTotalAccounts;
122
+ auto cacheSize = static_cast <size_t >(bucketListTotalAccounts *
123
+ percentAccountsInBucket);
124
+ mCache = std::make_unique<CacheT>(cacheSize);
125
+ }
126
+ }
127
+
98
128
LiveBucketIndex::IterT
99
129
LiveBucketIndex::begin () const
100
130
{
@@ -133,7 +163,7 @@ LiveBucketIndex::markBloomMiss() const
133
163
std::shared_ptr<BucketEntry const >
134
164
LiveBucketIndex::getCachedEntry (LedgerKey const & k) const
135
165
{
136
- if (shouldUseCache ())
166
+ if (shouldUseCache () && isCachedType (k) )
137
167
{
138
168
std::shared_lock<std::shared_mutex> lock (mCacheMutex );
139
169
auto cachePtr = mCache ->maybeGet (k);
@@ -262,6 +292,24 @@ LiveBucketIndex::getBucketEntryCounters() const
262
292
return mInMemoryIndex ->getBucketEntryCounters ();
263
293
}
264
294
295
+ bool
296
+ LiveBucketIndex::shouldUseCache () const
297
+ {
298
+ if (mDiskIndex )
299
+ {
300
+ std::shared_lock<std::shared_mutex> lock (mCacheMutex );
301
+ return mCache != nullptr ;
302
+ }
303
+
304
+ return false ;
305
+ }
306
+
307
+ bool
308
+ LiveBucketIndex::isCachedType (LedgerKey const & lk)
309
+ {
310
+ return lk.type () == ACCOUNT;
311
+ }
312
+
265
313
void
266
314
LiveBucketIndex::maybeAddToCache (
267
315
std::shared_ptr<BucketEntry const > const & entry) const
@@ -270,6 +318,10 @@ LiveBucketIndex::maybeAddToCache(
270
318
{
271
319
releaseAssertOrThrow (entry);
272
320
auto k = getBucketLedgerKey (*entry);
321
+ if (!isCachedType (k))
322
+ {
323
+ return ;
324
+ }
273
325
274
326
// If we are adding an entry to the cache, we must have missed it
275
327
// earlier.
0 commit comments