rippled
Loading...
Searching...
No Matches
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 <xrpld/nodestore/Factory.h>
21#include <xrpld/nodestore/Manager.h>
22#include <xrpl/basics/contract.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
29namespace ripple {
30namespace NodeStore {
31
33{
34 explicit MemoryDB() = default;
35
37 bool open = false;
39};
40
41class MemoryFactory : public Factory
42{
43private:
46
47public:
49 ~MemoryFactory() override;
50
52 getName() const override;
53
56 size_t keyBytes,
57 Section const& keyValues,
59 Scheduler& scheduler,
60 beast::Journal journal) override;
61
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
79class MemoryBackend : public Backend
80{
81private:
83
86 MemoryDB* db_{nullptr};
87
88public:
90 size_t keyBytes,
91 Section const& keyValues,
92 beast::Journal journal)
93 : name_(get(keyValues, "path")), journal_(journal)
94 {
95 boost::ignore_unused(journal_); // Keep unused journal_ just in case.
96 if (name_.empty())
97 Throw<std::runtime_error>("Missing path in Memory backend");
98 }
99
100 ~MemoryBackend() override
101 {
102 close();
103 }
104
106 getName() override
107 {
108 return name_;
109 }
110
111 void
112 open(bool createIfMissing) override
113 {
115 }
116
117 bool
118 isOpen() override
119 {
120 return static_cast<bool>(db_);
121 }
122
123 void
124 close() override
125 {
126 db_ = nullptr;
127 }
128
129 //--------------------------------------------------------------------------
130
131 Status
132 fetch(void const* key, std::shared_ptr<NodeObject>* pObject) override
133 {
134 XRPL_ASSERT(
135 db_, "ripple::NodeStore::MemoryBackend::fetch : non-null database");
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
152 {
154 results.reserve(hashes.size());
155 for (auto const& h : hashes)
156 {
158 Status status = fetch(h->begin(), &nObj);
159 if (status != ok)
160 results.push_back({});
161 else
162 results.push_back(nObj);
163 }
164
165 return {results, ok};
166 }
167
168 void
169 store(std::shared_ptr<NodeObject> const& object) override
170 {
171 XRPL_ASSERT(
172 db_, "ripple::NodeStore::MemoryBackend::store : non-null database");
174 db_->table.emplace(object->getHash(), object);
175 }
176
177 void
178 storeBatch(Batch const& batch) override
179 {
180 for (auto const& e : batch)
181 store(e);
182 }
183
184 void
185 sync() override
186 {
187 }
188
189 void
191 {
192 XRPL_ASSERT(
193 db_,
194 "ripple::NodeStore::MemoryBackend::for_each : non-null database");
195 for (auto const& e : db_->table)
196 f(e.second);
197 }
198
199 int
200 getWriteLoad() override
201 {
202 return 0;
203 }
204
205 void
206 setDeletePath() override
207 {
208 }
209
210 int
211 fdRequired() const override
212 {
213 return 0;
214 }
215};
216
217//------------------------------------------------------------------------------
218
220{
221 Manager::instance().insert(*this);
222}
223
225{
226 Manager::instance().erase(*this);
227}
228
231{
232 return "Memory";
233}
234
237 size_t keyBytes,
238 Section const& keyValues,
240 Scheduler& scheduler,
241 beast::Journal journal)
242{
243 return std::make_unique<MemoryBackend>(keyBytes, keyValues, journal);
244}
245
246} // namespace NodeStore
247} // namespace ripple
A generic endpoint for log messages.
Definition: Journal.h:59
A backend used for the NodeStore.
Definition: Backend.h:40
Base class for backend factories.
Definition: Factory.h:34
static Manager & instance()
Returns the instance of the manager singleton.
Definition: ManagerImp.cpp:116
virtual void erase(Factory &factory)=0
Remove a factory.
virtual void insert(Factory &factory)=0
Add a factory.
void close() override
Close the backend.
void store(std::shared_ptr< NodeObject > const &object) override
Store a single object.
void open(bool createIfMissing) override
Open the backend.
std::string getName() override
Get the human-readable name of this backend.
std::pair< std::vector< std::shared_ptr< NodeObject > >, Status > fetchBatch(std::vector< uint256 const * > const &hashes) override
Fetch a batch synchronously.
MemoryBackend(size_t keyBytes, Section const &keyValues, beast::Journal journal)
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
int getWriteLoad() override
Estimate the number of write operations pending.
void storeBatch(Batch const &batch) override
Store a group of objects.
void setDeletePath() override
Remove contents on disk upon destruction.
int fdRequired() const override
Returns the number of file descriptors the backend expects to need.
Status fetch(void const *key, std::shared_ptr< NodeObject > *pObject) override
Fetch a single object.
bool isOpen() override
Returns true is the database is open.
std::string getName() const override
Retrieve the name of this factory.
std::map< std::string, MemoryDB, boost::beast::iless > map_
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.
MemoryDB & open(std::string const &path)
Scheduling for asynchronous backend activity.
Holds a collection of configuration values.
Definition: BasicConfig.h:46
static base_uint fromVoid(void const *data)
Definition: base_uint.h:318
T empty(T... args)
T make_tuple(T... args)
static MemoryFactory memoryFactory
Status
Return codes from Backend operations.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
Definition: BasicConfig.h:356
T push_back(T... args)
T reserve(T... args)
T reset(T... args)
T size(T... args)
std::map< uint256 const, std::shared_ptr< NodeObject > > table