//------------------------------------------------------------------------------ /* Copyright (c) 2011-2013, OpenCoin, Inc. */ //============================================================================== class KeyvaDBBackendFactory::Backend : public NodeStore::Backend { public: typedef UnsignedInteger <32> Key; enum { keyBytes = Key::sizeInBytes }; explicit Backend (StringPairArray const& keyValues) : m_path (keyValues ["path"]) , m_db (KeyvaDB::New ( keyBytes, File::getCurrentWorkingDirectory().getChildFile (m_path).withFileExtension ("key"), File::getCurrentWorkingDirectory().getChildFile (m_path).withFileExtension ("val"), false)) { } ~Backend () { } std::string getDataBaseName () { return m_path.toStdString (); } void writeObject (NodeObject const& object) { m_db->put ( object.getHash ().begin (), &object.getData () [0], object.getData ().size ()); } bool bulkStore (std::vector const& objs) { for (size_t i = 0; i < objs.size (); ++i) { writeObject (*objs [i]); } return true; } struct MyGetCallback : KeyvaDB::GetCallback { int valueBytes; HeapBlock data; void* createStorageForValue (int valueBytes_) { valueBytes = valueBytes_; data.malloc (valueBytes); return data.getData (); } }; NodeObject::pointer retrieve (uint256 const& hash) { NodeObject::pointer result; MyGetCallback cb; bool const found = m_db->get (hash.begin (), &cb); if (found) { result = fromBinary (hash, cb.data.getData (), cb.valueBytes); } return result; } void visitAll (FUNCTION_TYPE func) { bassertfalse; } Blob toBlob (NodeObject::ref obj) { 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) { if (size < 9) throw std::runtime_error ("undersized object"); uint32 index = htonl (*reinterpret_cast (data)); int htype = data[8]; return boost::make_shared (static_cast (htype), index, data + 9, size - 9, hash); } private: String m_path; ScopedPointer m_db; }; //------------------------------------------------------------------------------ KeyvaDBBackendFactory::KeyvaDBBackendFactory () { } KeyvaDBBackendFactory::~KeyvaDBBackendFactory () { } KeyvaDBBackendFactory& KeyvaDBBackendFactory::getInstance () { static KeyvaDBBackendFactory instance; return instance; } String KeyvaDBBackendFactory::getName () const { return "KeyvaDB"; } NodeStore::Backend* KeyvaDBBackendFactory::createInstance (StringPairArray const& keyValues) { return new KeyvaDBBackendFactory::Backend (keyValues); } //------------------------------------------------------------------------------