//------------------------------------------------------------------------------ /* Copyright (c) 2011-2013, OpenCoin, Inc. */ //============================================================================== class KeyvaDBBackendFactory::Backend : public NodeStore::Backend { private: typedef RecycledObjectPool MemoryPool; typedef RecycledObjectPool EncodedBlobPool; public: Backend (size_t keyBytes, StringPairArray const& keyValues, NodeStore::Scheduler& scheduler) : m_keyBytes (keyBytes) , m_scheduler (scheduler) , m_path (keyValues ["path"]) , m_db (KeyvaDB::New ( keyBytes, 3, File::getCurrentWorkingDirectory().getChildFile (m_path).withFileExtension ("key"), File::getCurrentWorkingDirectory().getChildFile (m_path).withFileExtension ("val"))) { } ~Backend () { } std::string getName () { return m_path.toStdString (); } //-------------------------------------------------------------------------- Status fetch (void const* key, NodeObject::Ptr* pObject) { pObject->reset (); Status status (ok); struct Callback : KeyvaDB::GetCallback { explicit Callback (MemoryBlock& block) : m_block (block) { } void* getStorageForValue (int valueBytes) { m_size = valueBytes; m_block.ensureSize (valueBytes); return m_block.getData (); } void const* getData () const noexcept { return m_block.getData (); } size_t getSize () const noexcept { return m_size; } private: MemoryBlock& m_block; size_t m_size; }; MemoryPool::ScopedItem item (m_memoryPool); MemoryBlock& block (item.getObject ()); Callback cb (block); // VFALCO TODO Can't we get KeyvaDB to provide a proper status? // bool const found = m_db->get (key, &cb); if (found) { NodeStore::DecodedBlob decoded (key, cb.getData (), cb.getSize ()); if (decoded.wasOk ()) { *pObject = decoded.createObject (); status = ok; } else { status = dataCorrupt; } } else { status = notFound; } return status; } void store (NodeObject::ref object) { EncodedBlobPool::ScopedItem item (m_blobPool); NodeStore::EncodedBlob& encoded (item.getObject ()); encoded.prepare (object); m_db->put (encoded.getKey (), encoded.getData (), encoded.getSize ()); } void storeBatch (NodeStore::Batch const& batch) { for (int i = 0; i < batch.size (); ++i) store (batch [i]); } void visitAll (VisitCallback& callback) { // VFALCO TODO Implement this! // bassertfalse; //m_db->visitAll (); } int getWriteLoad () { // we dont do pending writes return 0; } //-------------------------------------------------------------------------- private: size_t const m_keyBytes; NodeStore::Scheduler& m_scheduler; String m_path; ScopedPointer m_db; MemoryPool m_memoryPool; EncodedBlobPool m_blobPool; }; //------------------------------------------------------------------------------ KeyvaDBBackendFactory::KeyvaDBBackendFactory () { } KeyvaDBBackendFactory::~KeyvaDBBackendFactory () { } KeyvaDBBackendFactory& KeyvaDBBackendFactory::getInstance () { static KeyvaDBBackendFactory instance; return instance; } String KeyvaDBBackendFactory::getName () const { return "KeyvaDB"; } NodeStore::Backend* KeyvaDBBackendFactory::createInstance ( size_t keyBytes, StringPairArray const& keyValues, NodeStore::Scheduler& scheduler) { return new KeyvaDBBackendFactory::Backend (keyBytes, keyValues, scheduler); } //------------------------------------------------------------------------------