mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Move NodeStore and backends to ripple_core
This commit is contained in:
279
modules/ripple_core/node/MdbBackendFactory.cpp
Normal file
279
modules/ripple_core/node/MdbBackendFactory.cpp
Normal file
@@ -0,0 +1,279 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011-2013, OpenCoin, Inc.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if RIPPLE_MDB_AVAILABLE
|
||||
|
||||
class MdbBackendFactory::Backend
|
||||
: public NodeStore::Backend
|
||||
, public NodeStore::BatchWriter::Callback
|
||||
, LeakChecked <MdbBackendFactory::Backend>
|
||||
{
|
||||
public:
|
||||
typedef NodeStore::Batch Batch;
|
||||
typedef NodeStore::EncodedBlob EncodedBlob;
|
||||
typedef NodeStore::DecodedBlob DecodedBlob;
|
||||
|
||||
explicit Backend (size_t keyBytes,
|
||||
StringPairArray const& keyValues,
|
||||
NodeStore::Scheduler& scheduler)
|
||||
: m_keyBytes (keyBytes)
|
||||
, m_scheduler (scheduler)
|
||||
, m_batch (*this, scheduler)
|
||||
, m_env (nullptr)
|
||||
{
|
||||
String path (keyValues ["path"]);
|
||||
|
||||
if (path.isEmpty ())
|
||||
Throw (std::runtime_error ("Missing path in MDB backend"));
|
||||
|
||||
m_basePath = path.toStdString();
|
||||
|
||||
// Regarding the path supplied to mdb_env_open:
|
||||
// This directory must already exist and be writable.
|
||||
//
|
||||
File dir (File::getCurrentWorkingDirectory().getChildFile (path));
|
||||
Result result = dir.createDirectory ();
|
||||
|
||||
if (result.wasOk ())
|
||||
{
|
||||
int error = mdb_env_create (&m_env);
|
||||
|
||||
// Should use the size of the file plus the free space on the disk
|
||||
if (error == 0)
|
||||
error = mdb_env_set_mapsize (m_env, 512L * 1024L * 1024L * 1024L);
|
||||
|
||||
if (error == 0)
|
||||
error = mdb_env_open (
|
||||
m_env,
|
||||
m_basePath.c_str (),
|
||||
MDB_NOTLS,
|
||||
0664);
|
||||
|
||||
MDB_txn* txn;
|
||||
|
||||
if (error == 0)
|
||||
error = mdb_txn_begin (m_env, NULL, 0, &txn);
|
||||
|
||||
if (error == 0)
|
||||
error = mdb_dbi_open (txn, NULL, 0, &m_dbi);
|
||||
|
||||
if (error == 0)
|
||||
error = mdb_txn_commit (txn);
|
||||
|
||||
if (error != 0)
|
||||
{
|
||||
String s;
|
||||
s << "Error #" << error << " creating mdb environment";
|
||||
Throw (std::runtime_error (s.toStdString ()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
String s;
|
||||
s << "MDB Backend failed to create directory, " << result.getErrorMessage ();
|
||||
Throw (std::runtime_error (s.toStdString().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
~Backend ()
|
||||
{
|
||||
if (m_env != nullptr)
|
||||
{
|
||||
mdb_dbi_close (m_env, m_dbi);
|
||||
mdb_env_close (m_env);
|
||||
}
|
||||
}
|
||||
|
||||
std::string getName()
|
||||
{
|
||||
return m_basePath;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
unsigned char* mdb_cast (T* p)
|
||||
{
|
||||
return const_cast <unsigned char*> (static_cast <unsigned char const*> (p));
|
||||
}
|
||||
|
||||
Status fetch (void const* key, NodeObject::Ptr* pObject)
|
||||
{
|
||||
pObject->reset ();
|
||||
|
||||
Status status (ok);
|
||||
|
||||
MDB_txn* txn = nullptr;
|
||||
|
||||
int error = 0;
|
||||
|
||||
error = mdb_txn_begin (m_env, NULL, MDB_RDONLY, &txn);
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
MDB_val dbkey;
|
||||
MDB_val data;
|
||||
|
||||
dbkey.mv_size = m_keyBytes;
|
||||
dbkey.mv_data = mdb_cast (key);
|
||||
|
||||
error = mdb_get (txn, m_dbi, &dbkey, &data);
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
DecodedBlob decoded (key, data.mv_data, data.mv_size);
|
||||
|
||||
if (decoded.wasOk ())
|
||||
{
|
||||
*pObject = decoded.createObject ();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = dataCorrupt;
|
||||
}
|
||||
}
|
||||
else if (error == MDB_NOTFOUND)
|
||||
{
|
||||
status = notFound;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = unknown;
|
||||
|
||||
WriteLog (lsWARNING, NodeObject) << "MDB txn failed, code=" << error;
|
||||
}
|
||||
|
||||
mdb_txn_abort (txn);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = unknown;
|
||||
|
||||
WriteLog (lsWARNING, NodeObject) << "MDB txn failed, code=" << error;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void store (NodeObject::ref object)
|
||||
{
|
||||
m_batch.store (object);
|
||||
}
|
||||
|
||||
void storeBatch (Batch const& batch)
|
||||
{
|
||||
MDB_txn* txn = nullptr;
|
||||
|
||||
int error = 0;
|
||||
|
||||
error = mdb_txn_begin (m_env, NULL, 0, &txn);
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
EncodedBlob::Pool::ScopedItem item (m_blobPool);
|
||||
|
||||
BOOST_FOREACH (NodeObject::Ptr const& object, batch)
|
||||
{
|
||||
EncodedBlob& encoded (item.getObject ());
|
||||
|
||||
encoded.prepare (object);
|
||||
|
||||
MDB_val key;
|
||||
key.mv_size = m_keyBytes;
|
||||
key.mv_data = mdb_cast (encoded.getKey ());
|
||||
|
||||
MDB_val data;
|
||||
data.mv_size = encoded.getSize ();
|
||||
data.mv_data = mdb_cast (encoded.getData ());
|
||||
|
||||
error = mdb_put (txn, m_dbi, &key, &data, 0);
|
||||
|
||||
if (error != 0)
|
||||
{
|
||||
WriteLog (lsWARNING, NodeObject) << "mdb_put failed, error=" << error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
error = mdb_txn_commit(txn);
|
||||
|
||||
if (error != 0)
|
||||
{
|
||||
WriteLog (lsWARNING, NodeObject) << "mdb_txn_commit failed, error=" << error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mdb_txn_abort (txn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLog (lsWARNING, NodeObject) << "mdb_txn_begin failed, error=" << error;
|
||||
}
|
||||
}
|
||||
|
||||
void visitAll (VisitCallback& callback)
|
||||
{
|
||||
// VFALCO TODO Implement this!
|
||||
bassertfalse;
|
||||
}
|
||||
|
||||
int getWriteLoad ()
|
||||
{
|
||||
return m_batch.getWriteLoad ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void writeBatch (Batch const& batch)
|
||||
{
|
||||
storeBatch (batch);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t const m_keyBytes;
|
||||
NodeStore::Scheduler& m_scheduler;
|
||||
NodeStore::BatchWriter m_batch;
|
||||
NodeStore::EncodedBlob::Pool m_blobPool;
|
||||
std::string m_basePath;
|
||||
MDB_env* m_env;
|
||||
MDB_dbi m_dbi;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
MdbBackendFactory::MdbBackendFactory ()
|
||||
{
|
||||
}
|
||||
|
||||
MdbBackendFactory::~MdbBackendFactory ()
|
||||
{
|
||||
}
|
||||
|
||||
MdbBackendFactory& MdbBackendFactory::getInstance ()
|
||||
{
|
||||
static MdbBackendFactory instance;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
String MdbBackendFactory::getName () const
|
||||
{
|
||||
return "mdb";
|
||||
}
|
||||
|
||||
NodeStore::Backend* MdbBackendFactory::createInstance (
|
||||
size_t keyBytes,
|
||||
StringPairArray const& keyValues,
|
||||
NodeStore::Scheduler& scheduler)
|
||||
{
|
||||
return new MdbBackendFactory::Backend (keyBytes, keyValues, scheduler);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user