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
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
35{
36 explicit MemoryDB() = default;
37
39 bool open = false;
41};
42
43class MemoryFactory : public Factory
44{
45private:
48
49public:
51 ~MemoryFactory() override;
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(
69 std::piecewise_construct, std::make_tuple(path), std::make_tuple());
70 MemoryDB& db = result.first->second;
71 if (db.open)
72 Throw<std::runtime_error>("already open");
73 return db;
74 }
75};
76
78
79//------------------------------------------------------------------------------
80
81class MemoryBackend : public Backend
82{
83private:
85
88 MemoryDB* db_{nullptr};
89
90public:
92 size_t keyBytes,
93 Section const& keyValues,
94 beast::Journal journal)
95 : name_(get(keyValues, "path")), journal_(journal)
96 {
97 boost::ignore_unused(journal_); // Keep unused journal_ just in case.
98 if (name_.empty())
99 Throw<std::runtime_error>("Missing path in Memory backend");
100 }
101
102 ~MemoryBackend() override
103 {
104 close();
105 }
106
108 getName() override
109 {
110 return name_;
111 }
112
113 void
114 open(bool createIfMissing) override
115 {
117 }
118
119 bool
120 isOpen() override
121 {
122 return static_cast<bool>(db_);
123 }
124
125 void
126 close() override
127 {
128 db_ = nullptr;
129 }
130
131 //--------------------------------------------------------------------------
132
133 Status
134 fetch(void const* key, std::shared_ptr<NodeObject>* pObject) override
135 {
136 XRPL_ASSERT(
137 db_, "ripple::NodeStore::MemoryBackend::fetch : non-null database");
138 uint256 const hash(uint256::fromVoid(key));
139
141
142 Map::iterator iter = db_->table.find(hash);
143 if (iter == db_->table.end())
144 {
145 pObject->reset();
146 return notFound;
147 }
148 *pObject = iter->second;
149 return ok;
150 }
151
154 {
156 results.reserve(hashes.size());
157 for (auto const& h : hashes)
158 {
160 Status status = fetch(h->begin(), &nObj);
161 if (status != ok)
162 results.push_back({});
163 else
164 results.push_back(nObj);
165 }
166
167 return {results, ok};
168 }
169
170 void
171 store(std::shared_ptr<NodeObject> const& object) override
172 {
173 XRPL_ASSERT(
174 db_, "ripple::NodeStore::MemoryBackend::store : non-null database");
176 db_->table.emplace(object->getHash(), object);
177 }
178
179 void
180 storeBatch(Batch const& batch) override
181 {
182 for (auto const& e : batch)
183 store(e);
184 }
185
186 void
187 sync() override
188 {
189 }
190
191 void
193 {
194 XRPL_ASSERT(
195 db_,
196 "ripple::NodeStore::MemoryBackend::for_each : non-null database");
197 for (auto const& e : db_->table)
198 f(e.second);
199 }
200
201 int
202 getWriteLoad() override
203 {
204 return 0;
205 }
206
207 void
208 setDeletePath() override
209 {
210 }
211
212 int
213 fdRequired() const override
214 {
215 return 0;
216 }
217};
218
219//------------------------------------------------------------------------------
220
222{
223 Manager::instance().insert(*this);
224}
225
227{
228 Manager::instance().erase(*this);
229}
230
233{
234 return "Memory";
235}
236
239 size_t keyBytes,
240 Section const& keyValues,
242 Scheduler& scheduler,
243 beast::Journal journal)
244{
245 return std::make_unique<MemoryBackend>(keyBytes, keyValues, journal);
246}
247
248} // namespace NodeStore
249} // 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
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:45
static base_uint fromVoid(void const *data)
Definition: base_uint.h:319
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:355
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