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>
25#include <xrpl/basics/contract.h>
26#include <xrpl/beast/utility/instrumentation.h>
27#include <boost/filesystem.hpp>
33#include <nudb/nudb.hpp>
69 Throw<std::runtime_error>(
70 "nodestore: Missing path in NuDB backend");
78 nudb::context& context,
89 Throw<std::runtime_error>(
90 "nodestore: Missing path in NuDB backend");
100 catch (nudb::system_error
const&)
114 open(
bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt)
117 using namespace boost::filesystem;
121 "ripple::NodeStore::NuDBBackend::open : database is already "
123 JLOG(
j_.
error()) <<
"database is already open";
126 auto const folder = path(
name_);
127 auto const dp = (folder /
"nudb.dat").
string();
128 auto const kp = (folder /
"nudb.key").
string();
129 auto const lp = (folder /
"nudb.log").
string();
133 create_directories(folder);
134 nudb::create<nudb::xxhasher>(
142 nudb::block_size(kp),
145 if (ec == nudb::errc::file_exists)
148 Throw<nudb::system_error>(ec);
150 db_.open(dp, kp, lp, ec);
152 Throw<nudb::system_error>(ec);
155 Throw<std::runtime_error>(
"nodestore: unknown appnum");
162 return db_.is_open();
166 open(
bool createIfMissing)
override
168 open(createIfMissing,
appnum, nudb::make_uid(), nudb::make_salt());
181 JLOG(
j_.
fatal()) <<
"NuBD close() failed: " << ec.message();
182 Throw<nudb::system_error>(ec);
187 boost::filesystem::remove_all(
name_, ec);
190 JLOG(
j_.
fatal()) <<
"Filesystem remove_all of " <<
name_
191 <<
" failed with: " << ec.message();
205 [key, pno, &status](
void const* data,
std::size_t size) {
206 nudb::detail::buffer bf;
208 DecodedBlob decoded(key, result.first, result.second);
209 if (!decoded.
wasOk())
218 if (ec == nudb::error::key_not_found)
221 Throw<nudb::system_error>(ec);
230 for (
auto const& h : hashes)
240 return {results,
ok};
248 nudb::detail::buffer bf;
250 db_.insert(e.
getKey(), result.first, result.second, ec);
251 if (ec && ec != nudb::error::key_exists)
252 Throw<nudb::system_error>(ec);
262 report.
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
273 for (
auto const& e : batch)
275 report.
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
288 auto const dp =
db_.dat_path();
289 auto const kp =
db_.key_path();
290 auto const lp =
db_.log_path();
295 Throw<nudb::system_error>(ec);
303 nudb::detail::buffer bf;
305 DecodedBlob decoded(key, result.first, result.second);
306 if (!decoded.
wasOk())
316 Throw<nudb::system_error>(ec);
317 db_.open(dp, kp, lp, ec);
319 Throw<nudb::system_error>(ec);
337 auto const dp =
db_.dat_path();
338 auto const kp =
db_.key_path();
339 auto const lp =
db_.log_path();
343 Throw<nudb::system_error>(ec);
344 nudb::verify_info vi;
345 nudb::verify<nudb::xxhasher>(vi, dp, kp, 0, nudb::no_progress{}, ec);
347 Throw<nudb::system_error>(ec);
348 db_.open(dp, kp, lp, ec);
350 Throw<nudb::system_error>(ec);
389 return std::make_unique<NuDBBackend>(
390 keyBytes, keyValues,
burstSize, scheduler, journal);
399 nudb::context& context,
402 return std::make_unique<NuDBBackend>(
403 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