20 #include <ripple/basics/contract.h>
21 #include <ripple/nodestore/Factory.h>
22 #include <ripple/nodestore/Manager.h>
23 #include <ripple/nodestore/impl/BatchWriter.h>
24 #include <ripple/nodestore/impl/DecodedBlob.h>
25 #include <ripple/nodestore/impl/EncodedBlob.h>
26 #include <ripple/nodestore/impl/codec.h>
27 #include <boost/filesystem.hpp>
34 #include <nudb/nudb.hpp>
72 Throw<std::runtime_error>(
73 "nodestore: Missing path in NuDB backend");
81 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 JLOG(
j_.
error()) <<
"database is already open";
128 auto const folder = path(
name_);
129 auto const dp = (folder /
"nudb.dat").
string();
130 auto const kp = (folder /
"nudb.key").
string();
131 auto const lp = (folder /
"nudb.log").
string();
135 create_directories(folder);
136 nudb::create<nudb::xxhasher>(
144 nudb::block_size(kp),
147 if (ec == nudb::errc::file_exists)
150 Throw<nudb::system_error>(ec);
152 db_.open(dp, kp, lp, ec);
154 Throw<nudb::system_error>(ec);
166 Throw<std::runtime_error>(
"nodestore: unknown appnum");
173 return db_.is_open();
177 open(
bool createIfMissing)
override
179 open(createIfMissing,
currentType, nudb::make_uid(), nudb::make_salt());
192 JLOG(
j_.
fatal()) <<
"NuBD close() failed: " << ec.message();
193 Throw<nudb::system_error>(ec);
198 boost::filesystem::remove_all(
name_, ec);
201 JLOG(
j_.
fatal()) <<
"Filesystem remove_all of " <<
name_
202 <<
" failed with: " << ec.message();
216 [key, pno, &status](
void const* data,
std::size_t size) {
217 nudb::detail::buffer bf;
219 DecodedBlob decoded(key, result.first, result.second);
220 if (!decoded.
wasOk())
229 if (ec == nudb::error::key_not_found)
232 Throw<nudb::system_error>(ec);
241 for (
auto const& h : hashes)
251 return {results,
ok};
259 nudb::detail::buffer bf;
261 db_.insert(e.
getKey(), result.first, result.second, ec);
262 if (ec && ec != nudb::error::key_exists)
263 Throw<nudb::system_error>(ec);
278 for (
auto const& e : batch)
280 report.
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
293 auto const dp =
db_.dat_path();
294 auto const kp =
db_.key_path();
295 auto const lp =
db_.log_path();
300 Throw<nudb::system_error>(ec);
308 nudb::detail::buffer bf;
310 DecodedBlob decoded(key, result.first, result.second);
311 if (!decoded.
wasOk())
313 ec = make_error_code(nudb::error::missing_value);
321 Throw<nudb::system_error>(ec);
322 db_.open(dp, kp, lp, ec);
324 Throw<nudb::system_error>(ec);
342 auto const dp =
db_.dat_path();
343 auto const kp =
db_.key_path();
344 auto const lp =
db_.log_path();
348 Throw<nudb::system_error>(ec);
349 nudb::verify_info vi;
350 nudb::verify<nudb::xxhasher>(vi, dp, kp, 0, nudb::no_progress{}, ec);
352 Throw<nudb::system_error>(ec);
353 db_.open(dp, kp, lp, ec);
355 Throw<nudb::system_error>(ec);
400 return std::make_unique<NuDBBackend>(
401 keyBytes, keyValues,
burstSize, scheduler, journal);
410 nudb::context& context,
413 return std::make_unique<NuDBBackend>(
414 keyBytes, keyValues,
burstSize, scheduler, context, journal);
Holds a collection of configuration values.
bool wasOk() const noexcept
Determine if the decoding was successful.
std::pair< void const *, std::size_t > nodeobject_decompress(void const *in, std::size_t in_size, BufferFactory &&bf)
Base class for backend factories.
std::atomic< bool > deletePath_
void store(std::shared_ptr< NodeObject > const &no) override
Store a single object.
void open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt) override
Open the backend.
Batch-writing assist logic.
void setDeletePath() override
Remove contents on disk upon destruction.
Parsed key/value blob into NodeObject components.
virtual void erase(Factory &factory)=0
Remove a factory.
void do_insert(std::shared_ptr< NodeObject > const &no)
bool isOpen() override
Returns true is the database is open.
std::pair< std::vector< std::shared_ptr< NodeObject > >, Status > fetchBatch(std::vector< uint256 const * > const &hashes) override
Fetch a batch synchronously.
void close() override
Close the backend.
void writeBatch(Batch const &batch) override
int fdRequired() const override
Returns the number of file descriptors the backend expects to need.
static NuDBFactory nuDBFactory
static constexpr std::uint64_t currentType
virtual void insert(Factory &factory)=0
Add a factory.
std::shared_ptr< NodeObject > createObject()
Create a NodeObject from this data.
void const * getData() const noexcept
int getWriteLoad() override
Estimate the number of write operations pending.
This callback does the actual writing.
static constexpr std::uint64_t deterministicType
A generic endpoint for log messages.
NuDBBackend(size_t keyBytes, Section const &keyValues, std::size_t burstSize, Scheduler &scheduler, beast::Journal journal)
Scheduling for asynchronous backend activity.
void open(bool createIfMissing) override
Open the backend.
Contains information about a batch write operation.
void verify() override
Perform consistency checks on database.
std::string getName() override
Get the human-readable name of this backend.
Status
Return codes from Backend operations.
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.
static constexpr std::uint64_t deterministicMask
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string getName() const override
Retrieve the name of this factory.
int getWriteLoad()
Get an estimate of the amount of writing I/O pending.
std::size_t getSize() const noexcept
Convert a NodeObject from in-memory to database format.
const std::size_t burstSize_
void store(std::shared_ptr< NodeObject > const &object)
Store the object.
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.
void storeBatch(Batch const &batch) override
Store a group of objects.
std::pair< void const *, std::size_t > nodeobject_compress(void const *in, std::size_t in_size, BufferFactory &&bf)
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
static Manager & instance()
Returns the instance of the manager singleton.
std::chrono::milliseconds elapsed
NuDBBackend(size_t keyBytes, Section const &keyValues, std::size_t burstSize, Scheduler &scheduler, nudb::context &context, beast::Journal journal)
void const * getKey() const noexcept
virtual void onBatchWrite(BatchWriteReport const &report)=0
Reports the completion of a batch write Allows the scheduler to monitor the node store's performance.
Status fetch(void const *key, std::shared_ptr< NodeObject > *pno) override
Fetch a single object.
T & get(EitherAmount &amt)
A backend used for the NodeStore.