Skip to content

Commit ad7b164

Browse files
authored
Merge pull request #4176 from SirTyson/parallel-bl-db
Parallel bl db Reviewed-by: marta-lokhova
2 parents ededc67 + 916bb73 commit ad7b164

19 files changed

+1014
-543
lines changed

src/bucket/Bucket.cpp

+11-123
Original file line numberDiff line numberDiff line change
@@ -77,35 +77,6 @@ Bucket::Bucket()
7777
{
7878
}
7979

80-
std::unique_ptr<XDRInputFileStream>
81-
Bucket::openStream()
82-
{
83-
releaseAssertOrThrow(!mFilename.empty());
84-
auto streamPtr = std::make_unique<XDRInputFileStream>();
85-
streamPtr->open(mFilename.string());
86-
return std::move(streamPtr);
87-
}
88-
89-
XDRInputFileStream&
90-
Bucket::getIndexStream()
91-
{
92-
if (!mIndexStream)
93-
{
94-
mIndexStream = openStream();
95-
}
96-
return *mIndexStream;
97-
}
98-
99-
XDRInputFileStream&
100-
Bucket::getEvictionStream()
101-
{
102-
if (!mEvictionStream)
103-
{
104-
mEvictionStream = openStream();
105-
}
106-
return *mEvictionStream;
107-
}
108-
10980
Hash const&
11081
Bucket::getHash() const
11182
{
@@ -156,90 +127,6 @@ void
156127
Bucket::freeIndex()
157128
{
158129
mIndex.reset(nullptr);
159-
mIndexStream.reset(nullptr);
160-
}
161-
162-
std::optional<BucketEntry>
163-
Bucket::getEntryAtOffset(LedgerKey const& k, std::streamoff pos,
164-
size_t pageSize)
165-
{
166-
ZoneScoped;
167-
auto& stream = getIndexStream();
168-
stream.seek(pos);
169-
170-
BucketEntry be;
171-
if (pageSize == 0)
172-
{
173-
if (stream.readOne(be))
174-
{
175-
return std::make_optional(be);
176-
}
177-
}
178-
else if (stream.readPage(be, k, pageSize))
179-
{
180-
return std::make_optional(be);
181-
}
182-
183-
// Mark entry miss for metrics
184-
getIndex().markBloomMiss();
185-
return std::nullopt;
186-
}
187-
188-
std::optional<BucketEntry>
189-
Bucket::getBucketEntry(LedgerKey const& k)
190-
{
191-
ZoneScoped;
192-
auto pos = getIndex().lookup(k);
193-
if (pos.has_value())
194-
{
195-
return getEntryAtOffset(k, pos.value(), getIndex().getPageSize());
196-
}
197-
198-
return std::nullopt;
199-
}
200-
201-
// When searching for an entry, BucketList calls this function on every bucket.
202-
// Since the input is sorted, we do a binary search for the first key in keys.
203-
// If we find the entry, we remove the found key from keys so that later buckets
204-
// do not load shadowed entries. If we don't find the entry, we do not remove it
205-
// from keys so that it will be searched for again at a lower level.
206-
void
207-
Bucket::loadKeys(std::set<LedgerKey, LedgerEntryIdCmp>& keys,
208-
std::vector<LedgerEntry>& result)
209-
{
210-
ZoneScoped;
211-
212-
auto currKeyIt = keys.begin();
213-
auto const& index = getIndex();
214-
auto indexIter = index.begin();
215-
while (currKeyIt != keys.end() && indexIter != index.end())
216-
{
217-
auto [offOp, newIndexIter] = index.scan(indexIter, *currKeyIt);
218-
indexIter = newIndexIter;
219-
if (offOp)
220-
{
221-
auto entryOp =
222-
getEntryAtOffset(*currKeyIt, *offOp, getIndex().getPageSize());
223-
if (entryOp)
224-
{
225-
if (entryOp->type() != DEADENTRY)
226-
{
227-
result.push_back(entryOp->liveEntry());
228-
}
229-
230-
currKeyIt = keys.erase(currKeyIt);
231-
continue;
232-
}
233-
}
234-
235-
++currKeyIt;
236-
}
237-
}
238-
239-
std::vector<PoolID> const&
240-
Bucket::getPoolIDsByAsset(Asset const& asset) const
241-
{
242-
return getIndex().getPoolIDsByAsset(asset);
243130
}
244131

245132
#ifdef BUILD_TESTS
@@ -787,12 +674,12 @@ mergeCasesWithEqualKeys(MergeCounters& mc, BucketInputIterator& oi,
787674
}
788675

789676
bool
790-
Bucket::scanForEviction(AbstractLedgerTxn& ltx, EvictionIterator& iter,
791-
uint32_t& bytesToScan,
792-
uint32_t& remainingEntriesToEvict, uint32_t ledgerSeq,
793-
medida::Counter& entriesEvictedCounter,
794-
medida::Counter& bytesScannedForEvictionCounter,
795-
std::optional<EvictionMetrics>& metrics)
677+
Bucket::scanForEvictionLegacySQL(
678+
AbstractLedgerTxn& ltx, EvictionIterator& iter, uint32_t& bytesToScan,
679+
uint32_t& remainingEntriesToEvict, uint32_t ledgerSeq,
680+
medida::Counter& entriesEvictedCounter,
681+
medida::Counter& bytesScannedForEvictionCounter,
682+
std::optional<EvictionStatistics>& stats) const
796683
{
797684
ZoneScoped;
798685
if (isEmpty() ||
@@ -809,7 +696,8 @@ Bucket::scanForEviction(AbstractLedgerTxn& ltx, EvictionIterator& iter,
809696
return true;
810697
}
811698

812-
auto& stream = getEvictionStream();
699+
XDRInputFileStream stream{};
700+
stream.open(mFilename);
813701
stream.seek(iter.bucketFileOffset);
814702

815703
BucketEntry be;
@@ -844,10 +732,10 @@ Bucket::scanForEviction(AbstractLedgerTxn& ltx, EvictionIterator& iter,
844732
if (shouldEvict())
845733
{
846734
ZoneNamedN(evict, "evict entry", true);
847-
if (metrics.has_value())
735+
if (stats.has_value())
848736
{
849-
++metrics->numEntriesEvicted;
850-
metrics->evictedEntriesAgeSum +=
737+
++stats->numEntriesEvicted;
738+
stats->evictedEntriesAgeSum +=
851739
ledgerSeq - liveUntilLedger;
852740
}
853741

src/bucket/Bucket.h

+15-50
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace stellar
3838
class AbstractLedgerTxn;
3939
class Application;
4040
class BucketManager;
41-
struct EvictionMetrics;
41+
struct EvictionStatistics;
4242

4343
class Bucket : public std::enable_shared_from_this<Bucket>,
4444
public NonMovableOrCopyable
@@ -49,33 +49,9 @@ class Bucket : public std::enable_shared_from_this<Bucket>,
4949

5050
std::unique_ptr<BucketIndex const> mIndex{};
5151

52-
// Lazily-constructed and retained for read path, one for BucketListDB reads
53-
// and one for eviction scans
54-
std::unique_ptr<XDRInputFileStream> mIndexStream;
55-
std::unique_ptr<XDRInputFileStream> mEvictionStream;
56-
5752
// Returns index, throws if index not yet initialized
5853
BucketIndex const& getIndex() const;
5954

60-
// Returns (lazily-constructed) file stream for bucketDB search. Note
61-
// this might be in some random position left over from a previous read --
62-
// must be seek()'ed before use.
63-
XDRInputFileStream& getIndexStream();
64-
65-
// Returns (lazily-constructed) file stream for eviction scans. Unlike the
66-
// indexStream, this should retain its position in-between calls. However, a
67-
// node performing catchup or joining the network may need to begin evicting
68-
// mid-bucket, so this stream should still be seeked to the proper position
69-
// before reading.
70-
XDRInputFileStream& getEvictionStream();
71-
72-
// Loads the bucket entry for LedgerKey k. Starts at file offset pos and
73-
// reads until key is found or the end of the page.
74-
std::optional<BucketEntry>
75-
getEntryAtOffset(LedgerKey const& k, std::streamoff pos, size_t pageSize);
76-
77-
std::unique_ptr<XDRInputFileStream> openStream();
78-
7955
static std::string randomFileName(std::string const& tmpDir,
8056
std::string ext);
8157

@@ -109,18 +85,6 @@ class Bucket : public std::enable_shared_from_this<Bucket>,
10985
// Sets index, throws if index is already set
11086
void setIndex(std::unique_ptr<BucketIndex const>&& index);
11187

112-
// Loads bucket entry for LedgerKey k.
113-
std::optional<BucketEntry> getBucketEntry(LedgerKey const& k);
114-
115-
// Loads LedgerEntry's for given keys. When a key is found, the
116-
// entry is added to result and the key is removed from keys.
117-
void loadKeys(std::set<LedgerKey, LedgerEntryIdCmp>& keys,
118-
std::vector<LedgerEntry>& result);
119-
120-
// Return all PoolIDs that contain the given asset on either side of the
121-
// pool
122-
std::vector<PoolID> const& getPoolIDsByAsset(Asset const& asset) const;
123-
12488
// At version 11, we added support for INITENTRY and METAENTRY. Before this
12589
// we were only supporting LIVEENTRY and DEADENTRY.
12690
static constexpr ProtocolVersion
@@ -141,19 +105,6 @@ class Bucket : public std::enable_shared_from_this<Bucket>,
141105
static std::string randomBucketName(std::string const& tmpDir);
142106
static std::string randomBucketIndexName(std::string const& tmpDir);
143107

144-
// Returns false if eof reached or if Bucket protocol version < 20, true
145-
// otherwise. Modifies iter as the bucket is scanned. Also modifies
146-
// bytesToScan and remainingEntriesToEvict such that after this function
147-
// returns:
148-
// bytesToScan -= amount_bytes_scanned
149-
// remainingEntriesToEvict -= entries_evicted
150-
bool scanForEviction(AbstractLedgerTxn& ltx, EvictionIterator& iter,
151-
uint32_t& bytesToScan,
152-
uint32_t& remainingEntriesToEvict, uint32_t ledgerSeq,
153-
medida::Counter& entriesEvictedCounter,
154-
medida::Counter& bytesScannedForEvictionCounter,
155-
std::optional<EvictionMetrics>& metrics);
156-
157108
#ifdef BUILD_TESTS
158109
// "Applies" the bucket to the database. For each entry in the bucket,
159110
// if the entry is init or live, creates or updates the corresponding
@@ -169,6 +120,18 @@ class Bucket : public std::enable_shared_from_this<Bucket>,
169120

170121
#endif // BUILD_TESTS
171122

123+
// Returns false if eof reached, true otherwise. Modifies iter as the bucket
124+
// is scanned. Also modifies bytesToScan and maxEntriesToEvict such that
125+
// after this function returns:
126+
// bytesToScan -= amount_bytes_scanned
127+
// maxEntriesToEvict -= entries_evicted
128+
bool scanForEvictionLegacySQL(
129+
AbstractLedgerTxn& ltx, EvictionIterator& iter, uint32_t& bytesToScan,
130+
uint32_t& remainingEntriesToEvict, uint32_t ledgerSeq,
131+
medida::Counter& entriesEvictedCounter,
132+
medida::Counter& bytesScannedForEvictionCounter,
133+
std::optional<EvictionStatistics>& stats) const;
134+
172135
// Create a fresh bucket from given vectors of init (created) and live
173136
// (updated) LedgerEntries, and dead LedgerEntryKeys. The bucket will
174137
// be sorted, hashed, and adopted in the provided BucketManager.
@@ -201,5 +164,7 @@ class Bucket : public std::enable_shared_from_this<Bucket>,
201164
static uint32_t getBucketVersion(std::shared_ptr<Bucket> const& bucket);
202165
static uint32_t
203166
getBucketVersion(std::shared_ptr<Bucket const> const& bucket);
167+
168+
friend class BucketSnapshot;
204169
};
205170
}

0 commit comments

Comments
 (0)