Skip to content

Commit 86f4619

Browse files
committedJan 30, 2024
Enable parallel BucketsDB loads
1 parent 6cfd9fd commit 86f4619

8 files changed

+94
-28
lines changed
 

‎src/bucket/BucketManager.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,11 @@ class BucketManager : NonMovableOrCopyable
207207
virtual void maybeSetIndex(std::shared_ptr<Bucket> b,
208208
std::unique_ptr<BucketIndex const>&& index) = 0;
209209

210-
virtual std::unique_ptr<SearchableBucketListSnapshot const>
210+
virtual std::unique_ptr<SearchableBucketListSnapshot>
211211
getSearchableBucketListSnapshot() const = 0;
212212

213+
virtual std::recursive_mutex& getBucketSnapshotMutex() const = 0;
214+
213215
// Scans BucketList for non-live entries to evict starting at the entry
214216
// pointed to by EvictionIterator. Scans until `maxEntriesToEvict` entries
215217
// have been evicted or maxEvictionScanSize bytes have been scanned.

‎src/bucket/BucketManagerImpl.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ BucketManagerImpl::scanForEvictionLegacySQL(AbstractLedgerTxn& ltx,
907907
}
908908
}
909909

910-
std::unique_ptr<SearchableBucketListSnapshot const>
910+
std::unique_ptr<SearchableBucketListSnapshot>
911911
BucketManagerImpl::getSearchableBucketListSnapshot() const
912912
{
913913
releaseAssertOrThrow(mApp.getConfig().isUsingBucketListDB() && mBucketList);
@@ -919,6 +919,12 @@ BucketManagerImpl::getSearchableBucketListSnapshot() const
919919
new SearchableBucketListSnapshot(mApp, *mBucketList));
920920
}
921921

922+
std::recursive_mutex&
923+
BucketManagerImpl::getBucketSnapshotMutex() const
924+
{
925+
return mBucketSnapshotMutex;
926+
}
927+
922928
medida::Meter&
923929
BucketManagerImpl::getBloomMissMeter() const
924930
{

‎src/bucket/BucketManagerImpl.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,9 @@ class BucketManagerImpl : public BucketManager
143143
void scanForEvictionLegacySQL(AbstractLedgerTxn& ltx,
144144
uint32_t ledgerSeq) override;
145145

146-
std::unique_ptr<SearchableBucketListSnapshot const>
146+
std::unique_ptr<SearchableBucketListSnapshot>
147147
getSearchableBucketListSnapshot() const override;
148+
std::recursive_mutex& getBucketSnapshotMutex() const override;
148149

149150
medida::Meter& getBloomMissMeter() const override;
150151
medida::Meter& getBloomLookupMeter() const override;

‎src/bucket/SearchableBucketListSnapshot.cpp

+28-16
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ SearchableBucketListSnapshot::isWithinAllowedLedgerDrift(
6161
return mLCL >= minimumLCL;
6262
}
6363

64+
void
65+
SearchableBucketListSnapshot::maybeUpdateSnapshot()
66+
{
67+
auto currLCL = mApp.getLedgerManager().getLastClosedLedgerNum();
68+
if (currLCL != mLCL)
69+
{
70+
mLCL = currLCL;
71+
mLevels.clear();
72+
73+
std::lock_guard<std::recursive_mutex> lock(
74+
mApp.getBucketManager().getBucketSnapshotMutex());
75+
auto& bl = mApp.getBucketManager().getBucketList();
76+
for (uint32_t i = 0; i < BucketList::kNumLevels; ++i)
77+
{
78+
auto const& level = bl.getLevel(i);
79+
mLevels.emplace_back(SearchableBucketLevelSnapshot(level));
80+
}
81+
}
82+
}
83+
6484
void
6585
SearchableBucketListSnapshot::loopAllBuckets(
6686
std::function<bool(SearchableBucketSnapshot const&)> f) const
@@ -85,13 +105,11 @@ SearchableBucketListSnapshot::loopAllBuckets(
85105
}
86106

87107
std::shared_ptr<LedgerEntry>
88-
SearchableBucketListSnapshot::getLedgerEntry(LedgerKey const& k) const
108+
SearchableBucketListSnapshot::getLedgerEntry(LedgerKey const& k)
89109
{
90110
ZoneScoped;
91111
auto timer = getPointLoadTimer(k.type()).TimeScope();
92-
93-
// Snapshots not currently supported, all access must be up to date
94-
releaseAssert(isWithinAllowedLedgerDrift(0));
112+
maybeUpdateSnapshot();
95113

96114
std::shared_ptr<LedgerEntry> result{};
97115

@@ -117,13 +135,11 @@ SearchableBucketListSnapshot::getLedgerEntry(LedgerKey const& k) const
117135

118136
std::vector<LedgerEntry>
119137
SearchableBucketListSnapshot::loadKeys(
120-
std::set<LedgerKey, LedgerEntryIdCmp> const& inKeys) const
138+
std::set<LedgerKey, LedgerEntryIdCmp> const& inKeys)
121139
{
122140
ZoneScoped;
123141
auto timer = recordBulkLoadMetrics("prefetch", inKeys.size()).TimeScope();
124-
125-
// Snapshots not currently supported, all access must be up to date
126-
releaseAssert(isWithinAllowedLedgerDrift(0));
142+
maybeUpdateSnapshot();
127143

128144
std::vector<LedgerEntry> entries;
129145

@@ -140,13 +156,11 @@ SearchableBucketListSnapshot::loadKeys(
140156

141157
std::vector<LedgerEntry>
142158
SearchableBucketListSnapshot::loadPoolShareTrustLinesByAccountAndAsset(
143-
AccountID const& accountID, Asset const& asset) const
159+
AccountID const& accountID, Asset const& asset)
144160
{
145161
ZoneScoped;
146162
auto timer = recordBulkLoadMetrics("poolshareTrustlines", 0).TimeScope();
147-
148-
// Snapshots not currently supported, all access must be up to date
149-
releaseAssert(isWithinAllowedLedgerDrift(0));
163+
maybeUpdateSnapshot();
150164

151165
UnorderedMap<LedgerKey, LedgerEntry> liquidityPoolToTrustline;
152166
UnorderedSet<LedgerKey> deadTrustlines;
@@ -189,13 +203,11 @@ SearchableBucketListSnapshot::loadPoolShareTrustLinesByAccountAndAsset(
189203

190204
std::vector<InflationWinner>
191205
SearchableBucketListSnapshot::loadInflationWinners(size_t maxWinners,
192-
int64_t minBalance) const
206+
int64_t minBalance)
193207
{
194208
ZoneScoped;
195209
auto timer = recordBulkLoadMetrics("inflationWinners", 0).TimeScope();
196-
197-
// Snapshots not currently supported, all access must be up to date
198-
releaseAssert(isWithinAllowedLedgerDrift(0));
210+
maybeUpdateSnapshot();
199211

200212
UnorderedMap<AccountID, int64_t> voteCount;
201213
UnorderedSet<AccountID> seen;

‎src/bucket/SearchableBucketListSnapshot.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct SearchableBucketLevelSnapshot
2121

2222
// A lightweight wrapper around the BucketList for thread safe BucketListDB
2323
// lookups
24-
class SearchableBucketListSnapshot : public NonMovable
24+
class SearchableBucketListSnapshot : public NonMovableOrCopyable
2525
{
2626
Application& mApp;
2727
std::vector<SearchableBucketLevelSnapshot> mLevels;
@@ -53,22 +53,25 @@ class SearchableBucketListSnapshot : public NonMovable
5353
// allowedLedgerDrift, lcl]
5454
bool isWithinAllowedLedgerDrift(uint32_t allowedLedgerDrift) const;
5555

56+
// Checks if snapshot is behind the current LCL and updates as necessary
57+
void maybeUpdateSnapshot();
58+
5659
SearchableBucketListSnapshot(Application& app, BucketList const& bl);
5760

5861
public:
5962
std::vector<LedgerEntry>
60-
loadKeys(std::set<LedgerKey, LedgerEntryIdCmp> const& inKeys) const;
63+
loadKeys(std::set<LedgerKey, LedgerEntryIdCmp> const& inKeys);
6164

6265
std::vector<LedgerEntry>
6366
loadPoolShareTrustLinesByAccountAndAsset(AccountID const& accountID,
64-
Asset const& asset) const;
67+
Asset const& asset);
6568

6669
std::vector<InflationWinner> loadInflationWinners(size_t maxWinners,
67-
int64_t minBalance) const;
70+
int64_t minBalance);
6871

69-
std::shared_ptr<LedgerEntry> getLedgerEntry(LedgerKey const& k) const;
72+
std::shared_ptr<LedgerEntry> getLedgerEntry(LedgerKey const& k);
7073

71-
friend std::unique_ptr<SearchableBucketListSnapshot const>
74+
friend std::unique_ptr<SearchableBucketListSnapshot>
7275
BucketManagerImpl::getSearchableBucketListSnapshot() const;
7376
};
7477
}

‎src/bucket/test/BucketListTests.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "bucket/BucketList.h"
1616
#include "bucket/BucketManager.h"
1717
#include "bucket/BucketOutputIterator.h"
18+
#include "bucket/SearchableBucketListSnapshot.h"
1819
#include "bucket/test/BucketTestUtils.h"
1920
#include "ledger/test/LedgerTestUtils.h"
2021
#include "lib/catch.hpp"
@@ -1113,6 +1114,47 @@ TEST_CASE_VERSIONS("eviction scan", "[bucketlist]")
11131114
});
11141115
}
11151116

1117+
TEST_CASE_VERSIONS("Searchable BucketListDB snapshots", "[bucketlist]")
1118+
{
1119+
VirtualClock clock;
1120+
Config cfg(getTestConfig(0, Config::TESTDB_IN_MEMORY_SQLITE));
1121+
cfg.EXPERIMENTAL_BUCKETLIST_DB = true;
1122+
1123+
auto app = createTestApplication<BucketTestApplication>(clock, cfg);
1124+
for_versions_from(20, *app, [&] {
1125+
LedgerManagerForBucketTests& lm = app->getLedgerManager();
1126+
auto& bm = app->getBucketManager();
1127+
1128+
auto entry =
1129+
LedgerTestUtils::generateValidLedgerEntryOfType(CLAIMABLE_BALANCE);
1130+
entry.data.claimableBalance().amount = 0;
1131+
1132+
auto searchableBL = bm.getSearchableBucketListSnapshot();
1133+
1134+
// Update entry every 5 ledgers so we can see bucket merge events
1135+
for (auto ledgerSeq = 1; ledgerSeq < 101; ++ledgerSeq)
1136+
{
1137+
if ((ledgerSeq - 1) % 5 == 0)
1138+
{
1139+
++entry.data.claimableBalance().amount;
1140+
entry.lastModifiedLedgerSeq = ledgerSeq;
1141+
lm.setNextLedgerEntryBatchForBucketTesting({}, {entry}, {});
1142+
}
1143+
else
1144+
{
1145+
lm.setNextLedgerEntryBatchForBucketTesting({}, {}, {});
1146+
}
1147+
1148+
closeLedger(*app);
1149+
1150+
// Snapshot should automatically update with latest version
1151+
auto loadedEntry =
1152+
searchableBL->getLedgerEntry(LedgerEntryKey(entry));
1153+
REQUIRE((loadedEntry && *loadedEntry == entry));
1154+
}
1155+
});
1156+
}
1157+
11161158
static std::string
11171159
formatX32(uint32_t v)
11181160
{

‎src/ledger/LedgerTxn.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3371,7 +3371,7 @@ LedgerTxnRoot::Impl::areEntriesMissingInCacheForOffer(OfferEntry const& oe)
33713371
return false;
33723372
}
33733373

3374-
SearchableBucketListSnapshot const&
3374+
SearchableBucketListSnapshot&
33753375
LedgerTxnRoot::Impl::getSearchableBucketListSnapshot() const
33763376
{
33773377
releaseAssert(mApp.getConfig().isUsingBucketListDB());

‎src/ledger/LedgerTxnImpl.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ class LedgerTxnRoot::Impl
740740
mutable BestOffers mBestOffers;
741741
mutable uint64_t mPrefetchHits{0};
742742
mutable uint64_t mPrefetchMisses{0};
743-
mutable std::unique_ptr<SearchableBucketListSnapshot const>
743+
mutable std::unique_ptr<SearchableBucketListSnapshot>
744744
mSearchableBucketListSnapshot{};
745745

746746
size_t mBulkLoadBatchSize;
@@ -874,7 +874,7 @@ class LedgerTxnRoot::Impl
874874

875875
bool areEntriesMissingInCacheForOffer(OfferEntry const& oe);
876876

877-
SearchableBucketListSnapshot const& getSearchableBucketListSnapshot() const;
877+
SearchableBucketListSnapshot& getSearchableBucketListSnapshot() const;
878878

879879
public:
880880
// Constructor has the strong exception safety guarantee

0 commit comments

Comments
 (0)
Please sign in to comment.