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 <xrpl/basics/contract.h>
21#include <xrpl/nodestore/Factory.h>
22#include <xrpl/nodestore/Manager.h>
23
24#include <boost/beast/core/string.hpp>
25#include <boost/core/ignore_unused.hpp>
26
27#include <map>
28#include <memory>
29#include <mutex>
30
31namespace ripple {
32namespace NodeStore {
33
42
43class MemoryFactory : public Factory
44{
45private:
49
50public:
51 explicit MemoryFactory(Manager& manager);
52
54 getName() const override;
55
58 size_t keyBytes,
59 Section const& keyValues,
61 Scheduler& scheduler,
62 beast::Journal journal) override;
63
65 open(std::string const& path)
66 {
68 auto const result = map_.emplace(
70 MemoryDB& db = result.first->second;
71 if (db.open)
72 Throw<std::runtime_error>("already open");
73 return db;
74 }
75};
76
78
79void
81{
82 static MemoryFactory instance{manager};
83 memoryFactory = &instance;
84}
85
86//------------------------------------------------------------------------------
87
88class MemoryBackend : public Backend
89{
90private:
92
95 MemoryDB* db_{nullptr};
96
97public:
99 size_t keyBytes,
100 Section const& keyValues,
101 beast::Journal journal)
102 : name_(get(keyValues, "path")), journal_(journal)
103 {
104 boost::ignore_unused(journal_); // Keep unused journal_ just in case.
105 if (name_.empty())
106 Throw<std::runtime_error>("Missing path in Memory backend");
107 }
108
109 ~MemoryBackend() override
110 {
111 close();
112 }
113
115 getName() override
116 {
117 return name_;
118 }
119
120 void
121 open(bool) override
122 {
124 }
125
126 bool
127 isOpen() override
128 {
129 return static_cast<bool>(db_);
130 }
131
132 void
133 close() override
134 {
135 db_ = nullptr;
136 }
137
138 //--------------------------------------------------------------------------
139
140 Status
141 fetch(void const* key, std::shared_ptr<NodeObject>* pObject) override
142 {
143 XRPL_ASSERT(
144 db_, "ripple::NodeStore::MemoryBackend::fetch : non-null database");
145 uint256 const hash(uint256::fromVoid(key));
146
148
149 Map::iterator iter = db_->table.find(hash);
150 if (iter == db_->table.end())
151 {
152 pObject->reset();
153 return notFound;
154 }
155 *pObject = iter->second;
156 return ok;
157 }
158
161 {
163 results.reserve(hashes.size());
164 for (auto const& h : hashes)
165 {
167 Status status = fetch(h->begin(), &nObj);
168 if (status != ok)
169 results.push_back({});
170 else
171 results.push_back(nObj);
172 }
173
174 return {results, ok};
175 }
176
177 void
178 store(std::shared_ptr<NodeObject> const& object) override
179 {
180 XRPL_ASSERT(
181 db_, "ripple::NodeStore::MemoryBackend::store : non-null database");
183 db_->table.emplace(object->getHash(), object);
184 }
185
186 void
187 storeBatch(Batch const& batch) override
188 {
189 for (auto const& e : batch)
190 store(e);
191 }
192
193 void
194 sync() override
195 {
196 }
197
198 void
200 {
201 XRPL_ASSERT(
202 db_,
203 "ripple::NodeStore::MemoryBackend::for_each : non-null database");
204 for (auto const& e : db_->table)
205 f(e.second);
206 }
207
208 int
209 getWriteLoad() override
210 {
211 return 0;
212 }
213
214 void
215 setDeletePath() override
216 {
217 }
218
219 int
220 fdRequired() const override
221 {
222 return 0;
223 }
224};
225
226//------------------------------------------------------------------------------
227
228MemoryFactory::MemoryFactory(Manager& manager) : manager_(manager)
229{
230 manager_.insert(*this);
231}
232
235{
236 return "Memory";
237}
238
241 size_t keyBytes,
242 Section const& keyValues,
244 Scheduler& scheduler,
245 beast::Journal journal)
246{
247 return std::make_unique<MemoryBackend>(keyBytes, keyValues, journal);
248}
249
250} // namespace NodeStore
251} // namespace ripple
A generic endpoint for log messages.
Definition Journal.h:60
A backend used for the NodeStore.
Definition Backend.h:40
Base class for backend factories.
Definition Factory.h:36
Singleton for managing NodeStore factories and back ends.
Definition Manager.h:32
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.
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 open(bool) override
Open the backend.
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:45
static base_uint fromVoid(void const *data)
Definition base_uint.h:319
T empty(T... args)
T is_same_v
T make_tuple(T... args)
MemoryFactory * memoryFactory
void registerMemoryFactory(Manager &manager)
Status
Return codes from Backend operations.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
T piecewise_construct
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