2019-12-09 20:45:58 -05:00
|
|
|
#include "rocksdb.h"
|
2019-12-06 20:39:32 -05:00
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
2019-12-06 17:33:18 -05:00
|
|
|
|
2019-12-22 18:38:10 -05:00
|
|
|
RocksDBStorageProvider::RocksDBStorageProvider(std::shared_ptr<rocksdb::DB> &spdb, std::shared_ptr<rocksdb::ColumnFamilyHandle> &spcolfam, const rocksdb::Snapshot *psnapshot, size_t count)
|
|
|
|
: m_spdb(spdb), m_psnapshot(psnapshot), m_spcolfamily(spcolfam), m_count(count)
|
2019-12-06 20:39:32 -05:00
|
|
|
{
|
|
|
|
m_readOptionsTemplate = rocksdb::ReadOptions();
|
|
|
|
m_readOptionsTemplate.snapshot = m_psnapshot;
|
|
|
|
}
|
|
|
|
|
2019-12-23 23:32:04 -05:00
|
|
|
void RocksDBStorageProvider::insert(const char *key, size_t cchKey, void *data, size_t cb, bool fOverwrite)
|
2019-12-06 20:39:32 -05:00
|
|
|
{
|
2019-12-08 20:06:22 -05:00
|
|
|
rocksdb::Status status;
|
|
|
|
if (m_spbatch != nullptr)
|
2019-12-09 20:45:58 -05:00
|
|
|
status = m_spbatch->Put(m_spcolfamily.get(), rocksdb::Slice(key, cchKey), rocksdb::Slice((const char*)data, cb));
|
2019-12-08 20:06:22 -05:00
|
|
|
else
|
2019-12-09 20:45:58 -05:00
|
|
|
status = m_spdb->Put(WriteOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cchKey), rocksdb::Slice((const char*)data, cb));
|
2019-12-06 20:39:32 -05:00
|
|
|
if (!status.ok())
|
2019-12-08 20:06:22 -05:00
|
|
|
throw status.ToString();
|
2019-12-22 19:41:36 -05:00
|
|
|
|
|
|
|
if (!fOverwrite)
|
|
|
|
++m_count;
|
2019-12-06 20:39:32 -05:00
|
|
|
}
|
|
|
|
|
2019-12-20 17:45:07 -05:00
|
|
|
bool RocksDBStorageProvider::erase(const char *key, size_t cchKey)
|
2019-12-06 20:39:32 -05:00
|
|
|
{
|
2019-12-08 20:06:22 -05:00
|
|
|
rocksdb::Status status;
|
|
|
|
if (m_spbatch != nullptr)
|
2019-12-22 17:30:15 -05:00
|
|
|
{
|
2019-12-09 20:45:58 -05:00
|
|
|
status = m_spbatch->Delete(m_spcolfamily.get(), rocksdb::Slice(key, cchKey));
|
2019-12-22 17:30:15 -05:00
|
|
|
}
|
2019-12-08 20:06:22 -05:00
|
|
|
else
|
2019-12-22 17:30:15 -05:00
|
|
|
{
|
2019-12-22 19:41:36 -05:00
|
|
|
if (!FKeyExists(key, cchKey))
|
2019-12-22 17:30:15 -05:00
|
|
|
return false;
|
2019-12-09 20:45:58 -05:00
|
|
|
status = m_spdb->Delete(WriteOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cchKey));
|
2019-12-22 17:30:15 -05:00
|
|
|
}
|
2019-12-22 18:38:10 -05:00
|
|
|
if (status.ok())
|
2019-12-22 19:41:36 -05:00
|
|
|
--m_count;
|
2019-12-20 17:45:07 -05:00
|
|
|
return status.ok();
|
2019-12-06 20:39:32 -05:00
|
|
|
}
|
|
|
|
|
2019-12-20 17:45:07 -05:00
|
|
|
void RocksDBStorageProvider::retrieve(const char *key, size_t cchKey, callbackSingle fn) const
|
2019-12-06 20:39:32 -05:00
|
|
|
{
|
|
|
|
std::string value;
|
2019-12-09 20:45:58 -05:00
|
|
|
auto status = m_spdb->Get(ReadOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cchKey), &value);
|
2019-12-19 17:30:31 -05:00
|
|
|
if (status.ok())
|
|
|
|
fn(key, cchKey, value.data(), value.size());
|
2019-12-06 20:39:32 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t RocksDBStorageProvider::clear()
|
|
|
|
{
|
2019-12-22 18:38:10 -05:00
|
|
|
size_t celem = count();
|
2019-12-09 20:45:58 -05:00
|
|
|
auto status = m_spdb->DropColumnFamily(m_spcolfamily.get());
|
|
|
|
auto strName = m_spcolfamily->GetName();
|
|
|
|
|
|
|
|
rocksdb::ColumnFamilyHandle *handle = nullptr;
|
|
|
|
m_spdb->CreateColumnFamily(rocksdb::ColumnFamilyOptions(), strName, &handle);
|
|
|
|
m_spcolfamily = std::shared_ptr<rocksdb::ColumnFamilyHandle>(handle);
|
|
|
|
|
2019-12-06 20:39:32 -05:00
|
|
|
if (!status.ok())
|
2019-12-08 20:06:22 -05:00
|
|
|
throw status.ToString();
|
2019-12-22 18:38:10 -05:00
|
|
|
m_count = 0;
|
2019-12-06 20:39:32 -05:00
|
|
|
return celem;
|
|
|
|
}
|
|
|
|
|
2019-12-22 18:38:10 -05:00
|
|
|
size_t RocksDBStorageProvider::count() const
|
2019-12-06 20:39:32 -05:00
|
|
|
{
|
2019-12-22 18:38:10 -05:00
|
|
|
return m_count;
|
2019-12-06 20:39:32 -05:00
|
|
|
}
|
|
|
|
|
2019-12-20 17:45:07 -05:00
|
|
|
bool RocksDBStorageProvider::enumerate(callback fn) const
|
2019-12-06 20:39:32 -05:00
|
|
|
{
|
2019-12-09 20:45:58 -05:00
|
|
|
std::unique_ptr<rocksdb::Iterator> it = std::unique_ptr<rocksdb::Iterator>(m_spdb->NewIterator(ReadOptions(), m_spcolfamily.get()));
|
2019-12-22 18:38:10 -05:00
|
|
|
size_t count = 0;
|
2019-12-06 20:39:32 -05:00
|
|
|
for (it->SeekToFirst(); it->Valid(); it->Next()) {
|
2019-12-22 18:38:10 -05:00
|
|
|
++count;
|
2019-12-20 17:45:07 -05:00
|
|
|
bool fContinue = fn(it->key().data(), it->key().size(), it->value().data(), it->value().size());
|
|
|
|
if (!fContinue)
|
|
|
|
break;
|
2019-12-06 20:39:32 -05:00
|
|
|
}
|
2019-12-22 18:38:10 -05:00
|
|
|
if (!it->Valid() && count != m_count)
|
|
|
|
{
|
|
|
|
const_cast<RocksDBStorageProvider*>(this)->m_count = count; // BUG!!! but be resilient
|
|
|
|
}
|
2019-12-06 20:39:32 -05:00
|
|
|
assert(it->status().ok()); // Check for any errors found during the scan
|
2019-12-20 17:45:07 -05:00
|
|
|
return !it->Valid();
|
2019-12-06 20:39:32 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
const IStorage *RocksDBStorageProvider::clone() const
|
|
|
|
{
|
2019-12-09 20:45:58 -05:00
|
|
|
const rocksdb::Snapshot *psnapshot = const_cast<RocksDBStorageProvider*>(this)->m_spdb->GetSnapshot();
|
2019-12-22 18:38:10 -05:00
|
|
|
return new RocksDBStorageProvider(const_cast<RocksDBStorageProvider*>(this)->m_spdb, const_cast<RocksDBStorageProvider*>(this)->m_spcolfamily, psnapshot, m_count);
|
2019-12-06 20:39:32 -05:00
|
|
|
}
|
|
|
|
|
2019-12-06 17:33:18 -05:00
|
|
|
RocksDBStorageProvider::~RocksDBStorageProvider()
|
|
|
|
{
|
2019-12-06 20:39:32 -05:00
|
|
|
if (m_spdb != nullptr)
|
|
|
|
{
|
|
|
|
if (m_psnapshot != nullptr)
|
|
|
|
m_spdb->ReleaseSnapshot(m_psnapshot);
|
|
|
|
}
|
2019-12-08 20:06:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
rocksdb::WriteOptions RocksDBStorageProvider::WriteOptions() const
|
|
|
|
{
|
|
|
|
auto opt = rocksdb::WriteOptions();
|
|
|
|
opt.disableWAL = true;
|
|
|
|
return opt;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RocksDBStorageProvider::beginWriteBatch()
|
|
|
|
{
|
|
|
|
m_spbatch = std::make_unique<rocksdb::WriteBatch>();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RocksDBStorageProvider::endWriteBatch()
|
|
|
|
{
|
|
|
|
m_spdb->Write(WriteOptions(), m_spbatch.get());
|
|
|
|
m_spbatch = nullptr;
|
2019-12-09 20:45:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void RocksDBStorageProvider::flush()
|
|
|
|
{
|
|
|
|
m_spdb->SyncWAL();
|
2019-12-22 19:41:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool RocksDBStorageProvider::FKeyExists(const char *key, size_t cch) const
|
|
|
|
{
|
|
|
|
std::string strT;
|
|
|
|
return m_spdb->Get(ReadOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cch), &strT).ok();
|
2019-12-06 17:33:18 -05:00
|
|
|
}
|