From ab6b0e00e62aaf88e238e2f4a4da2db2f4339a4b Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Thu, 11 Jul 2013 09:56:36 -0700 Subject: [PATCH] Add MDB NodeStore::BackendFactory --- Builds/QtCreator/rippled.pro | 1 + SConstruct | 1 + .../node/ripple_MdbBackendFactory.cpp | 133 ++++++++++++++++++ .../node/ripple_MdbBackendFactory.h | 29 ++++ modules/ripple_app/ripple_app.cpp | 4 +- modules/ripple_mdb/ripple_mdb.c | 20 +-- modules/ripple_mdb/ripple_mdb.h | 10 ++ src/cpp/ripple/ripple_Main.cpp | 8 +- 8 files changed, 183 insertions(+), 23 deletions(-) create mode 100644 modules/ripple_app/node/ripple_MdbBackendFactory.cpp create mode 100644 modules/ripple_app/node/ripple_MdbBackendFactory.h diff --git a/Builds/QtCreator/rippled.pro b/Builds/QtCreator/rippled.pro index 9dac36d3c3..5d46a2102f 100644 --- a/Builds/QtCreator/rippled.pro +++ b/Builds/QtCreator/rippled.pro @@ -77,6 +77,7 @@ SOURCES += \ ../../modules/ripple_data/ripple_data.cpp \ ../../modules/ripple_json/ripple_json.cpp \ ../../modules/ripple_leveldb/ripple_leveldb.cpp \ + ../../modules/ripple_mdb/ripple_mdb.c \ ../../modules/ripple_net/ripple_net.cpp \ ../../modules/ripple_sqlite/ripple_sqlite.c \ ../../modules/ripple_websocket/ripple_websocket.cpp diff --git a/SConstruct b/SConstruct index 149ad38378..dfe3c783f0 100644 --- a/SConstruct +++ b/SConstruct @@ -135,6 +135,7 @@ COMPILED_FILES = [ 'modules/ripple_data/ripple_data.cpp', 'modules/ripple_json/ripple_json.cpp', 'modules/ripple_leveldb/ripple_leveldb.cpp', + 'modules/ripple_mdb/ripple_mdb.c', 'modules/ripple_net/ripple_net.cpp', 'modules/ripple_websocket/ripple_websocket.cpp', 'modules/ripple_sqlite/ripple_sqlite.c' diff --git a/modules/ripple_app/node/ripple_MdbBackendFactory.cpp b/modules/ripple_app/node/ripple_MdbBackendFactory.cpp new file mode 100644 index 0000000000..7c7ff578db --- /dev/null +++ b/modules/ripple_app/node/ripple_MdbBackendFactory.cpp @@ -0,0 +1,133 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +class MdbBackendFactory::Backend : public NodeStore::Backend +{ +public: + explicit Backend (StringPairArray const& keyValues) + : m_env (nullptr) + { + if (keyValues ["path"].isEmpty ()) + throw std::runtime_error ("Missing path in MDB backend"); + + int error = 0; + + error = mdb_env_create (&m_env); + + if (error == 0) + { + error = mdb_env_open ( + m_env, + keyValues ["path"].toStdString().c_str (), + 0, + 0); + + } + + if (error != 0) + { + String s; + s << "Error #" << error << " creating mdb environment"; + throw std::runtime_error (s.toStdString ()); + } + } + + ~Backend () + { + if (m_env != nullptr) + mdb_env_close (m_env); + } + + std::string getDataBaseName() + { + return std::string (); + } + + bool store (NodeObject::ref obj) + { + return false; + } + + bool bulkStore (std::vector const& objs) + { + return false; + } + + NodeObject::pointer retrieve (uint256 const& hash) + { + return NodeObject::pointer (); + } + + void visitAll (FUNCTION_TYPE func) + { + } + + Blob toBlob (NodeObject::ref obj) const + { + Blob rawData (9 + obj->getData ().size ()); + unsigned char* bufPtr = &rawData.front(); + + *reinterpret_cast (bufPtr + 0) = ntohl (obj->getIndex ()); + + *reinterpret_cast (bufPtr + 4) = ntohl (obj->getIndex ()); + + *(bufPtr + 8) = static_cast (obj->getType ()); + + memcpy (bufPtr + 9, &obj->getData ().front (), obj->getData ().size ()); + + return rawData; + } + + NodeObject::pointer fromBinary (uint256 const& hash, char const* data, int size) const + { + if (size < 9) + throw std::runtime_error ("undersized object"); + + uint32 const index = htonl (*reinterpret_cast (data)); + + int const htype = data [8]; + + return boost::make_shared ( + static_cast (htype), + index, + data + 9, + size - 9, + hash); + } + +private: + MDB_env* m_env; +}; + +//------------------------------------------------------------------------------ + +MdbBackendFactory::MdbBackendFactory () +{ +} + +MdbBackendFactory::~MdbBackendFactory () +{ +} + +MdbBackendFactory& MdbBackendFactory::getInstance () +{ + static MdbBackendFactory instance; + + return instance; +} + +String MdbBackendFactory::getName () const +{ + return "mdb"; +} + +NodeStore::Backend* MdbBackendFactory::createInstance (StringPairArray const& keyValues) +{ + return new MdbBackendFactory::Backend (keyValues); +} + +//------------------------------------------------------------------------------ + diff --git a/modules/ripple_app/node/ripple_MdbBackendFactory.h b/modules/ripple_app/node/ripple_MdbBackendFactory.h new file mode 100644 index 0000000000..8b2a5b8eb4 --- /dev/null +++ b/modules/ripple_app/node/ripple_MdbBackendFactory.h @@ -0,0 +1,29 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_MDBBACKENDFACTORY_H_INCLUDED +#define RIPPLE_MDBBACKENDFACTORY_H_INCLUDED + +/** Factory to produce a backend using MDB. + + @note MDB is not currently available for Win32 +*/ +class MdbBackendFactory : public NodeStore::BackendFactory +{ +private: + class Backend; + + MdbBackendFactory (); + ~MdbBackendFactory (); + +public: + static MdbBackendFactory& getInstance (); + + String getName () const; + NodeStore::Backend* createInstance (StringPairArray const& keyValues); +}; + +#endif diff --git a/modules/ripple_app/ripple_app.cpp b/modules/ripple_app/ripple_app.cpp index 130e11334d..7ee1c95b7e 100644 --- a/modules/ripple_app/ripple_app.cpp +++ b/modules/ripple_app/ripple_app.cpp @@ -74,7 +74,7 @@ #include "ripple_app.h" #include "../ripple_data/ripple_data.h" - +#include "../ripple_mdb/ripple_mdb.h" #include "../ripple_net/ripple_net.h" #include "../modules/ripple_websocket/ripple_websocket.h" @@ -97,6 +97,7 @@ namespace ripple #include "node/ripple_NodeObject.h" #include "node/ripple_NodeStore.h" #include "node/ripple_LevelDBBackendFactory.h" +#include "node/ripple_MdbBackendFactory.h" #include "node/ripple_NullBackendFactory.h" #include "node/ripple_SqliteBackendFactory.h" @@ -238,6 +239,7 @@ static const uint64 tenTo17m1 = tenTo17 - 1; #include "node/ripple_NodeObject.cpp" #include "node/ripple_NodeStore.cpp" #include "node/ripple_LevelDBBackendFactory.cpp" +#include "node/ripple_MdbBackendFactory.cpp" #include "node/ripple_NullBackendFactory.cpp" #include "node/ripple_SqliteBackendFactory.cpp" diff --git a/modules/ripple_mdb/ripple_mdb.c b/modules/ripple_mdb/ripple_mdb.c index bb842cca6a..1a31ef3052 100644 --- a/modules/ripple_mdb/ripple_mdb.c +++ b/modules/ripple_mdb/ripple_mdb.c @@ -12,27 +12,9 @@ #include "beast/modules/beast_core/system/beast_TargetPlatform.h" -#define __LITTLE_ENDIAN 1 -#define __BIG_ENDIAN 2 -typedef unsigned short uint16_t; - -#if BEAST_LITTLE_ENDIAN -# define BYTE_ORDER __LITTLE_ENDIAN -#elif BEAST_BIG_ENDIAN -# define BYTE_ORDER __BIG_ENDIAN -#else -# error "Unknown endianness" -#endif - -#if BEAST_MSVC -#pragma warning (push) -//#pragma warning (disable: 4092) -#endif +#if RIPPLE_MDB_AVAILABLE #include "mdb/libraries/liblmdb/mdb.c" #include "mdb/libraries/liblmdb/midl.c" -#include "mdb/libraries/liblmdb/mdb.c" -#if BEAST_MSVC -#pragma warning (pop) #endif diff --git a/modules/ripple_mdb/ripple_mdb.h b/modules/ripple_mdb/ripple_mdb.h index 6961f82eb6..44c3aafd2a 100644 --- a/modules/ripple_mdb/ripple_mdb.h +++ b/modules/ripple_mdb/ripple_mdb.h @@ -7,5 +7,15 @@ #ifndef RIPPLE_MDB_H_INCLUDED #define RIPPLE_MDB_H_INCLUDED +#if ! BEAST_WIN32 +#define RIPPLE_MDB_AVAILABLE 1 + +#include "mdb/libraries/liblmdb/lmdb.h" + +#else +// mdb is unsupported on Win32 +#define RIPPLE_MDB_AVAILBLE 0 + +#endif #endif diff --git a/src/cpp/ripple/ripple_Main.cpp b/src/cpp/ripple/ripple_Main.cpp index 18455387fd..b8700bb3cc 100644 --- a/src/cpp/ripple/ripple_Main.cpp +++ b/src/cpp/ripple/ripple_Main.cpp @@ -122,8 +122,8 @@ int rippleMain (int argc, char** argv) // Checks the heap at every allocation and deallocation (slow). // //Debug::setAlwaysCheckHeap (false); - - // Keeps freed memory blocks and fills them with a guard value. + + // Keeps freed memory blocks and fills them with a guard value. // //Debug::setHeapDelayedFree (false); @@ -184,7 +184,9 @@ int rippleMain (int argc, char** argv) // These must be added before the Application object is created NodeStore::addBackendFactory (SqliteBackendFactory::getInstance ()); NodeStore::addBackendFactory (LevelDBBackendFactory::getInstance ()); - +#if RIPPLE_MDB_AVAILABLE + NodeStore::addBackendFactory (MdbBackendFactory::getInstance ()); +#endif if (! RandomNumbers::getInstance ().initialize ()) {