rippled
Database.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2017 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_NODESTORE_DATABASE_H_INCLUDED
21 #define RIPPLE_NODESTORE_DATABASE_H_INCLUDED
22 
23 #include <ripple/basics/TaggedCache.h>
24 #include <ripple/nodestore/Backend.h>
25 #include <ripple/nodestore/NodeObject.h>
26 #include <ripple/nodestore/Scheduler.h>
27 #include <ripple/protocol/SystemParameters.h>
28 
29 #include <condition_variable>
30 #include <thread>
31 
32 namespace ripple {
33 
34 class Ledger;
35 
36 namespace NodeStore {
37 
51 class Database
52 {
53 public:
54  Database() = delete;
55 
63  Database(
64  Scheduler& scheduler,
65  int readThreads,
66  Section const& config,
67  beast::Journal j);
68 
73  virtual ~Database();
74 
79  virtual std::string
80  getName() const = 0;
81 
83  virtual void
84  importDatabase(Database& source) = 0;
85 
89  virtual std::int32_t
90  getWriteLoad() const = 0;
91 
104  virtual void
105  store(
106  NodeObjectType type,
107  Blob&& data,
108  uint256 const& hash,
109  std::uint32_t ledgerSeq) = 0;
110 
111  /* Check if two ledgers are in the same database
112 
113  If these two sequence numbers map to the same database,
114  the result of a fetch with either sequence number would
115  be identical.
116 
117  @param s1 The first sequence number
118  @param s2 The second sequence number
119 
120  @return 'true' if both ledgers would be in the same DB
121 
122  */
123  virtual bool
125 
126  virtual void
127  sync() = 0;
128 
142  uint256 const& hash,
143  std::uint32_t ledgerSeq = 0,
144  FetchType fetchType = FetchType::synchronous);
145 
158  void
159  asyncFetch(
160  uint256 const& hash,
161  std::uint32_t ledgerSeq,
162  std::function<void(std::shared_ptr<NodeObject> const&)>&& callback);
163 
169  virtual bool
170  storeLedger(std::shared_ptr<Ledger const> const& srcLedger) = 0;
171 
173  virtual void
174  sweep() = 0;
175 
182  {
183  return storeCount_;
184  }
185 
188  {
189  return fetchTotalCount_;
190  }
191 
194  {
195  return fetchHitCount_;
196  }
197 
199  getStoreSize() const
200  {
201  return storeSz_;
202  }
203 
205  getFetchSize() const
206  {
207  return fetchSz_;
208  }
209 
210  void
212 
214  int
215  fdRequired() const
216  {
217  return fdRequired_;
218  }
219 
220  virtual void
221  stop();
222 
223  bool
224  isStopping() const;
225 
228  [[nodiscard]] std::uint32_t
229  ledgersPerShard() const noexcept
230  {
231  return ledgersPerShard_;
232  }
233 
236  [[nodiscard]] std::uint32_t
237  earliestLedgerSeq() const noexcept
238  {
239  return earliestLedgerSeq_;
240  }
241 
244  [[nodiscard]] std::uint32_t
245  earliestShardIndex() const noexcept
246  {
247  return earliestShardIndex_;
248  }
249 
255  [[nodiscard]] std::uint32_t
256  firstLedgerSeq(std::uint32_t shardIndex) const noexcept
257  {
258  assert(shardIndex >= earliestShardIndex_);
259  if (shardIndex <= earliestShardIndex_)
260  return earliestLedgerSeq_;
261  return 1 + (shardIndex * ledgersPerShard_);
262  }
263 
269  [[nodiscard]] std::uint32_t
270  lastLedgerSeq(std::uint32_t shardIndex) const noexcept
271  {
272  assert(shardIndex >= earliestShardIndex_);
273  return (shardIndex + 1) * ledgersPerShard_;
274  }
275 
281  [[nodiscard]] std::uint32_t
282  seqToShardIndex(std::uint32_t ledgerSeq) const noexcept
283  {
284  assert(ledgerSeq >= earliestLedgerSeq_);
285  return (ledgerSeq - 1) / ledgersPerShard_;
286  }
287 
296  [[nodiscard]] std::uint32_t
297  maxLedgers(std::uint32_t shardIndex) const noexcept;
298 
299 protected:
302  int fdRequired_{0};
303 
306 
307  // The default is DEFAULT_LEDGERS_PER_SHARD (16384) to match the XRP ledger
308  // network. Can be set through the configuration file using the
309  // 'ledgers_per_shard' field under the 'node_db' and 'shard_db' stanzas.
310  // If specified, the value must be a multiple of 256 and equally assigned
311  // in both stanzas. Only unit tests or alternate networks should change
312  // this value.
314 
315  // The default is XRP_LEDGER_EARLIEST_SEQ (32570) to match the XRP ledger
316  // network's earliest allowed ledger sequence. Can be set through the
317  // configuration file using the 'earliest_seq' field under the 'node_db'
318  // and 'shard_db' stanzas. If specified, the value must be greater than zero
319  // and equally assigned in both stanzas. Only unit tests or alternate
320  // networks should change this value.
322 
323  // The earliest shard index
325 
326  void
328  {
329  assert(count <= sz);
330  storeCount_ += count;
331  storeSz_ += sz;
332  }
333 
334  // Called by the public import function
335  void
336  importInternal(Backend& dstBackend, Database& srcDB);
337 
338  // Called by the public storeLedger function
339  bool
340  storeLedger(Ledger const& srcLedger, std::shared_ptr<Backend> dstBackend);
341 
342  void
343  updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
344  {
345  fetchTotalCount_ += fetches;
346  fetchHitCount_ += hits;
347  fetchDurationUs_ += duration;
348  }
349 
350 private:
356 
359 
360  // reads to do
361  std::map<
362  uint256,
367 
368  // last read
370 
372  bool readStopping_{false};
373 
376  uint256 const& hash,
377  std::uint32_t ledgerSeq,
378  FetchReport& fetchReport) = 0;
379 
387  virtual void
389 
396  getCounters() const
397  {
398  return std::nullopt;
399  }
400 
401  void
402  threadEntry();
403 };
404 
405 } // namespace NodeStore
406 } // namespace ripple
407 
408 #endif
ripple::NodeStore::Database::getFetchSize
std::uint32_t getFetchSize() const
Definition: Database.h:205
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:42
ripple::NodeStore::Database::lastLedgerSeq
std::uint32_t lastLedgerSeq(std::uint32_t shardIndex) const noexcept
Calculates the last ledger sequence for a given shard index.
Definition: Database.h:270
ripple::NodeStore::Database::readLastHash_
uint256 readLastHash_
Definition: Database.h:369
ripple::NodeStore::Database::getWriteLoad
virtual std::int32_t getWriteLoad() const =0
Retrieve the estimated number of pending write operations.
ripple::NodeStore::Database::getStoreCount
std::uint64_t getStoreCount() const
Gather statistics pertaining to read and write activities.
Definition: Database.h:181
ripple::NodeStore::Database::fetchDurationUs_
std::atomic< std::uint64_t > fetchDurationUs_
Definition: Database.h:354
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:51
std::string
STL class.
std::shared_ptr< NodeObject >
ripple::NodeStore::Database::ledgersPerShard_
const std::uint32_t ledgersPerShard_
Definition: Database.h:313
std::pair
ripple::NodeStore::Database::fdRequired_
int fdRequired_
Definition: Database.h:302
std::vector< unsigned char >
ripple::NodeObjectType
NodeObjectType
The types of node objects.
Definition: NodeObject.h:32
ripple::NodeStore::Database::read_
std::map< uint256, std::vector< std::pair< std::uint32_t, std::function< void(std::shared_ptr< NodeObject > const &)> > > > read_
Definition: Database.h:366
ripple::NodeStore::Database::fetchTotalCount_
std::atomic< std::uint64_t > fetchTotalCount_
Definition: Database.h:353
ripple::NodeStore::Database::asyncFetch
void asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::function< void(std::shared_ptr< NodeObject > const &)> &&callback)
Fetch an object without waiting.
Definition: Database.cpp:107
ripple::NodeStore::Database::sync
virtual void sync()=0
ripple::NodeStore::Database::fetchSz_
std::atomic< std::uint32_t > fetchSz_
Definition: Database.h:305
ripple::NodeStore::Database::stop
virtual void stop()
Definition: Database.cpp:89
ripple::NodeStore::FetchReport
Contains information about a fetch operation.
Definition: ripple/nodestore/Scheduler.h:32
ripple::NodeStore::Database::readStopping_
bool readStopping_
Definition: Database.h:372
std::function
ripple::NodeStore::Database::store
virtual void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t ledgerSeq)=0
Store the object.
ripple::NodeStore::Database::fetchHitCount_
std::atomic< std::uint32_t > fetchHitCount_
Definition: Database.h:304
ripple::NodeStore::Database::storeCount_
std::atomic< std::uint64_t > storeCount_
Definition: Database.h:351
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:529
ripple::NodeStore::Database::updateFetchMetrics
void updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
Definition: Database.h:343
ripple::NodeStore::Database::readLock_
std::mutex readLock_
Definition: Database.h:357
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:75
ripple::NodeStore::Database::getName
virtual std::string getName() const =0
Retrieve the name associated with this backend.
ripple::NodeStore::Database::getStoreSize
std::uint64_t getStoreSize() const
Definition: Database.h:199
ripple::NodeStore::Database::storeSz_
std::atomic< std::uint64_t > storeSz_
Definition: Database.h:352
ripple::NodeStore::Database::firstLedgerSeq
std::uint32_t firstLedgerSeq(std::uint32_t shardIndex) const noexcept
Calculates the first ledger sequence for a given shard index.
Definition: Database.h:256
ripple::NodeStore::Database::importInternal
void importInternal(Backend &dstBackend, Database &srcDB)
Definition: Database.cpp:119
thread
ripple::Ledger
Holds a ledger.
Definition: Ledger.h:76
ripple::NodeStore::Database::readCondVar_
std::condition_variable readCondVar_
Definition: Database.h:358
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::int32_t
std::atomic< std::uint32_t >
std::map
STL class.
ripple::NodeStore::Scheduler
Scheduling for asynchronous backend activity.
Definition: ripple/nodestore/Scheduler.h:60
ripple::NodeStore::Database::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous)
Fetch a node object.
Definition: Database.cpp:158
ripple::NodeStore::Database::~Database
virtual ~Database()
Destroy the node store.
Definition: Database.cpp:57
ripple::NodeStore::Database::for_each
virtual void for_each(std::function< void(std::shared_ptr< NodeObject >)> f)=0
Visit every object in the database This is usually called during import.
ripple::NodeStore::Database::sweep
virtual void sweep()=0
Remove expired entries from the positive and negative caches.
ripple::NodeStore::Database::storeStats
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition: Database.h:327
ripple::NodeStore::FetchType
FetchType
Definition: ripple/nodestore/Scheduler.h:29
ripple::NodeStore::Database::isStopping
bool isStopping() const
Definition: Database.cpp:69
ripple::NodeStore::Database::threadEntry
void threadEntry()
Definition: Database.cpp:283
ripple::NodeStore::Database::getCounters
virtual std::optional< Backend::Counters< std::uint64_t > > getCounters() const
Retrieve backend read and write stats.
Definition: Database.h:396
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::NodeStore::Database::storeLedger
virtual bool storeLedger(std::shared_ptr< Ledger const > const &srcLedger)=0
Store a ledger from a different database.
ripple::NodeStore::Database::j_
const beast::Journal j_
Definition: Database.h:300
ripple::NodeStore::Database::readThreads_
std::vector< std::thread > readThreads_
Definition: Database.h:371
ripple::NodeStore::Database::seqToShardIndex
std::uint32_t seqToShardIndex(std::uint32_t ledgerSeq) const noexcept
Calculates the shard index for a given ledger sequence.
Definition: Database.h:282
ripple::NodeStore::Database::storeDurationUs_
std::atomic< std::uint64_t > storeDurationUs_
Definition: Database.h:355
ripple::NodeStore::Database::earliestShardIndex
std::uint32_t earliestShardIndex() const noexcept
Definition: Database.h:245
ripple::NodeStore::Database::getCountsJson
void getCountsJson(Json::Value &obj)
Definition: Database.cpp:329
condition_variable
ripple::NodeStore::Database::earliestLedgerSeq_
const std::uint32_t earliestLedgerSeq_
Definition: Database.h:321
ripple::NodeStore::Database::getFetchHitCount
std::uint32_t getFetchHitCount() const
Definition: Database.h:193
std::optional
std::mutex
STL class.
ripple::NodeStore::Database::earliestShardIndex_
const std::uint32_t earliestShardIndex_
Definition: Database.h:324
ripple::NodeStore::Database::scheduler_
Scheduler & scheduler_
Definition: Database.h:301
ripple::NodeStore::Database::getFetchTotalCount
std::uint32_t getFetchTotalCount() const
Definition: Database.h:187
ripple::NodeStore::Database::earliestLedgerSeq
std::uint32_t earliestLedgerSeq() const noexcept
Definition: Database.h:237
ripple::NodeStore::Database::isSameDB
virtual bool isSameDB(std::uint32_t s1, std::uint32_t s2)=0
ripple::NodeStore::Database::maxLedgers
std::uint32_t maxLedgers(std::uint32_t shardIndex) const noexcept
Calculates the maximum ledgers for a given shard index.
Definition: Database.cpp:76
ripple::NodeStore::FetchType::synchronous
@ synchronous
ripple::NodeStore::Database::importDatabase
virtual void importDatabase(Database &source)=0
Import objects from another database.
ripple::NodeStore::Database::ledgersPerShard
std::uint32_t ledgersPerShard() const noexcept
Definition: Database.h:229
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::NodeStore::Database::Database
Database()=delete
ripple::NodeStore::Database::fdRequired
int fdRequired() const
Returns the number of file descriptors the database expects to need.
Definition: Database.h:215
ripple::NodeStore::Backend
A backend used for the NodeStore.
Definition: Backend.h:39