rippled
MemoryFactory.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/basics/contract.h>
21 #include <ripple/nodestore/Factory.h>
22 #include <ripple/nodestore/Manager.h>
23 #include <boost/beast/core/string.hpp>
24 #include <boost/core/ignore_unused.hpp>
25 #include <map>
26 #include <memory>
27 #include <mutex>
28 
29 namespace ripple {
30 namespace NodeStore {
31 
32 struct MemoryDB
33 {
34  explicit MemoryDB() = default;
35 
37  bool open = false;
39 };
40 
41 class MemoryFactory : public Factory
42 {
43 private:
46 
47 public:
48  MemoryFactory();
49  ~MemoryFactory() override;
50 
52  getName() const override;
53 
56  size_t keyBytes,
57  Section const& keyValues,
58  std::size_t burstSize,
59  Scheduler& scheduler,
60  beast::Journal journal) override;
61 
62  MemoryDB&
63  open(std::string const& path)
64  {
66  auto const result = map_.emplace(
67  std::piecewise_construct, std::make_tuple(path), std::make_tuple());
68  MemoryDB& db = result.first->second;
69  if (db.open)
70  Throw<std::runtime_error>("already open");
71  return db;
72  }
73 };
74 
76 
77 //------------------------------------------------------------------------------
78 
79 class MemoryBackend : public Backend
80 {
81 private:
83 
86  MemoryDB* db_{nullptr};
87 
88 public:
90  size_t keyBytes,
91  Section const& keyValues,
92  Scheduler& scheduler,
93  beast::Journal journal)
94  : name_(get<std::string>(keyValues, "path")), journal_(journal)
95  {
96  boost::ignore_unused(journal_); // Keep unused journal_ just in case.
97  if (name_.empty())
98  Throw<std::runtime_error>("Missing path in Memory backend");
99  }
100 
101  ~MemoryBackend() override
102  {
103  close();
104  }
105 
107  getName() override
108  {
109  return name_;
110  }
111 
112  void
113  open(bool createIfMissing) override
114  {
116  }
117 
118  bool
119  isOpen() override
120  {
121  return static_cast<bool>(db_);
122  }
123 
124  void
125  close() override
126  {
127  db_ = nullptr;
128  }
129 
130  //--------------------------------------------------------------------------
131 
132  Status
133  fetch(void const* key, std::shared_ptr<NodeObject>* pObject) override
134  {
135  assert(db_);
136  uint256 const hash(uint256::fromVoid(key));
137 
139 
140  Map::iterator iter = db_->table.find(hash);
141  if (iter == db_->table.end())
142  {
143  pObject->reset();
144  return notFound;
145  }
146  *pObject = iter->second;
147  return ok;
148  }
149 
150  bool
151  canFetchBatch() override
152  {
153  return false;
154  }
155 
157  fetchBatch(std::vector<uint256 const*> const& hashes) override
158  {
160  results.reserve(hashes.size());
161  for (auto const& h : hashes)
162  {
164  Status status = fetch(h->begin(), &nObj);
165  if (status != ok)
166  results.push_back({});
167  else
168  results.push_back(nObj);
169  }
170 
171  return {results, ok};
172  }
173 
174  void
175  store(std::shared_ptr<NodeObject> const& object) override
176  {
177  assert(db_);
179  db_->table.emplace(object->getHash(), object);
180  }
181 
182  void
183  storeBatch(Batch const& batch) override
184  {
185  for (auto const& e : batch)
186  store(e);
187  }
188 
189  void
190  sync() override
191  {
192  }
193 
194  void
196  {
197  assert(db_);
198  for (auto const& e : db_->table)
199  f(e.second);
200  }
201 
202  int
203  getWriteLoad() override
204  {
205  return 0;
206  }
207 
208  void
209  setDeletePath() override
210  {
211  }
212 
213  void
214  verify() override
215  {
216  }
217 
218  int
219  fdRequired() const override
220  {
221  return 0;
222  }
223 };
224 
225 //------------------------------------------------------------------------------
226 
228 {
229  Manager::instance().insert(*this);
230 }
231 
233 {
234  Manager::instance().erase(*this);
235 }
236 
239 {
240  return "Memory";
241 }
242 
245  size_t keyBytes,
246  Section const& keyValues,
247  std::size_t,
248  Scheduler& scheduler,
249  beast::Journal journal)
250 {
251  return std::make_unique<MemoryBackend>(
252  keyBytes, keyValues, scheduler, journal);
253 }
254 
255 } // namespace NodeStore
256 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
ripple::NodeStore::MemoryFactory::createInstance
std::unique_ptr< Backend > createInstance(size_t keyBytes, Section const &keyValues, std::size_t burstSize, Scheduler &scheduler, beast::Journal journal) override
Create an instance of this factory's backend.
Definition: MemoryFactory.cpp:244
ripple::NodeStore::Factory
Base class for backend factories.
Definition: Factory.h:33
std::make_tuple
T make_tuple(T... args)
ripple::NodeStore::MemoryBackend::isOpen
bool isOpen() override
Returns true is the database is open.
Definition: MemoryFactory.cpp:119
std::string
STL class.
std::shared_ptr< NodeObject >
ripple::NodeStore::MemoryBackend::fdRequired
int fdRequired() const override
Returns the number of file descriptors the backend expects to need.
Definition: MemoryFactory.cpp:219
ripple::NodeStore::ok
@ ok
Definition: nodestore/Types.h:45
ripple::NodeStore::Manager::erase
virtual void erase(Factory &factory)=0
Remove a factory.
ripple::NodeStore::MemoryFactory
Definition: MemoryFactory.cpp:41
std::pair
std::vector::reserve
T reserve(T... args)
ripple::NodeStore::MemoryBackend::~MemoryBackend
~MemoryBackend() override
Definition: MemoryFactory.cpp:101
std::vector
STL class.
std::vector::size
T size(T... args)
ripple::NodeStore::MemoryFactory::getName
std::string getName() const override
Retrieve the name of this factory.
Definition: MemoryFactory.cpp:238
ripple::NodeStore::MemoryBackend::db_
MemoryDB * db_
Definition: MemoryFactory.cpp:86
std::lock_guard
STL class.
ripple::NodeStore::MemoryBackend::setDeletePath
void setDeletePath() override
Remove contents on disk upon destruction.
Definition: MemoryFactory.cpp:209
std::function
ripple::NodeStore::MemoryBackend::getName
std::string getName() override
Get the human-readable name of this backend.
Definition: MemoryFactory.cpp:107
ripple::NodeStore::MemoryBackend::fetch
Status fetch(void const *key, std::shared_ptr< NodeObject > *pObject) override
Fetch a single object.
Definition: MemoryFactory.cpp:133
ripple::NodeStore::MemoryBackend::store
void store(std::shared_ptr< NodeObject > const &object) override
Store a single object.
Definition: MemoryFactory.cpp:175
std::shared_ptr::reset
T reset(T... args)
ripple::NodeStore::MemoryFactory::~MemoryFactory
~MemoryFactory() override
Definition: MemoryFactory.cpp:232
std::vector::push_back
T push_back(T... args)
ripple::NodeStore::notFound
@ notFound
Definition: nodestore/Types.h:46
ripple::NodeStore::MemoryFactory::map_
std::map< std::string, MemoryDB, boost::beast::iless > map_
Definition: MemoryFactory.cpp:45
ripple::base_uint< 256 >
ripple::NodeStore::MemoryFactory::MemoryFactory
MemoryFactory()
Definition: MemoryFactory.cpp:227
ripple::NodeStore::MemoryBackend::close
void close() override
Close the backend.
Definition: MemoryFactory.cpp:125
ripple::NodeStore::Manager::insert
virtual void insert(Factory &factory)=0
Add a factory.
ripple::NodeStore::MemoryFactory::mutex_
std::mutex mutex_
Definition: MemoryFactory.cpp:44
ripple::NodeStore::MemoryBackend::MemoryBackend
MemoryBackend(size_t keyBytes, Section const &keyValues, Scheduler &scheduler, beast::Journal journal)
Definition: MemoryFactory.cpp:89
ripple::NodeStore::MemoryFactory::open
MemoryDB & open(std::string const &path)
Definition: MemoryFactory.cpp:63
ripple::NodeStore::MemoryDB::table
std::map< uint256 const, std::shared_ptr< NodeObject > > table
Definition: MemoryFactory.cpp:38
ripple::NodeStore::MemoryBackend::getWriteLoad
int getWriteLoad() override
Estimate the number of write operations pending.
Definition: MemoryFactory.cpp:203
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
map
ripple::NodeStore::Scheduler
Scheduling for asynchronous backend activity.
Definition: ripple/nodestore/Scheduler.h:60
ripple::NodeStore::MemoryBackend::storeBatch
void storeBatch(Batch const &batch) override
Store a group of objects.
Definition: MemoryFactory.cpp:183
memory
ripple::NodeStore::MemoryDB::open
bool open
Definition: MemoryFactory.cpp:37
ripple::NodeStore::MemoryBackend
Definition: MemoryFactory.cpp:79
ripple::NodeStore::Status
Status
Return codes from Backend operations.
Definition: nodestore/Types.h:44
ripple::NodeStore::MemoryDB
Definition: MemoryFactory.cpp:32
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::NodeStore::MemoryBackend::journal_
const beast::Journal journal_
Definition: MemoryFactory.cpp:85
ripple::NodeStore::MemoryDB::mutex
std::mutex mutex
Definition: MemoryFactory.cpp:36
ripple::NodeStore::MemoryBackend::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: MemoryFactory.cpp:195
std
STL namespace.
ripple::base_uint< 256 >::fromVoid
static base_uint fromVoid(void const *data)
Definition: base_uint.h:223
ripple::NodeStore::memoryFactory
static MemoryFactory memoryFactory
Definition: MemoryFactory.cpp:75
std::string::empty
T empty(T... args)
ripple::NodeStore::MemoryBackend::open
void open(bool createIfMissing) override
Open the backend.
Definition: MemoryFactory.cpp:113
mutex
std::size_t
ripple::NodeStore::MemoryBackend::sync
void sync() override
Definition: MemoryFactory.cpp:190
ripple::NodeStore::MemoryBackend::verify
void verify() override
Perform consistency checks on database.
Definition: MemoryFactory.cpp:214
ripple::NodeStore::MemoryBackend::fetchBatch
std::pair< std::vector< std::shared_ptr< NodeObject > >, Status > fetchBatch(std::vector< uint256 const * > const &hashes) override
Fetch a batch synchronously.
Definition: MemoryFactory.cpp:157
ripple::NodeStore::MemoryBackend::canFetchBatch
bool canFetchBatch() override
Return true if batch fetches are optimized.
Definition: MemoryFactory.cpp:151
ripple::NodeStore::MemoryBackend::name_
std::string name_
Definition: MemoryFactory.cpp:84
ripple::NodeStore::Manager::instance
static Manager & instance()
Returns the instance of the manager singleton.
Definition: ManagerImp.cpp:128
std::unique_ptr
STL class.
ripple::get
T & get(EitherAmount &amt)
Definition: AmountSpec.h:116
ripple::NodeStore::MemoryDB::MemoryDB
MemoryDB()=default
ripple::NodeStore::Backend
A backend used for the NodeStore.
Definition: Backend.h:39