rippled
DatabaseRotatingImp.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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 #include <ripple/app/ledger/Ledger.h>
21 #include <ripple/nodestore/impl/DatabaseRotatingImp.h>
22 #include <ripple/protocol/HashPrefix.h>
23 
24 namespace ripple {
25 namespace NodeStore {
26 
28  std::string const& name,
29  Scheduler& scheduler,
30  int readThreads,
31  Stoppable& parent,
32  std::shared_ptr<Backend> writableBackend,
33  std::shared_ptr<Backend> archiveBackend,
34  Section const& config,
36  : DatabaseRotating(name, parent, scheduler, readThreads, config, j)
37  , pCache_(std::make_shared<TaggedCache<uint256, NodeObject>>(
38  name,
41  stopwatch(),
42  j))
43  , nCache_(std::make_shared<KeyCache<uint256>>(
44  name,
45  stopwatch(),
48  , writableBackend_(std::move(writableBackend))
49  , archiveBackend_(std::move(archiveBackend))
50 {
51  if (writableBackend_)
52  fdRequired_ += writableBackend_->fdRequired();
53  if (archiveBackend_)
54  fdRequired_ += archiveBackend_->fdRequired();
55  setParent(parent);
56 }
57 
58 void
61  std::string const& writableBackendName)> const& f)
62 {
63  std::lock_guard lock(mutex_);
64 
65  auto newBackend = f(writableBackend_->getName());
66  archiveBackend_->setDeletePath();
67  archiveBackend_ = std::move(writableBackend_);
68  writableBackend_ = std::move(newBackend);
69 }
70 
73 {
74  std::lock_guard lock(mutex_);
75  return writableBackend_->getName();
76 }
77 
80 {
81  std::lock_guard lock(mutex_);
82  return writableBackend_->getWriteLoad();
83 }
84 
85 void
87 {
88  auto const backend = [&] {
89  std::lock_guard lock(mutex_);
90  return writableBackend_;
91  }();
92 
93  importInternal(*backend, source);
94 }
95 
96 bool
98 {
99  auto const backend = [&] {
100  std::lock_guard lock(mutex_);
101  return writableBackend_;
102  }();
103 
104  return Database::storeLedger(
105  *srcLedger, backend, pCache_, nCache_, nullptr);
106 }
107 
108 void
110  NodeObjectType type,
111  Blob&& data,
112  uint256 const& hash,
113  std::uint32_t seq)
114 {
115  auto nObj = NodeObject::createObject(type, std::move(data), hash);
116  pCache_->canonicalize_replace_cache(hash, nObj);
117 
118  auto const backend = [&] {
119  std::lock_guard lock(mutex_);
120  return writableBackend_;
121  }();
122  backend->store(nObj);
123 
124  nCache_->erase(hash);
125  storeStats(nObj->getData().size());
126 }
127 
128 bool
130  uint256 const& hash,
131  std::uint32_t seq,
133 {
134  // See if the object is in cache
135  object = pCache_->fetch(hash);
136  if (object || nCache_->touch_if_exists(hash))
137  return true;
138 
139  // Otherwise post a read
140  Database::asyncFetch(hash, seq, pCache_, nCache_);
141  return false;
142 }
143 
144 void
146 {
147  pCache_->setTargetSize(size);
148  pCache_->setTargetAge(age);
149  nCache_->setTargetSize(size);
150  nCache_->setTargetAge(age);
151 }
152 
153 void
155 {
156  pCache_->sweep();
157  nCache_->sweep();
158 }
159 
162 {
163  auto [writable, archive] = [&] {
164  std::lock_guard lock(mutex_);
166  }();
167 
168  // Try to fetch from the writable backend
169  auto nObj = fetchInternal(hash, writable);
170  if (!nObj)
171  {
172  // Otherwise try to fetch from the archive backend
173  nObj = fetchInternal(hash, archive);
174  if (nObj)
175  {
176  {
177  // Refresh the writable backend pointer
178  std::lock_guard lock(mutex_);
179  writable = writableBackend_;
180  }
181 
182  // Update writable backend with data from the archive backend
183  writable->store(nObj);
184  nCache_->erase(hash);
185  }
186  }
187  return nObj;
188 }
189 
190 void
193 {
194  auto [writable, archive] = [&] {
195  std::lock_guard lock(mutex_);
197  }();
198 
199  // Iterate the writable backend
200  writable->for_each(f);
201 
202  // Iterate the archive backend
203  archive->for_each(f);
204 }
205 
206 } // namespace NodeStore
207 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
ripple::NodeStore::DatabaseRotatingImp::rotateWithLock
void rotateWithLock(std::function< std::unique_ptr< NodeStore::Backend >(std::string const &writableBackendName)> const &f) override
Rotates the backends.
Definition: DatabaseRotatingImp.cpp:59
ripple::NodeStore::cacheTargetSize
@ cacheTargetSize
Definition: nodestore/impl/Tuning.h:28
ripple::NodeStore::DatabaseRotatingImp::archiveBackend_
std::shared_ptr< Backend > archiveBackend_
Definition: DatabaseRotatingImp.h:123
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:53
std::string
STL class.
std::shared_ptr
STL class.
ripple::TaggedCache
Map/cache combination.
Definition: TaggedCache.h:52
ripple::NodeStore::DatabaseRotatingImp::sweep
void sweep() override
Remove expired entries from the positive and negative caches.
Definition: DatabaseRotatingImp.cpp:154
ripple::NodeStore::DatabaseRotatingImp::tune
void tune(int size, std::chrono::seconds age) override
Set the maximum number of entries and maximum cache age for both caches.
Definition: DatabaseRotatingImp.cpp:145
ripple::NodeStore::Database::fdRequired_
int fdRequired_
Definition: Database.h:244
std::vector< unsigned char >
ripple::NodeObjectType
NodeObjectType
The types of node objects.
Definition: NodeObject.h:32
ripple::NodeObject::createObject
static std::shared_ptr< NodeObject > createObject(NodeObjectType type, Blob &&data, uint256 const &hash)
Create an object from fields.
Definition: NodeObject.cpp:37
std::chrono::seconds
ripple::NodeStore::DatabaseRotatingImp::DatabaseRotatingImp
DatabaseRotatingImp()=delete
ripple::NodeStore::DatabaseRotatingImp::store
void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t seq) override
Store the object.
Definition: DatabaseRotatingImp.cpp:109
std::lock_guard
STL class.
ripple::stopwatch
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:86
std::function
ripple::NodeStore::DatabaseRotatingImp::getName
std::string getName() const override
Retrieve the name associated with this backend.
Definition: DatabaseRotatingImp.cpp:72
ripple::Stoppable::setParent
void setParent(Stoppable &parent)
Set the parent of this Stoppable.
Definition: Stoppable.cpp:43
ripple::base_uint< 256 >
ripple::NodeStore::DatabaseRotatingImp::getWriteLoad
std::int32_t getWriteLoad() const override
Retrieve the estimated number of pending write operations.
Definition: DatabaseRotatingImp.cpp:79
ripple::Stoppable
Provides an interface for starting and stopping.
Definition: Stoppable.h:201
ripple::NodeStore::Database::importInternal
void importInternal(Backend &dstBackend, Database &srcDB)
Definition: Database.cpp:158
ripple::NodeStore::DatabaseRotatingImp::asyncFetch
bool asyncFetch(uint256 const &hash, std::uint32_t seq, std::shared_ptr< NodeObject > &object) override
Fetch an object without waiting.
Definition: DatabaseRotatingImp.cpp:129
ripple::NodeStore::cacheTargetAge
constexpr std::chrono::seconds cacheTargetAge
Definition: nodestore/impl/Tuning.h:36
ripple::NodeStore::DatabaseRotatingImp::mutex_
std::mutex mutex_
Definition: DatabaseRotatingImp.h:124
ripple::NodeStore::DatabaseRotatingImp::storeLedger
bool storeLedger(std::shared_ptr< Ledger const > const &srcLedger) override
Copies a ledger stored in a different database to this one.
Definition: DatabaseRotatingImp.cpp:97
ripple::NodeStore::Database::storeStats
void storeStats(size_t sz)
Definition: Database.h:250
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::int32_t
ripple::NodeStore::DatabaseRotating
Definition: DatabaseRotating.h:33
ripple::NodeStore::Scheduler
Scheduling for asynchronous backend activity.
Definition: ripple/nodestore/Scheduler.h:57
ripple::NodeStore::DatabaseRotatingImp::import
void import(Database &source) override
Import objects from another database.
Definition: DatabaseRotatingImp.cpp:86
ripple::NodeStore::Database::fetchInternal
std::shared_ptr< NodeObject > fetchInternal(uint256 const &hash, std::shared_ptr< Backend > backend)
Definition: Database.cpp:123
ripple::NodeStore::DatabaseRotatingImp::fetchFrom
std::shared_ptr< NodeObject > fetchFrom(uint256 const &hash, std::uint32_t seq) override
Definition: DatabaseRotatingImp.cpp:161
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
Copies a ledger stored in a different database to this one.
std
STL namespace.
ripple::NodeStore::Database::asyncFetch
virtual bool asyncFetch(uint256 const &hash, std::uint32_t seq, std::shared_ptr< NodeObject > &object)=0
Fetch an object without waiting.
std::make_pair
T make_pair(T... args)
ripple::NodeObject
A simple object that the Ledger uses to store entries.
Definition: NodeObject.h:48
ripple::KeyCache
Maintains a cache of keys with no associated data.
Definition: KeyCache.h:43
std::unique_ptr
STL class.
ripple::NodeStore::DatabaseRotatingImp::for_each
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
Definition: DatabaseRotatingImp.cpp:191
ripple::NodeStore::DatabaseRotatingImp::writableBackend_
std::shared_ptr< Backend > writableBackend_
Definition: DatabaseRotatingImp.h:122
ripple::NodeStore::DatabaseRotatingImp::nCache_
std::shared_ptr< KeyCache< uint256 > > nCache_
Definition: DatabaseRotatingImp.h:120
ripple::NodeStore::DatabaseRotatingImp::pCache_
std::shared_ptr< TaggedCache< uint256, NodeObject > > pCache_
Definition: DatabaseRotatingImp.h:117