Skip to content

Commit 8ac1ff7

Browse files
authored
feat: Implement and use LedgerCacheInterface (#1955)
For #1200
1 parent 2684237 commit 8ac1ff7

File tree

68 files changed

+373
-181
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+373
-181
lines changed

src/app/ClioApplication.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "app/WebHandlers.hpp"
2424
#include "data/AmendmentCenter.hpp"
2525
#include "data/BackendFactory.hpp"
26+
#include "data/LedgerCache.hpp"
2627
#include "etl/ETLService.hpp"
2728
#include "etl/LoadBalancer.hpp"
2829
#include "etl/NetworkValidatedLedgers.hpp"
@@ -102,9 +103,10 @@ ClioApplication::run(bool const useNgWebServer)
102103
auto whitelistHandler = web::dosguard::WhitelistHandler{config_};
103104
auto dosGuard = web::dosguard::DOSGuard{config_, whitelistHandler};
104105
auto sweepHandler = web::dosguard::IntervalSweepHandler{config_, ioc, dosGuard};
106+
auto cache = data::LedgerCache{};
105107

106108
// Interface to the database
107-
auto backend = data::makeBackend(config_);
109+
auto backend = data::makeBackend(config_, cache);
108110

109111
auto const amendmentCenter = std::make_shared<data::AmendmentCenter const>(backend);
110112

src/data/BackendFactory.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "data/BackendInterface.hpp"
2323
#include "data/CassandraBackend.hpp"
24+
#include "data/LedgerCacheInterface.hpp"
2425
#include "data/cassandra/SettingsProvider.hpp"
2526
#include "util/log/Logger.hpp"
2627
#include "util/newconfig/ConfigDefinition.hpp"
@@ -38,10 +39,11 @@ namespace data {
3839
* @brief A factory function that creates the backend based on a config.
3940
*
4041
* @param config The clio config to use
42+
* @param cache The ledger cache to use
4143
* @return A shared_ptr<BackendInterface> with the selected implementation
4244
*/
4345
inline std::shared_ptr<BackendInterface>
44-
makeBackend(util::config::ClioConfigDefinition const& config)
46+
makeBackend(util::config::ClioConfigDefinition const& config, data::LedgerCacheInterface& cache)
4547
{
4648
static util::Logger const log{"Backend"}; // NOLINT(readability-identifier-naming)
4749
LOG(log.info()) << "Constructing BackendInterface";
@@ -53,7 +55,9 @@ makeBackend(util::config::ClioConfigDefinition const& config)
5355

5456
if (boost::iequals(type, "cassandra")) {
5557
auto const cfg = config.getObject("database." + type);
56-
backend = std::make_shared<data::cassandra::CassandraBackend>(data::cassandra::SettingsProvider{cfg}, readOnly);
58+
backend = std::make_shared<data::cassandra::CassandraBackend>(
59+
data::cassandra::SettingsProvider{cfg}, cache, readOnly
60+
);
5761
}
5862

5963
if (!backend)

src/data/BackendInterface.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ BackendInterface::fetchLedgerObject(
8787
boost::asio::yield_context yield
8888
) const
8989
{
90-
auto obj = cache_.get(key, sequence);
90+
auto obj = cache_.get().get(key, sequence);
9191
if (obj) {
9292
LOG(gLog.trace()) << "Cache hit - " << ripple::strHex(key);
9393
return obj;
@@ -126,7 +126,7 @@ BackendInterface::fetchLedgerObjects(
126126
results.resize(keys.size());
127127
std::vector<ripple::uint256> misses;
128128
for (size_t i = 0; i < keys.size(); ++i) {
129-
auto obj = cache_.get(keys[i], sequence);
129+
auto obj = cache_.get().get(keys[i], sequence);
130130
if (obj) {
131131
results[i] = *obj;
132132
} else {
@@ -156,7 +156,7 @@ BackendInterface::fetchSuccessorKey(
156156
boost::asio::yield_context yield
157157
) const
158158
{
159-
auto succ = cache_.getSuccessor(key, ledgerSequence);
159+
auto succ = cache_.get().getSuccessor(key, ledgerSequence);
160160
if (succ) {
161161
LOG(gLog.trace()) << "Cache hit - " << ripple::strHex(key);
162162
} else {

src/data/BackendInterface.hpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#pragma once
2121

2222
#include "data/DBHelpers.hpp"
23-
#include "data/LedgerCache.hpp"
23+
#include "data/LedgerCacheInterface.hpp"
2424
#include "data/Types.hpp"
2525
#include "etl/CorruptionDetector.hpp"
2626
#include "util/log/Logger.hpp"
@@ -40,6 +40,7 @@
4040
#include <cstddef>
4141
#include <cstdint>
4242
#include <exception>
43+
#include <functional>
4344
#include <optional>
4445
#include <shared_mutex>
4546
#include <string>
@@ -139,18 +140,27 @@ class BackendInterface {
139140
protected:
140141
mutable std::shared_mutex rngMtx_;
141142
std::optional<LedgerRange> range_;
142-
LedgerCache cache_;
143-
std::optional<etl::CorruptionDetector<LedgerCache>> corruptionDetector_;
143+
std::reference_wrapper<LedgerCacheInterface> cache_;
144+
std::optional<etl::CorruptionDetector> corruptionDetector_;
144145

145146
public:
146-
BackendInterface() = default;
147+
/**
148+
* @brief Construct a new backend interface instance.
149+
*
150+
* @param cache The ledger cache to use
151+
*/
152+
BackendInterface(LedgerCacheInterface& cache) : cache_{cache}
153+
{
154+
}
147155
virtual ~BackendInterface() = default;
148156

149-
// TODO: Remove this hack. Cache should not be exposed thru BackendInterface
157+
// TODO: Remove this hack once old ETL is removed.
158+
// Cache should not be exposed thru BackendInterface
159+
150160
/**
151161
* @return Immutable cache
152162
*/
153-
LedgerCache const&
163+
LedgerCacheInterface const&
154164
cache() const
155165
{
156166
return cache_;
@@ -159,7 +169,7 @@ class BackendInterface {
159169
/**
160170
* @return Mutable cache
161171
*/
162-
LedgerCache&
172+
LedgerCacheInterface&
163173
cache()
164174
{
165175
return cache_;
@@ -171,7 +181,7 @@ class BackendInterface {
171181
* @param detector The corruption detector to set
172182
*/
173183
void
174-
setCorruptionDetector(etl::CorruptionDetector<LedgerCache> detector)
184+
setCorruptionDetector(etl::CorruptionDetector detector)
175185
{
176186
corruptionDetector_ = std::move(detector);
177187
}

src/data/CassandraBackend.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "data/BackendInterface.hpp"
2323
#include "data/DBHelpers.hpp"
24+
#include "data/LedgerCacheInterface.hpp"
2425
#include "data/Types.hpp"
2526
#include "data/cassandra/Concepts.hpp"
2627
#include "data/cassandra/Handle.hpp"
@@ -88,10 +89,12 @@ class BasicCassandraBackend : public BackendInterface {
8889
* @brief Create a new cassandra/scylla backend instance.
8990
*
9091
* @param settingsProvider The settings provider to use
92+
* @param cache The ledger cache to use
9193
* @param readOnly Whether the database should be in readonly mode
9294
*/
93-
BasicCassandraBackend(SettingsProviderType settingsProvider, bool readOnly)
94-
: settingsProvider_{std::move(settingsProvider)}
95+
BasicCassandraBackend(SettingsProviderType settingsProvider, data::LedgerCacheInterface& cache, bool readOnly)
96+
: BackendInterface(cache)
97+
, settingsProvider_{std::move(settingsProvider)}
9598
, schema_{settingsProvider_}
9699
, handle_{settingsProvider_.getSettings()}
97100
, executor_{settingsProvider_.getSettings(), handle_}

src/data/LedgerCache.hpp

Lines changed: 19 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#pragma once
2121

22+
#include "data/LedgerCacheInterface.hpp"
2223
#include "data/Types.hpp"
2324
#include "util/prometheus/Counter.hpp"
2425
#include "util/prometheus/Label.hpp"
@@ -43,7 +44,7 @@ namespace data {
4344
/**
4445
* @brief Cache for an entire ledger.
4546
*/
46-
class LedgerCache {
47+
class LedgerCache : public LedgerCacheInterface {
4748
struct CacheEntry {
4849
uint32_t seq = 0;
4950
Blob blob;
@@ -83,109 +84,44 @@ class LedgerCache {
8384
std::unordered_set<ripple::uint256, ripple::hardened_hash<>> deletes_;
8485

8586
public:
86-
/**
87-
* @brief Update the cache with new ledger objects.
88-
*
89-
* @param objs The ledger objects to update cache with
90-
* @param seq The sequence to update cache for
91-
* @param isBackground Should be set to true when writing old data from a background thread
92-
*/
9387
void
94-
update(std::vector<LedgerObject> const& objs, uint32_t seq, bool isBackground = false);
95-
96-
/**
97-
* @brief Fetch a cached object by its key and sequence number.
98-
*
99-
* @param key The key to fetch for
100-
* @param seq The sequence to fetch for
101-
* @return If found in cache, will return the cached Blob; otherwise nullopt is returned
102-
*/
88+
update(std::vector<LedgerObject> const& objs, uint32_t seq, bool isBackground = false) override;
89+
10390
std::optional<Blob>
104-
get(ripple::uint256 const& key, uint32_t seq) const;
105-
106-
/**
107-
* @brief Gets a cached successor.
108-
*
109-
* Note: This function always returns std::nullopt when @ref isFull() returns false.
110-
*
111-
* @param key The key to fetch for
112-
* @param seq The sequence to fetch for
113-
* @return If found in cache, will return the cached successor; otherwise nullopt is returned
114-
*/
91+
get(ripple::uint256 const& key, uint32_t seq) const override;
92+
11593
std::optional<LedgerObject>
116-
getSuccessor(ripple::uint256 const& key, uint32_t seq) const;
117-
118-
/**
119-
* @brief Gets a cached predcessor.
120-
*
121-
* Note: This function always returns std::nullopt when @ref isFull() returns false.
122-
*
123-
* @param key The key to fetch for
124-
* @param seq The sequence to fetch for
125-
* @return If found in cache, will return the cached predcessor; otherwise nullopt is returned
126-
*/
94+
getSuccessor(ripple::uint256 const& key, uint32_t seq) const override;
95+
12796
std::optional<LedgerObject>
128-
getPredecessor(ripple::uint256 const& key, uint32_t seq) const;
97+
getPredecessor(ripple::uint256 const& key, uint32_t seq) const override;
12998

130-
/**
131-
* @brief Disables the cache.
132-
*/
13399
void
134-
setDisabled();
100+
setDisabled() override;
135101

136-
/**
137-
* @return true if the cache is disabled; false otherwise
138-
*/
139102
bool
140-
isDisabled() const;
141-
142-
/**
143-
* @brief Sets the full flag to true.
144-
*
145-
* This is used when cache loaded in its entirety at startup of the application. This can be either loaded from DB,
146-
* populated together with initial ledger download (on first run) or downloaded from a peer node (specified in
147-
* config).
148-
*/
103+
isDisabled() const override;
104+
149105
void
150-
setFull();
106+
setFull() override;
151107

152-
/**
153-
* @return The latest ledger sequence for which cache is available.
154-
*/
155108
uint32_t
156-
latestLedgerSequence() const;
109+
latestLedgerSequence() const override;
157110

158-
/**
159-
* @return true if the cache has all data for the most recent ledger; false otherwise
160-
*/
161111
bool
162-
isFull() const;
112+
isFull() const override;
163113

164-
/**
165-
* @return The total size of the cache.
166-
*/
167114
size_t
168-
size() const;
115+
size() const override;
169116

170-
/**
171-
* @return A number representing the success rate of hitting an object in the cache versus missing it.
172-
*/
173117
float
174-
getObjectHitRate() const;
118+
getObjectHitRate() const override;
175119

176-
/**
177-
* @return A number representing the success rate of hitting a successor in the cache versus missing it.
178-
*/
179120
float
180-
getSuccessorHitRate() const;
121+
getSuccessorHitRate() const override;
181122

182-
/**
183-
* @brief Waits until the cache contains a specific sequence.
184-
*
185-
* @param seq The sequence to wait for
186-
*/
187123
void
188-
waitUntilCacheContainsSeq(uint32_t seq);
124+
waitUntilCacheContainsSeq(uint32_t seq) override;
189125
};
190126

191127
} // namespace data

0 commit comments

Comments
 (0)