20#include <xrpld/nodestore/Factory.h>
21#include <xrpld/nodestore/Manager.h>
22#include <xrpld/nodestore/detail/DecodedBlob.h>
23#include <xrpld/nodestore/detail/EncodedBlob.h>
24#include <xrpld/nodestore/detail/codec.h>
26#include <xrpl/basics/contract.h>
27#include <xrpl/beast/utility/instrumentation.h>
29#include <boost/filesystem.hpp>
31#include <nudb/nudb.hpp>
73 Throw<std::runtime_error>(
74 "nodestore: Missing path in NuDB backend");
82 nudb::context& context,
93 Throw<std::runtime_error>(
94 "nodestore: Missing path in NuDB backend");
104 catch (nudb::system_error
const&)
118 open(
bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt)
121 using namespace boost::filesystem;
125 "ripple::NodeStore::NuDBBackend::open : database is already "
127 JLOG(
j_.
error()) <<
"database is already open";
131 auto const dp = (folder /
"nudb.dat").
string();
132 auto const kp = (folder /
"nudb.key").
string();
133 auto const lp = (folder /
"nudb.log").
string();
137 create_directories(folder);
138 nudb::create<nudb::xxhasher>(
146 nudb::block_size(kp),
149 if (ec == nudb::errc::file_exists)
152 Throw<nudb::system_error>(ec);
154 db_.open(dp, kp, lp, ec);
156 Throw<nudb::system_error>(ec);
159 Throw<std::runtime_error>(
"nodestore: unknown appnum");
166 return db_.is_open();
170 open(
bool createIfMissing)
override
172 open(createIfMissing,
appnum, nudb::make_uid(), nudb::make_salt());
185 JLOG(
j_.
fatal()) <<
"NuBD close() failed: " << ec.message();
186 Throw<nudb::system_error>(ec);
191 boost::filesystem::remove_all(
name_, ec);
194 JLOG(
j_.
fatal()) <<
"Filesystem remove_all of " <<
name_
195 <<
" failed with: " << ec.message();
209 [key, pno, &status](
void const* data,
std::size_t size) {
210 nudb::detail::buffer bf;
212 DecodedBlob decoded(key, result.first, result.second);
213 if (!decoded.
wasOk())
222 if (ec == nudb::error::key_not_found)
225 Throw<nudb::system_error>(ec);
234 for (
auto const& h : hashes)
244 return {results,
ok};
252 nudb::detail::buffer bf;
254 db_.insert(e.
getKey(), result.first, result.second, ec);
255 if (ec && ec != nudb::error::key_exists)
256 Throw<nudb::system_error>(ec);
266 report.
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
277 for (
auto const& e :
batch)
279 report.
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
292 auto const dp =
db_.dat_path();
293 auto const kp =
db_.key_path();
294 auto const lp =
db_.log_path();
299 Throw<nudb::system_error>(ec);
307 nudb::detail::buffer bf;
309 DecodedBlob decoded(key, result.first, result.second);
310 if (!decoded.
wasOk())
320 Throw<nudb::system_error>(ec);
321 db_.open(dp, kp, lp, ec);
323 Throw<nudb::system_error>(ec);
341 auto const dp =
db_.dat_path();
342 auto const kp =
db_.key_path();
343 auto const lp =
db_.log_path();
347 Throw<nudb::system_error>(ec);
348 nudb::verify_info vi;
349 nudb::verify<nudb::xxhasher>(vi, dp, kp, 0, nudb::no_progress{}, ec);
351 Throw<nudb::system_error>(ec);
352 db_.open(dp, kp, lp, ec);
354 Throw<nudb::system_error>(ec);
393 return std::make_unique<NuDBBackend>(
394 keyBytes, keyValues,
burstSize, scheduler, journal);
403 nudb::context& context,
406 return std::make_unique<NuDBBackend>(
407 keyBytes, keyValues,
burstSize, scheduler, context, journal);
A generic endpoint for log messages.
A backend used for the NodeStore.
Parsed key/value blob into NodeObject components.
std::shared_ptr< NodeObject > createObject()
Create a NodeObject from this data.
bool wasOk() const noexcept
Determine if the decoding was successful.
Convert a NodeObject from in-memory to database format.
void const * getKey() const noexcept
std::size_t getSize() const noexcept
void const * getData() const noexcept
Base class for backend factories.
static Manager & instance()
Returns the instance of the manager singleton.
virtual void erase(Factory &factory)=0
Remove a factory.
virtual void insert(Factory &factory)=0
Add a factory.
void store(std::shared_ptr< NodeObject > const &no) override
Store a single object.
NuDBBackend(size_t keyBytes, Section const &keyValues, std::size_t burstSize, Scheduler &scheduler, beast::Journal journal)
Status fetch(void const *key, std::shared_ptr< NodeObject > *pno) override
Fetch a single object.
void open(bool createIfMissing) override
Open the backend.
std::size_t const burstSize_
std::pair< std::vector< std::shared_ptr< NodeObject > >, Status > fetchBatch(std::vector< uint256 const * > const &hashes) override
Fetch a batch synchronously.
static constexpr std::uint64_t appnum
void close() override
Close the backend.
NuDBBackend(size_t keyBytes, Section const &keyValues, std::size_t burstSize, Scheduler &scheduler, nudb::context &context, beast::Journal journal)
void storeBatch(Batch const &batch) override
Store a group of objects.
void do_insert(std::shared_ptr< NodeObject > const &no)
int fdRequired() const override
Returns the number of file descriptors the backend expects to need.
std::string getName() override
Get the human-readable name of this backend.
void open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt) override
Open the backend.
void verify() override
Perform consistency checks on database.
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
std::atomic< bool > deletePath_
bool isOpen() override
Returns true is the database is open.
int getWriteLoad() override
Estimate the number of write operations pending.
void setDeletePath() override
Remove contents on disk upon destruction.
std::unique_ptr< Backend > createInstance(size_t keyBytes, Section const &keyValues, std::size_t burstSize, Scheduler &scheduler, nudb::context &context, beast::Journal journal) override
Create an instance of this factory's backend.
std::string getName() const override
Retrieve the name of this factory.
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.
Scheduling for asynchronous backend activity.
virtual void onBatchWrite(BatchWriteReport const &report)=0
Reports the completion of a batch write Allows the scheduler to monitor the node store's performance.
Holds a collection of configuration values.
static NuDBFactory nuDBFactory
std::pair< void const *, std::size_t > nodeobject_decompress(void const *in, std::size_t in_size, BufferFactory &&bf)
std::pair< void const *, std::size_t > nodeobject_compress(void const *in, std::size_t in_size, BufferFactory &&bf)
Status
Return codes from Backend operations.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::error_code make_error_code(ripple::TokenCodecErrc e)
@ open
We haven't closed our ledger yet, but others might have.
T get(Section const §ion, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
Contains information about a batch write operation.
std::chrono::milliseconds elapsed