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  bool duplicate = false);
146 
159  virtual void
160  asyncFetch(
161  uint256 const& hash,
162  std::uint32_t ledgerSeq,
163  std::function<void(std::shared_ptr<NodeObject> const&)>&& callback);
164 
170  virtual bool
171  storeLedger(std::shared_ptr<Ledger const> const& srcLedger) = 0;
172 
174  virtual void
175  sweep() = 0;
176 
183  {
184  return storeCount_;
185  }
186 
189  {
190  return fetchTotalCount_;
191  }
192 
195  {
196  return fetchHitCount_;
197  }
198 
200  getStoreSize() const
201  {
202  return storeSz_;
203  }
204 
206  getFetchSize() const
207  {
208  return fetchSz_;
209  }
210 
211  void
213 
215  int
216  fdRequired() const
217  {
218  return fdRequired_;
219  }
220 
221  virtual void
222  stop();
223 
224  bool
225  isStopping() const;
226 
229  [[nodiscard]] std::uint32_t
230  ledgersPerShard() const noexcept
231  {
232  return ledgersPerShard_;
233  }
234 
237  [[nodiscard]] std::uint32_t
238  earliestLedgerSeq() const noexcept
239  {
240  return earliestLedgerSeq_;
241  }
242 
245  [[nodiscard]] std::uint32_t
246  earliestShardIndex() const noexcept
247  {
248  return earliestShardIndex_;
249  }
250 
256  [[nodiscard]] std::uint32_t
257  firstLedgerSeq(std::uint32_t shardIndex) const noexcept
258  {
259  assert(shardIndex >= earliestShardIndex_);
260  if (shardIndex <= earliestShardIndex_)
261  return earliestLedgerSeq_;
262  return 1 + (shardIndex * ledgersPerShard_);
263  }
264 
270  [[nodiscard]] std::uint32_t
271  lastLedgerSeq(std::uint32_t shardIndex) const noexcept
272  {
273  assert(shardIndex >= earliestShardIndex_);
274  return (shardIndex + 1) * ledgersPerShard_;
275  }
276 
282  [[nodiscard]] std::uint32_t
283  seqToShardIndex(std::uint32_t ledgerSeq) const noexcept
284  {
285  assert(ledgerSeq >= earliestLedgerSeq_);
286  return (ledgerSeq - 1) / ledgersPerShard_;
287  }
288 
297  [[nodiscard]] std::uint32_t
298  maxLedgers(std::uint32_t shardIndex) const noexcept;
299 
300 protected:
303  int fdRequired_{0};
304 
307 
308  // The default is DEFAULT_LEDGERS_PER_SHARD (16384) to match the XRP ledger
309  // network. Can be set through the configuration file using the
310  // 'ledgers_per_shard' field under the 'node_db' and 'shard_db' stanzas.
311  // If specified, the value must be a multiple of 256 and equally assigned
312  // in both stanzas. Only unit tests or alternate networks should change
313  // this value.
315 
316  // The default is XRP_LEDGER_EARLIEST_SEQ (32570) to match the XRP ledger
317  // network's earliest allowed ledger sequence. Can be set through the
318  // configuration file using the 'earliest_seq' field under the 'node_db'
319  // and 'shard_db' stanzas. If specified, the value must be greater than zero
320  // and equally assigned in both stanzas. Only unit tests or alternate
321  // networks should change this value.
323 
324  // The earliest shard index
326 
327  // The maximum number of requests a thread extracts from the queue in an
328  // attempt to minimize the overhead of mutex acquisition. This is an
329  // advanced tunable, via the config file. The default value is 4.
330  int const requestBundle_;
331 
332  void
334  {
335  assert(count <= sz);
336  storeCount_ += count;
337  storeSz_ += sz;
338  }
339 
340  // Called by the public import function
341  void
342  importInternal(Backend& dstBackend, Database& srcDB);
343 
344  // Called by the public storeLedger function
345  bool
346  storeLedger(Ledger const& srcLedger, std::shared_ptr<Backend> dstBackend);
347 
348  void
349  updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
350  {
351  fetchTotalCount_ += fetches;
352  fetchHitCount_ += hits;
353  fetchDurationUs_ += duration;
354  }
355 
356 private:
362 
365 
366  // reads to do
367  std::map<
368  uint256,
373 
377 
380  uint256 const& hash,
381  std::uint32_t ledgerSeq,
382  FetchReport& fetchReport,
383  bool duplicate) = 0;
384 
392  virtual void
394 
401  getCounters() const
402  {
403  return std::nullopt;
404  }
405 
406  void
407  threadEntry();
408 };
409 
410 } // namespace NodeStore
411 } // namespace ripple
412 
413 #endif
ripple::NodeStore::Database::getFetchSize
std::uint32_t getFetchSize() const
Definition: Database.h:206
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:271
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:182
ripple::NodeStore::Database::fetchDurationUs_
std::atomic< std::uint64_t > fetchDurationUs_
Definition: Database.h:360
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:314
std::pair
ripple::NodeStore::Database::fdRequired_
int fdRequired_
Definition: Database.h:303
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:372
ripple::NodeStore::Database::requestBundle_
const int requestBundle_
Definition: Database.h:330
ripple::NodeStore::Database::fetchTotalCount_
std::atomic< std::uint64_t > fetchTotalCount_
Definition: Database.h:359
ripple::NodeStore::Database::asyncFetch
virtual 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:198
ripple::NodeStore::Database::sync
virtual void sync()=0
ripple::NodeStore::Database::fetchSz_
std::atomic< std::uint32_t > fetchSz_
Definition: Database.h:306
ripple::NodeStore::Database::stop
virtual void stop()
Definition: Database.cpp:165
ripple::NodeStore::FetchReport
Contains information about a fetch operation.
Definition: ripple/nodestore/Scheduler.h:32
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::readStopping_
std::atomic< bool > readStopping_
Definition: Database.h:374
ripple::NodeStore::Database::readThreads_
std::atomic< int > readThreads_
Definition: Database.h:375
ripple::NodeStore::Database::fetchHitCount_
std::atomic< std::uint32_t > fetchHitCount_
Definition: Database.h:305
ripple::NodeStore::Database::storeCount_
std::atomic< std::uint64_t > storeCount_
Definition: Database.h:357
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:550
ripple::NodeStore::Database::updateFetchMetrics
void updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
Definition: Database.h:349
ripple::NodeStore::Database::readLock_
std::mutex readLock_
Definition: Database.h:363
ripple::base_uint< 256 >
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:200
ripple::NodeStore::Database::storeSz_
std::atomic< std::uint64_t > storeSz_
Definition: Database.h:358
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:257
ripple::NodeStore::Database::importInternal
void importInternal(Backend &dstBackend, Database &srcDB)
Definition: Database.cpp:213
thread
ripple::Ledger
Holds a ledger.
Definition: Ledger.h:76
ripple::NodeStore::Database::readCondVar_
std::condition_variable readCondVar_
Definition: Database.h:364
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::~Database
virtual ~Database()
Destroy the node store.
Definition: Database.cpp:134
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:333
ripple::NodeStore::FetchType
FetchType
Definition: ripple/nodestore/Scheduler.h:29
ripple::NodeStore::Database::isStopping
bool isStopping() const
Definition: Database.cpp:146
ripple::NodeStore::Database::threadEntry
void threadEntry()
ripple::NodeStore::Database::getCounters
virtual std::optional< Backend::Counters< std::uint64_t > > getCounters() const
Retrieve backend read and write stats.
Definition: Database.h:401
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:301
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:283
ripple::NodeStore::Database::storeDurationUs_
std::atomic< std::uint64_t > storeDurationUs_
Definition: Database.h:361
ripple::NodeStore::Database::earliestShardIndex
std::uint32_t earliestShardIndex() const noexcept
Definition: Database.h:246
ripple::NodeStore::Database::getCountsJson
void getCountsJson(Json::Value &obj)
Definition: Database.cpp:378
condition_variable
ripple::NodeStore::Database::earliestLedgerSeq_
const std::uint32_t earliestLedgerSeq_
Definition: Database.h:322
ripple::NodeStore::Database::getFetchHitCount
std::uint32_t getFetchHitCount() const
Definition: Database.h:194
std::optional
std::mutex
STL class.
ripple::NodeStore::Database::earliestShardIndex_
const std::uint32_t earliestShardIndex_
Definition: Database.h:325
ripple::NodeStore::Database::fetchNodeObject
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
Definition: Database.cpp:252
ripple::NodeStore::Database::scheduler_
Scheduler & scheduler_
Definition: Database.h:302
ripple::NodeStore::Database::runningThreads_
std::atomic< int > runningThreads_
Definition: Database.h:376
ripple::NodeStore::Database::getFetchTotalCount
std::uint32_t getFetchTotalCount() const
Definition: Database.h:188
ripple::NodeStore::Database::earliestLedgerSeq
std::uint32_t earliestLedgerSeq() const noexcept
Definition: Database.h:238
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:152
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:230
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:216
ripple::NodeStore::Backend
A backend used for the NodeStore.
Definition: Backend.h:39