1
0
Fork 0

Merge branch 'engine-api' of https://github.com/arangodb/arangodb into engine-api

# Conflicts:
#	arangod/RocksDBEngine/RocksDBCommon.cpp
#	arangod/RocksDBEngine/RocksDBCommon.h
This commit is contained in:
Simon Grätzer 2017-03-28 01:15:50 +02:00
commit 8543cb77e3
15 changed files with 1141 additions and 613 deletions

View File

@ -438,13 +438,14 @@ set(ARANGOD_SOURCES
RocksDBEngine/RocksDBComparator.cpp
RocksDBEngine/RocksDBEdgeIndex.cpp
RocksDBEngine/RocksDBEngine.cpp
RocksDBEngine/RocksDBEntry.cpp
RocksDBEngine/RocksDBIndexFactory.cpp
RocksDBEngine/RocksDBKey.cpp
RocksDBEngine/RocksDBPrimaryIndex.cpp
RocksDBEngine/RocksDBPrimaryMockIndex.cpp
RocksDBEngine/RocksDBTransactionCollection.cpp
RocksDBEngine/RocksDBTransactionState.cpp
RocksDBEngine/RocksDBTypes.cpp
RocksDBEngine/RocksDBValue.cpp
RocksDBEngine/RocksDBView.cpp
)

View File

@ -22,18 +22,19 @@
////////////////////////////////////////////////////////////////////////////////
#include "RocksDBCollection.h"
#include "Aql/PlanCache.h"
#include "Basics/Result.h"
#include "Basics/StaticStrings.h"
#include "Aql/PlanCache.h"
#include "Basics/VelocyPackHelper.h"
#include "Cluster/ClusterMethods.h"
#include "Indexes/Index.h"
#include "Indexes/IndexIterator.h"
#include "RestServer/DatabaseFeature.h"
#include "RocksDBEngine/RocksDBEngine.h"
#include "RocksDBEngine/RocksDBEntry.h"
#include "RocksDBEngine/RocksDBKey.h"
#include "RocksDBEngine/RocksDBPrimaryMockIndex.h"
#include "RocksDBEngine/RocksDBToken.h"
#include "RocksDBEngine/RocksDBValue.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
#include "StorageEngine/TransactionState.h"
@ -48,7 +49,7 @@
#include <velocypack/velocypack-aliases.h>
using namespace arangodb;
static std::string const Empty;
RocksDBCollection::RocksDBCollection(LogicalCollection* collection,
@ -68,7 +69,7 @@ RocksDBCollection::RocksDBCollection(LogicalCollection* collection,
RocksDBCollection::~RocksDBCollection() {}
std::string const& RocksDBCollection::path() const {
return Empty; // we do not have any path
return Empty; // we do not have any path
}
void RocksDBCollection::setPath(std::string const&) {
@ -110,7 +111,8 @@ void RocksDBCollection::getPropertiesVPack(velocypack::Builder& result) const {
result.add("objectId", VPackValue(std::to_string(_objectId)));
}
void RocksDBCollection::getPropertiesVPackCoordinator(velocypack::Builder& result) const {
void RocksDBCollection::getPropertiesVPackCoordinator(
velocypack::Builder& result) const {
getPropertiesVPack(result);
}
@ -181,7 +183,9 @@ void RocksDBCollection::prepareIndexes(
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
if (_indexes[0]->type() != Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "got invalid indexes for collection '" << _logicalCollection->name() << "'";
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "got invalid indexes for collection '" << _logicalCollection->name()
<< "'";
for (auto const& it : _indexes) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "- " << it.get();
}
@ -229,7 +233,7 @@ std::shared_ptr<Index> RocksDBCollection::createIndex(
}
StorageEngine* engine = EngineSelectorFeature::ENGINE;
IndexFactory const* idxFactory = engine->indexFactory();
IndexFactory const* idxFactory = engine->indexFactory();
TRI_ASSERT(idxFactory != nullptr);
// We are sure that we do not have an index of this type.
@ -253,7 +257,8 @@ std::shared_ptr<Index> RocksDBCollection::createIndex(
THROW_ARANGO_EXCEPTION(res);
}
arangodb::aql::PlanCache::instance()->invalidate(_logicalCollection->vocbase());
arangodb::aql::PlanCache::instance()->invalidate(
_logicalCollection->vocbase());
// Until here no harm is done if sth fails. The shared ptr will clean up. if
// left before
@ -263,7 +268,8 @@ std::shared_ptr<Index> RocksDBCollection::createIndex(
application_features::ApplicationServer::getFeature<DatabaseFeature>(
"Database")
->forceSyncProperties();
VPackBuilder builder = _logicalCollection->toVelocyPackIgnore({"path", "statusString"}, true);
VPackBuilder builder =
_logicalCollection->toVelocyPackIgnore({"path", "statusString"}, true);
_logicalCollection->updateProperties(builder.slice(), doSync);
}
created = true;
@ -286,7 +292,8 @@ bool RocksDBCollection::dropIndex(TRI_idx_iid_t iid) {
std::unique_ptr<IndexIterator> RocksDBCollection::getAllIterator(
transaction::Methods* trx, ManagedDocumentResult* mdr, bool reverse) {
return std::unique_ptr<IndexIterator>(primaryIndex()->allIterator(trx, mdr, reverse));
return std::unique_ptr<IndexIterator>(
primaryIndex()->allIterator(trx, mdr, reverse));
}
std::unique_ptr<IndexIterator> RocksDBCollection::getAnyIterator(
@ -386,18 +393,18 @@ int RocksDBCollection::insert(arangodb::transaction::Methods* trx,
newSlice = slice;
}
TRI_voc_rid_t revisionId = transaction::helpers::extractRevFromDocument(newSlice);
TRI_voc_rid_t revisionId =
transaction::helpers::extractRevFromDocument(newSlice);
res = insertDocument(trx, revisionId, newSlice, options.waitForSync);
res = insertDocument(trx, revisionId, newSlice, options.waitForSync);
if (res == TRI_ERROR_NO_ERROR) {
// TODO: handle returning of result value!
// uint8_t const* vpack = lookupRevisionVPack(revisionId);
// if (vpack != nullptr) {
// result.addExisting(vpack, revisionId);
// }
// uint8_t const* vpack = lookupRevisionVPack(revisionId);
// if (vpack != nullptr) {
// result.addExisting(vpack, revisionId);
// }
}
return res;
}
@ -422,10 +429,10 @@ int RocksDBCollection::replace(
ManagedDocumentResult& previous, TRI_voc_rid_t const revisionId,
arangodb::velocypack::Slice const fromSlice,
arangodb::velocypack::Slice const toSlice) {
resultMarkerTick = 0;
bool const isEdgeCollection = (_logicalCollection->type() == TRI_COL_TYPE_EDGE);
bool const isEdgeCollection =
(_logicalCollection->type() == TRI_COL_TYPE_EDGE);
// get the previous revision
VPackSlice key = newSlice.get(StaticStrings::KeyString);
@ -442,7 +449,8 @@ int RocksDBCollection::replace(
uint8_t const* vpack = previous.vpack();
VPackSlice oldDoc(vpack);
TRI_voc_rid_t oldRevisionId = transaction::helpers::extractRevFromDocument(oldDoc);
TRI_voc_rid_t oldRevisionId =
transaction::helpers::extractRevFromDocument(oldDoc);
prevRev = oldRevisionId;
// Check old revision:
@ -473,13 +481,14 @@ int RocksDBCollection::replace(
}
}
res = updateDocument(trx, oldRevisionId, oldDoc, revisionId, VPackSlice(builder->slice()), options.waitForSync);
/* TODO: handle result handling
uint8_t const* vpack = lookupRevisionVPack(revisionId);
if (vpack != nullptr) {
result.addExisting(vpack, revisionId);
}
*/
res = updateDocument(trx, oldRevisionId, oldDoc, revisionId,
VPackSlice(builder->slice()), options.waitForSync);
/* TODO: handle result handling
uint8_t const* vpack = lookupRevisionVPack(revisionId);
if (vpack != nullptr) {
result.addExisting(vpack, revisionId);
}
*/
return res;
}
@ -516,7 +525,8 @@ int RocksDBCollection::remove(arangodb::transaction::Methods* trx,
uint8_t const* vpack = previous.vpack();
VPackSlice oldDoc(vpack);
TRI_voc_rid_t oldRevisionId = arangodb::transaction::helpers::extractRevFromDocument(oldDoc);
TRI_voc_rid_t oldRevisionId =
arangodb::transaction::helpers::extractRevFromDocument(oldDoc);
prevRev = oldRevisionId;
// Check old revision:
@ -530,7 +540,7 @@ int RocksDBCollection::remove(arangodb::transaction::Methods* trx,
}
res = removeDocument(trx, oldRevisionId, oldDoc, options.waitForSync);
return res;
}
@ -538,9 +548,10 @@ void RocksDBCollection::deferDropCollection(
std::function<bool(LogicalCollection*)> callback) {
THROW_ARANGO_NOT_YET_IMPLEMENTED();
}
/// @brief return engine-specific figures
void RocksDBCollection::figuresSpecific(std::shared_ptr<arangodb::velocypack::Builder>&) {
void RocksDBCollection::figuresSpecific(
std::shared_ptr<arangodb::velocypack::Builder>&) {
THROW_ARANGO_NOT_YET_IMPLEMENTED();
}
@ -552,7 +563,7 @@ void RocksDBCollection::createInitialIndexes() {
std::vector<std::shared_ptr<arangodb::Index>> systemIndexes;
StorageEngine* engine = EngineSelectorFeature::ENGINE;
IndexFactory const* idxFactory = engine->indexFactory();
IndexFactory const* idxFactory = engine->indexFactory();
TRI_ASSERT(idxFactory != nullptr);
idxFactory->fillSystemIndexes(_logicalCollection, systemIndexes);
@ -592,20 +603,21 @@ void RocksDBCollection::addIndexCoordinator(
_indexes.emplace_back(idx);
}
int RocksDBCollection::saveIndex(transaction::Methods* trx, std::shared_ptr<arangodb::Index> idx) {
int RocksDBCollection::saveIndex(transaction::Methods* trx,
std::shared_ptr<arangodb::Index> idx) {
TRI_ASSERT(!ServerState::instance()->isCoordinator());
// we cannot persist PrimaryMockIndex
TRI_ASSERT(idx->type() != Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX);
std::vector<std::shared_ptr<arangodb::Index>> indexListLocal;
indexListLocal.emplace_back(idx);
/* TODO
int res = fillIndexes(trx, indexListLocal, false);
/* TODO
int res = fillIndexes(trx, indexListLocal, false);
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
*/
if (res != TRI_ERROR_NO_ERROR) {
return res;
}
*/
std::shared_ptr<VPackBuilder> builder = idx->toVelocyPack(false);
auto vocbase = _logicalCollection->vocbase();
auto collectionId = _logicalCollection->cid();
@ -613,7 +625,7 @@ int RocksDBCollection::saveIndex(transaction::Methods* trx, std::shared_ptr<aran
StorageEngine* engine = EngineSelectorFeature::ENGINE;
engine->createIndex(vocbase, collectionId, idx->id(), data);
return TRI_ERROR_NO_ERROR;
}
@ -640,7 +652,7 @@ arangodb::RocksDBPrimaryMockIndex* RocksDBCollection::primaryIndex() const {
// the primary index must be the index at position #0
return static_cast<arangodb::RocksDBPrimaryMockIndex*>(primary.get());
}
int RocksDBCollection::insertDocument(arangodb::transaction::Methods* trx,
TRI_voc_rid_t revisionId,
VPackSlice const& doc,
@ -648,11 +660,12 @@ int RocksDBCollection::insertDocument(arangodb::transaction::Methods* trx,
// Coordinator doesn't know index internals
TRI_ASSERT(!ServerState::instance()->isCoordinator());
RocksDBEntry entry(RocksDBEntry::Document(_objectId, revisionId, doc));
RocksDBKey key(RocksDBKey::Document(_objectId, revisionId));
RocksDBValue value(RocksDBValue::Document(doc));
rocksdb::WriteBatch writeBatch;
writeBatch.Put(entry.key(), entry.value());
writeBatch.Put(key.key(), value.value());
auto indexes = _indexes;
size_t const n = indexes.size();
@ -682,10 +695,10 @@ int RocksDBCollection::insertDocument(arangodb::transaction::Methods* trx,
if (_logicalCollection->waitForSync()) {
waitForSync = true;
}
if (waitForSync) {
trx->state()->waitForSync(true);
// handle waitForSync for single operations here
if (trx->state()->isSingleOperation()) {
writeOptions.sync = true;
@ -707,11 +720,11 @@ int RocksDBCollection::removeDocument(arangodb::transaction::Methods* trx,
// Coordinator doesn't know index internals
TRI_ASSERT(!ServerState::instance()->isCoordinator());
RocksDBEntry entry(RocksDBEntry::Document(_objectId, revisionId, basics::VelocyPackHelper::EmptyObjectValue()));
auto key = RocksDBKey::Document(_objectId, revisionId);
rocksdb::WriteBatch writeBatch;
writeBatch.Delete(entry.key());
writeBatch.Delete(key.key());
auto indexes = _indexes;
size_t const n = indexes.size();
@ -734,10 +747,10 @@ int RocksDBCollection::removeDocument(arangodb::transaction::Methods* trx,
if (_logicalCollection->waitForSync()) {
waitForSync = true;
}
if (waitForSync) {
trx->state()->waitForSync(true);
// handle waitForSync for single operations here
if (trx->state()->isSingleOperation()) {
writeOptions.sync = true;
@ -754,8 +767,7 @@ int RocksDBCollection::removeDocument(arangodb::transaction::Methods* trx,
/// @brief looks up a document by key, low level worker
/// the key must be a string slice, no revision check is performed
int RocksDBCollection::lookupDocument(transaction::Methods* trx,
VPackSlice key,
int RocksDBCollection::lookupDocument(transaction::Methods* trx, VPackSlice key,
ManagedDocumentResult& result) {
if (!key.isString()) {
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
@ -766,21 +778,23 @@ int RocksDBCollection::lookupDocument(transaction::Methods* trx,
if (revisionId > 0) {
// TODO: add result handling!
/* uint8_t const* vpack = lookupRevisionVPack(revisionId);
if (vpack != nullptr) {
result.addExisting(vpack, revisionId);
}
*/
/* uint8_t const* vpack = lookupRevisionVPack(revisionId);
if (vpack != nullptr) {
result.addExisting(vpack, revisionId);
}
*/
return TRI_ERROR_NO_ERROR;
}
return TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND;
}
int RocksDBCollection::updateDocument(
transaction::Methods* trx, TRI_voc_rid_t oldRevisionId,
VPackSlice const& oldDoc, TRI_voc_rid_t newRevisionId,
VPackSlice const& newDoc, bool& waitForSync) {
int RocksDBCollection::updateDocument(transaction::Methods* trx,
TRI_voc_rid_t oldRevisionId,
VPackSlice const& oldDoc,
TRI_voc_rid_t newRevisionId,
VPackSlice const& newDoc,
bool& waitForSync) {
// TODO
return TRI_ERROR_NO_ERROR;
}

View File

@ -21,11 +21,12 @@
/// @author Daniel H. Larkin
////////////////////////////////////////////////////////////////////////////////
#include "RocksDBCommon.h"
#include "RocksDBEngine/RocksDBCommon.h"
using namespace arangodb;
namespace arangodb {
namespace rocksutils {
arangodb::Result arangodb::convertRocksDBStatus(rocksdb::Status const& status, StatusHint hint) {
arangodb::Result convertStatus(rocksdb::Status const& status, StatusHint hint) {
switch (status.code()) {
case rocksdb::Status::Code::kOk:
return {TRI_ERROR_NO_ERROR};
@ -72,3 +73,33 @@ arangodb::Result arangodb::convertRocksDBStatus(rocksdb::Status const& status, S
return {TRI_ERROR_INTERNAL, "unknown RocksDB status code"};
}
}
uint64_t uint64FromPersistent(char const* p) {
uint64_t value = 0;
uint64_t x = 0;
char const* end = p + sizeof(uint64_t);
do {
value += static_cast<uint64_t>(*p++) << x;
x += 8;
} while (p < end);
return value;
}
void uint64ToPersistent(char* p, uint64_t value) {
char* end = p + sizeof(uint64_t);
do {
*p++ = static_cast<uint8_t>(value & 0xff);
value >>= 8;
} while (p < end);
}
void uint64ToPersistent(std::string& p, uint64_t value) {
size_t len = 0;
do {
p.push_back(static_cast<char>(value & 0xff));
value >>= 8;
} while (++len < sizeof(uint64_t));
}
} // namespace rocksutils
} // namespace arangodb

View File

@ -30,14 +30,18 @@
#include <rocksdb/status.h>
namespace arangodb {
//namespace rocksdb {
namespace rocksutils {
enum StatusHint { none, document, collection, view, index, database };
arangodb::Result convertRocksDBStatus(::rocksdb::Status const&,
arangodb::Result convertStatus(rocksdb::Status const&,
StatusHint hint = StatusHint::none);
//} // namespace rocksdb
uint64_t uint64FromPersistent(char const* p);
void uint64ToPersistent(char* p, uint64_t value);
void uint64ToPersistent(std::string& out, uint64_t value);
} // namespace rocksutils
} // namespace arangodb
#endif

View File

@ -24,7 +24,7 @@
#include "RocksDBComparator.h"
#include "Basics/VelocyPackHelper.h"
#include "RocksDBEngine/RocksDBEntry.h"
#include "RocksDBEngine/RocksDBTypes.h"
using namespace arangodb;
using namespace arangodb::velocypack;
@ -83,13 +83,15 @@ int RocksDBComparator::compareDatabases(rocksdb::Slice const& lhs,
int RocksDBComparator::compareCollections(rocksdb::Slice const& lhs,
rocksdb::Slice const& rhs) const {
size_t offset = sizeof(char);
return memcmp(lhs.data() + offset, rhs.data() + offset, sizeof(uint64_t) + sizeof(uint64_t));
return memcmp(lhs.data() + offset, rhs.data() + offset,
sizeof(uint64_t) + sizeof(uint64_t));
}
int RocksDBComparator::compareIndexes(rocksdb::Slice const& lhs,
rocksdb::Slice const& rhs) const {
size_t offset = sizeof(char);
return memcmp(lhs.data() + offset, rhs.data() + offset, sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t));
return memcmp(lhs.data() + offset, rhs.data() + offset,
sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t));
}
int RocksDBComparator::compareDocuments(rocksdb::Slice const& lhs,
@ -145,7 +147,8 @@ int RocksDBComparator::compareUniqueIndexValues(
int RocksDBComparator::compareViews(rocksdb::Slice const& lhs,
rocksdb::Slice const& rhs) const {
size_t offset = sizeof(char);
return memcmp(lhs.data() + offset, rhs.data() + offset, sizeof(uint64_t) + sizeof(uint64_t));
return memcmp(lhs.data() + offset, rhs.data() + offset,
sizeof(uint64_t) + sizeof(uint64_t));
}
int RocksDBComparator::compareLexicographic(rocksdb::Slice const& lhs,

View File

@ -34,8 +34,9 @@
#include "Transaction/Methods.h"
#include "VocBase/LogicalCollection.h"
#include "RocksDBEngine/RocksDBCollection.h"
#include "RocksDBEngine/RocksDBCommon.h"
#include "RocksDBEngine/RocksDBEntry.h"
#include "RocksDBEngine/RocksDBKey.h"
#include "RocksDBEngine/RocksDBTypes.h"
#include "RocksDBEngine/RocksDBToken.h"
@ -103,8 +104,11 @@ bool RocksDBEdgeIndexIterator::next(TokenCallback const& cb, size_t limit) {
TRI_ASSERT(iter->key().size() > prefixSize);
VPackSlice edgeKey = VPackSlice(iter->key().data() + prefixSize);
TRI_ASSERT(edgeKey.isString());
// TODO how to make a primary index lookup?
//RocksDBCollection *coll = RocksDBCollection::toRocksDBCollection(_collection);
//RocksDBKey::PrimaryIndexValue(<#uint64_t indexId#>, <#const std::string &primaryKey#>)
#warning TODO query primary index ?!!
cb(RocksDBToken(0));
if (--limit == 0) {
@ -143,9 +147,8 @@ RocksDBEdgeIndex::RocksDBEdgeIndex(rocksdb::TransactionDB* db,
TRI_ASSERT(iid != 0);
#warning how to look this up?
TRI_voc_tick_t databaseId = collection->vocbase()->id();
RocksDBEntry entry =
RocksDBEntry::Index(databaseId, collection->cid(), iid, VPackSlice());
_objectId = 0;
RocksDBKey entry = RocksDBKey::Index(databaseId, collection->cid(), iid);
_objectId = 0;//entry.key;
}
RocksDBEdgeIndex::~RocksDBEdgeIndex() {}
@ -243,7 +246,7 @@ int RocksDBEdgeIndex::remove(transaction::Methods* trx,
if (status.ok()) {
return TRI_ERROR_NO_ERROR;
} else {
Result res = convertRocksDBStatus(status);
Result res = rocksutils::convertStatus(status, rocksutils::StatusHint::index);
return res.errorNumber();
}
} else {
@ -292,7 +295,7 @@ void RocksDBEdgeIndex::batchInsert(
rocksdb::Status status =
rtxr->Put(rocksdb::Slice(key.get(), keySize), rocksdb::Slice());
if (!status.ok()) {
Result res = convertRocksDBStatus(status, StatusHint::index);
Result res = rocksutils::convertStatus(status, rocksutils::StatusHint::index);
queue->setStatus(res.errorNumber());
rtxr->Rollback();
break;
@ -304,7 +307,7 @@ void RocksDBEdgeIndex::batchInsert(
}
rocksdb::Status status = rtxr->Commit();
if (!status.ok()) {
Result res = convertRocksDBStatus(status);
Result res = rocksutils::convertStatus(status, rocksutils::StatusHint::index);
queue->setStatus(res.errorNumber());
}

View File

@ -34,17 +34,18 @@
#include "RestServer/DatabasePathFeature.h"
#include "RestServer/ViewTypesFeature.h"
#include "RocksDBEngine/RocksDBCollection.h"
#include "RocksDBEngine/RocksDBEntry.h"
#include "RocksDBEngine/RocksDBIndexFactory.h"
#include "RocksDBEngine/RocksDBKey.h"
#include "RocksDBEngine/RocksDBTransactionCollection.h"
#include "RocksDBEngine/RocksDBTransactionContextData.h"
#include "RocksDBEngine/RocksDBTransactionState.h"
#include "RocksDBEngine/RocksDBTypes.h"
#include "RocksDBEngine/RocksDBValue.h"
#include "RocksDBEngine/RocksDBView.h"
#include "VocBase/ticks.h"
#include <rocksdb/db.h>
#include <rocksdb/convenience.h>
#include <rocksdb/db.h>
#include <rocksdb/env.h>
#include <rocksdb/filter_policy.h>
#include <rocksdb/iterator.h>
@ -69,52 +70,49 @@ std::string const RocksDBEngine::FeatureName("RocksDBEngine");
RocksDBEngine::RocksDBEngine(application_features::ApplicationServer* server)
: StorageEngine(server, EngineName, FeatureName, new RocksDBIndexFactory()),
_db(nullptr) {
//inherits order from StorageEngine
// inherits order from StorageEngine
}
RocksDBEngine::~RocksDBEngine() {
delete _db;
}
RocksDBEngine::~RocksDBEngine() { delete _db; }
// inherited from ApplicationFeature
// ---------------------------------
// add the storage engine's specifc options to the global list of options
void RocksDBEngine::collectOptions(std::shared_ptr<options::ProgramOptions>) {
}
void RocksDBEngine::collectOptions(std::shared_ptr<options::ProgramOptions>) {}
// validate the storage engine's specific options
void RocksDBEngine::validateOptions(std::shared_ptr<options::ProgramOptions>) {
}
void RocksDBEngine::validateOptions(std::shared_ptr<options::ProgramOptions>) {}
// preparation phase for storage engine. can be used for internal setup.
// the storage engine must not start any threads here or write any files
void RocksDBEngine::prepare() {
}
void RocksDBEngine::prepare() {}
void RocksDBEngine::start() {
//it is already decided that rocksdb is used
// it is already decided that rocksdb is used
if (!isEnabled()) {
return;
}
// set the database sub-directory for RocksDB
auto database = ApplicationServer::getFeature<DatabasePathFeature>("DatabasePath");
auto database =
ApplicationServer::getFeature<DatabasePathFeature>("DatabasePath");
_path = database->subdirectoryName("engine-rocksdb");
LOG_TOPIC(TRACE, arangodb::Logger::STARTUP) << "initializing rocksdb, path: " << _path;
LOG_TOPIC(TRACE, arangodb::Logger::STARTUP) << "initializing rocksdb, path: "
<< _path;
rocksdb::TransactionDBOptions transactionOptions;
_options.create_if_missing = true;
_options.max_open_files = -1;
rocksdb::Status status = rocksdb::TransactionDB::Open(_options, transactionOptions, _path, &_db);
rocksdb::Status status =
rocksdb::TransactionDB::Open(_options, transactionOptions, _path, &_db);
if (!status.ok()) {
LOG_TOPIC(FATAL, arangodb::Logger::STARTUP) << "unable to initialize RocksDB engine: " << status.ToString();
LOG_TOPIC(FATAL, arangodb::Logger::STARTUP)
<< "unable to initialize RocksDB engine: " << status.ToString();
FATAL_ERROR_EXIT();
}
@ -125,8 +123,7 @@ void RocksDBEngine::start() {
}
}
void RocksDBEngine::stop() {
}
void RocksDBEngine::stop() {}
void RocksDBEngine::unprepare() {
if (_db) {
@ -139,7 +136,8 @@ transaction::ContextData* RocksDBEngine::createTransactionContextData() {
return new RocksDBTransactionContextData;
}
TransactionState* RocksDBEngine::createTransactionState(TRI_vocbase_t* vocbase) {
TransactionState* RocksDBEngine::createTransactionState(
TRI_vocbase_t* vocbase) {
return new RocksDBTransactionState(vocbase);
}
@ -148,22 +146,24 @@ TransactionCollection* RocksDBEngine::createTransactionCollection(
int /*nestingLevel*/) {
return new RocksDBTransactionCollection(state, cid, accessType);
}
void RocksDBEngine::addParametersForNewCollection(VPackBuilder& builder, VPackSlice info) {
void RocksDBEngine::addParametersForNewCollection(VPackBuilder& builder,
VPackSlice info) {
if (!info.hasKey("objectId")) {
builder.add("objectId", VPackValue(std::to_string(TRI_NewTickServer())));
}
}
void RocksDBEngine::addParametersForNewIndex(VPackBuilder& builder, VPackSlice info) {
void RocksDBEngine::addParametersForNewIndex(VPackBuilder& builder,
VPackSlice info) {
if (!info.hasKey("objectId")) {
builder.add("objectId", VPackValue(std::to_string(TRI_NewTickServer())));
}
}
// create storage-engine specific collection
PhysicalCollection* RocksDBEngine::createPhysicalCollection(LogicalCollection* collection,
VPackSlice const& info) {
PhysicalCollection* RocksDBEngine::createPhysicalCollection(
LogicalCollection* collection, VPackSlice const& info) {
return new RocksDBCollection(collection, info);
}
@ -194,19 +194,20 @@ void RocksDBEngine::getDatabases(arangodb::velocypack::Builder& result) {
VPackSlice idSlice = slice.get("id");
if (!idSlice.isString()) {
LOG_TOPIC(ERR, arangodb::Logger::STARTUP)
<< "found invalid database declaration with non-string id: " << slice.toJson();
<< "found invalid database declaration with non-string id: "
<< slice.toJson();
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_PARAMETER_FILE);
}
// deleted
if (arangodb::basics::VelocyPackHelper::getBooleanValue(slice, "deleted",
false)) {
TRI_voc_tick_t id = static_cast<TRI_voc_tick_t>(
basics::StringUtils::uint64(idSlice.copyString()));
// database is deleted, skip it!
LOG_TOPIC(DEBUG, arangodb::Logger::STARTUP)
<< "found dropped database " << id;
LOG_TOPIC(DEBUG, arangodb::Logger::STARTUP) << "found dropped database "
<< id;
dropDatabase(id);
continue;
@ -216,7 +217,8 @@ void RocksDBEngine::getDatabases(arangodb::velocypack::Builder& result) {
VPackSlice nameSlice = slice.get("name");
if (!nameSlice.isString()) {
LOG_TOPIC(ERR, arangodb::Logger::STARTUP)
<< "found invalid database declaration with non-string name: " << slice.toJson();
<< "found invalid database declaration with non-string name: "
<< slice.toJson();
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_PARAMETER_FILE);
}
@ -235,7 +237,6 @@ void RocksDBEngine::getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid,
int RocksDBEngine::getCollectionsAndIndexes(
TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result,
bool wasCleanShutdown, bool isUpgrade) {
rocksdb::ReadOptions readOptions;
auto& iter = *_db->NewIterator(readOptions);
@ -243,16 +244,17 @@ int RocksDBEngine::getCollectionsAndIndexes(
auto rSlice = rocksDBSlice(RocksDBEntryType::Collection);
for (iter.Seek(rSlice); iter.Valid() && iter.key().starts_with(rSlice);
iter.Next()) {
if (!RocksDBEntry::isSameDatabase(RocksDBEntryType::Collection, vocbase->id(), iter.key())) {
if (vocbase->id() != RocksDBKey::databaseId(iter.key())) {
continue;
}
auto slice = VPackSlice(iter.value().data());
LOG_TOPIC(TRACE, Logger::FIXME) << "got collection slice: " << slice.toJson();
LOG_TOPIC(TRACE, Logger::FIXME) << "got collection slice: "
<< slice.toJson();
if (arangodb::basics::VelocyPackHelper::readBooleanValue(slice, "deleted", false)) {
if (arangodb::basics::VelocyPackHelper::readBooleanValue(slice, "deleted",
false)) {
continue;
}
result.add(slice);
@ -265,7 +267,6 @@ int RocksDBEngine::getCollectionsAndIndexes(
int RocksDBEngine::getViews(TRI_vocbase_t* vocbase,
arangodb::velocypack::Builder& result) {
rocksdb::ReadOptions readOptions;
auto& iter = *_db->NewIterator(readOptions);
@ -273,8 +274,7 @@ int RocksDBEngine::getViews(TRI_vocbase_t* vocbase,
auto rSlice = rocksDBSlice(RocksDBEntryType::View);
for (iter.Seek(rSlice); iter.Valid() && iter.key().starts_with(rSlice);
iter.Next()) {
if (!RocksDBEntry::isSameDatabase(RocksDBEntryType::View, vocbase->id(), iter.key())) {
if (vocbase->id() != !RocksDBKey::databaseId(iter.key())) {
continue;
}
@ -282,7 +282,8 @@ int RocksDBEngine::getViews(TRI_vocbase_t* vocbase,
LOG_TOPIC(TRACE, Logger::FIXME) << "got view slice: " << slice.toJson();
if (arangodb::basics::VelocyPackHelper::readBooleanValue(slice, "deleted", false)) {
if (arangodb::basics::VelocyPackHelper::readBooleanValue(slice, "deleted",
false)) {
continue;
}
result.add(slice);
@ -294,30 +295,34 @@ int RocksDBEngine::getViews(TRI_vocbase_t* vocbase,
}
std::string RocksDBEngine::databasePath(TRI_vocbase_t const* vocbase) const {
return std::string(); // no path to be returned here!
return std::string(); // no path to be returned here!
}
std::string RocksDBEngine::collectionPath(TRI_vocbase_t const* vocbase,
TRI_voc_cid_t id) const {
return std::string(); // no path to be returned here
return std::string(); // no path to be returned here
}
void RocksDBEngine::waitForSync(TRI_voc_tick_t tick) {
THROW_ARANGO_NOT_YET_IMPLEMENTED();
}
std::shared_ptr<arangodb::velocypack::Builder> RocksDBEngine::getReplicationApplierConfiguration(TRI_vocbase_t* vocbase, int& status) {
std::shared_ptr<arangodb::velocypack::Builder>
RocksDBEngine::getReplicationApplierConfiguration(TRI_vocbase_t* vocbase,
int& status) {
// TODO!
status = TRI_ERROR_FILE_NOT_FOUND;
return std::shared_ptr<arangodb::velocypack::Builder>();
}
int RocksDBEngine::removeReplicationApplierConfiguration(TRI_vocbase_t* vocbase) {
int RocksDBEngine::removeReplicationApplierConfiguration(
TRI_vocbase_t* vocbase) {
// TODO!
return TRI_ERROR_NO_ERROR;
}
int RocksDBEngine::saveReplicationApplierConfiguration(TRI_vocbase_t* vocbase, arangodb::velocypack::Slice slice, bool doSync) {
int RocksDBEngine::saveReplicationApplierConfiguration(
TRI_vocbase_t* vocbase, arangodb::velocypack::Slice slice, bool doSync) {
// TODO!
return TRI_ERROR_NO_ERROR;
}
@ -327,7 +332,6 @@ int RocksDBEngine::saveReplicationApplierConfiguration(TRI_vocbase_t* vocbase, a
TRI_vocbase_t* RocksDBEngine::openDatabase(
arangodb::velocypack::Slice const& args, bool isUpgrade, int& status) {
VPackSlice idSlice = args.get("id");
TRI_voc_tick_t id = static_cast<TRI_voc_tick_t>(
basics::StringUtils::uint64(idSlice.copyString()));
@ -341,36 +345,36 @@ TRI_vocbase_t* RocksDBEngine::openDatabase(
RocksDBEngine::Database* RocksDBEngine::createDatabase(
TRI_voc_tick_t id, arangodb::velocypack::Slice const& args, int& status) {
status = TRI_ERROR_NO_ERROR;
auto vocbase =
std::make_unique<TRI_vocbase_t>(TRI_VOCBASE_TYPE_NORMAL, id, args.get("name").copyString());
auto vocbase = std::make_unique<TRI_vocbase_t>(TRI_VOCBASE_TYPE_NORMAL, id,
args.get("name").copyString());
return vocbase.release();
}
int RocksDBEngine::writeCreateDatabaseMarker(TRI_voc_tick_t id,
VPackSlice const& slice) {
RocksDBEntry entry = RocksDBEntry::Database(id, slice);
rocksdb::WriteOptions options; // TODO: check which options would make sense
auto key = RocksDBKey::Database(id);
auto value = RocksDBValue::Database(slice);
rocksdb::WriteOptions options; // TODO: check which options would make sense
rocksdb::Status res = _db->Put(options, entry.key(), entry.value());
rocksdb::Status res = _db->Put(options, key.key(), value.value());
if (res.ok()) {
return TRI_ERROR_NO_ERROR;
}
return TRI_ERROR_INTERNAL; // TODO: need translation for RocksDB errors
return TRI_ERROR_INTERNAL; // TODO: need translation for RocksDB errors
}
int RocksDBEngine::writeCreateCollectionMarker(TRI_voc_tick_t databaseId,
TRI_voc_cid_t id,
VPackSlice const& slice) {
RocksDBEntry entry = RocksDBEntry::Collection(databaseId, id, slice);
rocksdb::WriteOptions options; // TODO: check which options would make sense
auto key = RocksDBKey::Collection(databaseId, id);
auto value = RocksDBValue::Collection(slice);
rocksdb::WriteOptions options; // TODO: check which options would make sense
rocksdb::Status res = _db->Put(options, entry.key(), entry.value());
rocksdb::Status res = _db->Put(options, key.key(), value.value());
if (res.ok()) {
return TRI_ERROR_NO_ERROR;
}
return TRI_ERROR_INTERNAL; // TODO: need translation for RocksDB errors
return TRI_ERROR_INTERNAL; // TODO: need translation for RocksDB errors
}
void RocksDBEngine::prepareDropDatabase(TRI_vocbase_t* vocbase,
@ -401,16 +405,15 @@ void RocksDBEngine::recoveryDone(TRI_vocbase_t* vocbase) {
std::string RocksDBEngine::createCollection(
TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
arangodb::LogicalCollection const* parameters) {
VPackBuilder builder =
parameters->toVelocyPackIgnore({"path", "statusString"}, true);
int res = writeCreateCollectionMarker(vocbase->id(), id, builder.slice());
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
return std::string(); // no need to return a path
return std::string(); // no need to return a path
}
arangodb::Result RocksDBEngine::persistCollection(
@ -424,7 +427,7 @@ arangodb::Result RocksDBEngine::persistCollection(
VPackBuilder builder =
collection->toVelocyPackIgnore({"path", "statusString"}, true);
VPackSlice const slice = builder.slice();
auto cid = collection->cid();
TRI_ASSERT(cid != 0);
TRI_UpdateTickServer(static_cast<TRI_voc_tick_t>(cid));
@ -432,9 +435,9 @@ arangodb::Result RocksDBEngine::persistCollection(
int res = writeCreateCollectionMarker(vocbase->id(), cid, slice);
if (res != TRI_ERROR_NO_ERROR) {
return { res };
return {res};
}
return {};
}
@ -449,9 +452,9 @@ void RocksDBEngine::destroyCollection(TRI_vocbase_t* vocbase,
THROW_ARANGO_NOT_YET_IMPLEMENTED();
}
void RocksDBEngine::changeCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
arangodb::LogicalCollection const* parameters,
bool doSync) {
void RocksDBEngine::changeCollection(
TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
arangodb::LogicalCollection const* parameters, bool doSync) {
createCollection(vocbase, id, parameters);
}
@ -463,12 +466,14 @@ arangodb::Result RocksDBEngine::renameCollection(
}
void RocksDBEngine::createIndex(TRI_vocbase_t* vocbase,
TRI_voc_cid_t collectionId, TRI_idx_iid_t indexId,
TRI_voc_cid_t collectionId,
TRI_idx_iid_t indexId,
arangodb::velocypack::Slice const& data) {
RocksDBEntry entry = RocksDBEntry::Index(vocbase->id(), collectionId, indexId, data);
rocksdb::WriteOptions options; // TODO: check which options would make sense
auto key = RocksDBKey::Index(vocbase->id(), collectionId, indexId);
auto value = RocksDBValue::Index(data);
rocksdb::WriteOptions options; // TODO: check which options would make sense
rocksdb::Status res = _db->Put(options, entry.key(), entry.value());
rocksdb::Status res = _db->Put(options, key.key(), value.value());
if (!res.ok()) {
// TODO: need translation for RocksDB errors
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
@ -606,7 +611,7 @@ int RocksDBEngine::openCollection(TRI_vocbase_t* vocbase,
/// @brief Add engine-specific AQL functions.
void RocksDBEngine::addAqlFunctions() {
// there are no specific AQL functions here
// TODO: potentially add NEAR, WITHIN?
// TODO: potentially add NEAR, WITHIN?
}
/// @brief Add engine-specific optimizer rules
@ -626,11 +631,11 @@ void RocksDBEngine::addRestHandlers(rest::RestHandlerFactory*) {
// TODO: add /_api/export and /_admin/wal later
}
EngineResult RocksDBEngine::dropDatabase(TRI_voc_tick_t str){
EngineResult RocksDBEngine::dropDatabase(TRI_voc_tick_t str) {
LOG_TOPIC(WARN, Logger::STARTUP) << "rocksdb - dropping database: " << str;
return EngineResult{};
}
bool RocksDBEngine::systemDatabaseExists() {
velocypack::Builder builder;
getDatabases(builder);
@ -656,11 +661,12 @@ void RocksDBEngine::addSystemDatabase() {
int res = writeCreateDatabaseMarker(id, builder.slice());
if (res != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(FATAL, arangodb::Logger::STARTUP) << "unable to write database marker: " << TRI_errno_string(res);
LOG_TOPIC(FATAL, arangodb::Logger::STARTUP)
<< "unable to write database marker: " << TRI_errno_string(res);
FATAL_ERROR_EXIT();
}
}
/// @brief open an existing database. internal function
TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
std::string const& name,
@ -680,7 +686,7 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
VPackSlice slice = builder.slice();
TRI_ASSERT(slice.isArray());
ViewTypesFeature* viewTypesFeature =
application_features::ApplicationServer::getFeature<ViewTypesFeature>(
"ViewTypes");
@ -696,7 +702,7 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
std::shared_ptr<LogicalView> view =
std::make_shared<arangodb::LogicalView>(vocbase.get(), it);
StorageEngine::registerView(vocbase.get(), view);
auto physical = static_cast<RocksDBView*>(view->getPhysical());
@ -759,4 +765,4 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
}
}
} // namespace
} // namespace

View File

@ -1,304 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Daniel H. Larkin
////////////////////////////////////////////////////////////////////////////////
#include "RocksDBEngine/RocksDBEntry.h"
#include "Basics/Exceptions.h"
using namespace arangodb;
using namespace arangodb::velocypack;
RocksDBEntry RocksDBEntry::Database(TRI_voc_tick_t databaseId, VPackSlice const& data) {
return RocksDBEntry(RocksDBEntryType::Database, databaseId, data);
}
RocksDBEntry RocksDBEntry::Collection(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, VPackSlice const& data) {
return RocksDBEntry(RocksDBEntryType::Collection, databaseId, collectionId, data);
}
RocksDBEntry RocksDBEntry::Index(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, TRI_idx_iid_t indexId, VPackSlice const& data) {
return RocksDBEntry(RocksDBEntryType::Index, databaseId, collectionId, indexId, data);
}
RocksDBEntry RocksDBEntry::Document(uint64_t collectionId, TRI_voc_rid_t revisionId,
VPackSlice const& data) {
return RocksDBEntry(RocksDBEntryType::Document, collectionId, revisionId, data);
}
RocksDBEntry RocksDBEntry::IndexValue(uint64_t indexId, TRI_voc_rid_t revisionId,
VPackSlice const& indexValues) {
return RocksDBEntry(RocksDBEntryType::IndexValue, indexId, revisionId, indexValues);
}
RocksDBEntry RocksDBEntry::UniqueIndexValue(uint64_t indexId,
TRI_voc_rid_t revisionId,
VPackSlice const& indexValues) {
return RocksDBEntry(RocksDBEntryType::UniqueIndexValue, indexId, revisionId, indexValues);
}
RocksDBEntry RocksDBEntry::View(TRI_voc_tick_t databaseId, TRI_voc_cid_t viewId, VPackSlice const& data) {
return RocksDBEntry(RocksDBEntryType::View, databaseId, viewId, data);
}
RocksDBEntryType RocksDBEntry::type() const { return _type; }
TRI_voc_tick_t RocksDBEntry::databaseId() const {
switch (_type) {
case RocksDBEntryType::Database: {
return uint64FromPersistent(_keyBuffer.data() + sizeof(char));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
TRI_voc_cid_t RocksDBEntry::collectionId() const {
switch (_type) {
case RocksDBEntryType::Collection: {
return uint64FromPersistent(_keyBuffer.data() + sizeof(char) + sizeof(uint64_t));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
TRI_voc_cid_t RocksDBEntry::viewId() const {
switch (_type) {
case RocksDBEntryType::View: {
return uint64FromPersistent(_keyBuffer.data() + sizeof(char) + sizeof(uint64_t));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
TRI_idx_iid_t RocksDBEntry::indexId() const {
switch (_type) {
case RocksDBEntryType::Index: {
return uint64FromPersistent(_keyBuffer.data() + sizeof(char) + sizeof(uint64_t) + sizeof(uint64_t));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
TRI_voc_rid_t RocksDBEntry::revisionId() const {
switch (_type) {
case RocksDBEntryType::Document: {
return uint64FromPersistent(_keyBuffer.data() + sizeof(char) + sizeof(uint64_t));
}
case RocksDBEntryType::IndexValue: {
return *reinterpret_cast<TRI_voc_rid_t const*>(
_keyBuffer.data() + (_keyBuffer.size() - sizeof(uint64_t)));
}
case RocksDBEntryType::UniqueIndexValue: {
return *reinterpret_cast<TRI_voc_rid_t const*>(_valueBuffer.data());
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
VPackSlice RocksDBEntry::indexedValues() const {
switch (_type) {
case RocksDBEntryType::IndexValue:
case RocksDBEntryType::UniqueIndexValue: {
return VPackSlice(_keyBuffer.data() + sizeof(char) + sizeof(uint64_t));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
VPackSlice RocksDBEntry::data() const {
switch (_type) {
case RocksDBEntryType::Database:
case RocksDBEntryType::Collection:
case RocksDBEntryType::Index:
case RocksDBEntryType::Document:
case RocksDBEntryType::View: {
return VPackSlice(_valueBuffer.data());
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
std::string const& RocksDBEntry::key() const { return _keyBuffer; }
std::string const& RocksDBEntry::value() const { return _valueBuffer; }
std::string& RocksDBEntry::valueBuffer() { return _valueBuffer; }
RocksDBEntry::RocksDBEntry(RocksDBEntryType type, uint64_t first, VPackSlice const& slice)
: _type(type), _keyBuffer(), _valueBuffer() {
switch (_type) {
case RocksDBEntryType::Database: {
size_t length = sizeof(char) + sizeof(uint64_t);
_keyBuffer.reserve(length);
_keyBuffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_keyBuffer, first); // databaseId
_valueBuffer.append(reinterpret_cast<char const*>(slice.begin()),
static_cast<size_t>(slice.byteSize()));
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBEntry::RocksDBEntry(RocksDBEntryType type, uint64_t first,
uint64_t second, VPackSlice const& slice)
: _type(type), _keyBuffer(), _valueBuffer() {
switch (_type) {
case RocksDBEntryType::Collection:
case RocksDBEntryType::View: {
size_t length = sizeof(char) + sizeof(uint64_t) + sizeof(uint64_t);
_keyBuffer.reserve(length);
_keyBuffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_keyBuffer, first); // databaseId
uint64ToPersistent(_keyBuffer, second); // viewId / collectionId
_valueBuffer.append(reinterpret_cast<char const*>(slice.begin()),
static_cast<size_t>(slice.byteSize()));
break;
}
case RocksDBEntryType::Document: {
size_t length = sizeof(char) + (2 * sizeof(uint64_t));
_keyBuffer.reserve(length);
_keyBuffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_keyBuffer, first);
uint64ToPersistent(_keyBuffer, second);
_valueBuffer.append(reinterpret_cast<char const*>(slice.begin()),
static_cast<size_t>(slice.byteSize()));
break;
}
case RocksDBEntryType::IndexValue: {
size_t length = sizeof(char) + static_cast<size_t>(slice.byteSize()) +
(2 * sizeof(uint64_t));
_keyBuffer.reserve(length);
_keyBuffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_keyBuffer, first);
_keyBuffer.append(reinterpret_cast<char const*>(slice.begin()),
static_cast<size_t>(slice.byteSize()));
_keyBuffer.append(std::to_string(second));
break;
}
case RocksDBEntryType::UniqueIndexValue: {
size_t length = sizeof(char) + static_cast<size_t>(slice.byteSize()) +
sizeof(uint64_t);
_keyBuffer.reserve(length);
_keyBuffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_keyBuffer, first);
_keyBuffer.append(reinterpret_cast<char const*>(slice.begin()),
static_cast<size_t>(slice.byteSize()));
_valueBuffer.append(reinterpret_cast<char const*>(&second),
sizeof(uint64_t));
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBEntry::RocksDBEntry(RocksDBEntryType type, uint64_t first,
uint64_t second, uint64_t third, VPackSlice const& slice)
: _type(type), _keyBuffer(), _valueBuffer() {
switch (_type) {
case RocksDBEntryType::Index: {
size_t length = sizeof(char) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t);
_keyBuffer.reserve(length);
_keyBuffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_keyBuffer, first); // databaseId
uint64ToPersistent(_keyBuffer, second); // collectionId
uint64ToPersistent(_keyBuffer, third); // indexId
_valueBuffer.append(reinterpret_cast<char const*>(slice.begin()),
static_cast<size_t>(slice.byteSize()));
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
bool RocksDBEntry::isSameDatabase(RocksDBEntryType type, TRI_voc_tick_t id, rocksdb::Slice const& slice) {
switch (type) {
case RocksDBEntryType::Collection:
case RocksDBEntryType::View: {
TRI_ASSERT(slice.size() == sizeof(char) + sizeof(uint64_t) + sizeof(uint64_t));
return id == uint64FromPersistent(slice.data() + sizeof(char));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
uint64_t RocksDBEntry::uint64FromPersistent(char const* p) {
uint64_t value = 0;
uint64_t x = 0;
char const* end = p + sizeof(uint64_t);
do {
value += static_cast<uint64_t>(*p++) << x;
x += 8;
} while (p < end);
return value;
}
void RocksDBEntry::uint64ToPersistent(char* p, uint64_t value) {
char* end = p + sizeof(uint64_t);
do {
*p++ = static_cast<uint8_t>(value & 0xff);
value >>= 8;
} while (p < end);
}
void RocksDBEntry::uint64ToPersistent(std::string& p, uint64_t value) {
size_t len = 0;
do {
p.push_back(static_cast<char>(value & 0xff));
value >>= 8;
} while (++len < sizeof(uint64_t));
}

View File

@ -1,87 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Daniel H. Larkin
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGO_ROCKSDB_ROCKSDB_ENTRY_H
#define ARANGO_ROCKSDB_ROCKSDB_ENTRY_H 1
#include "Basics/Common.h"
#include "RocksDBEngine/RocksDBTypes.h"
#include "VocBase/vocbase.h"
#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>
namespace arangodb {
class RocksDBEntry {
public:
RocksDBEntry() = delete;
static RocksDBEntry Database(TRI_voc_tick_t databaseId, VPackSlice const& data);
static RocksDBEntry Collection(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, VPackSlice const& data);
static RocksDBEntry Index(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, TRI_idx_iid_t indexId, VPackSlice const& data);
static RocksDBEntry Document(uint64_t collectionId, TRI_voc_rid_t revisionId,
VPackSlice const& data);
static RocksDBEntry IndexValue(uint64_t indexId, TRI_voc_rid_t revisionId,
VPackSlice const& indexValues);
static RocksDBEntry UniqueIndexValue(uint64_t indexId, TRI_voc_rid_t revisionId,
VPackSlice const& indexValues);
static RocksDBEntry View(TRI_voc_tick_t databaseId, TRI_voc_cid_t viewId, VPackSlice const& data);
public:
RocksDBEntryType type() const;
TRI_voc_tick_t databaseId() const;
TRI_voc_cid_t collectionId() const;
TRI_idx_iid_t indexId() const;
TRI_voc_cid_t viewId() const;
TRI_voc_rid_t revisionId() const;
VPackSlice indexedValues() const;
VPackSlice data() const;
std::string const& key() const;
std::string const& value() const;
std::string& valueBuffer();
static bool isSameDatabase(RocksDBEntryType type, TRI_voc_tick_t id, rocksdb::Slice const& slice);
static uint64_t uint64FromPersistent(char const* p);
static void uint64ToPersistent(char* p, uint64_t value);
static void uint64ToPersistent(std::string& out, uint64_t value);
private:
RocksDBEntry(RocksDBEntryType type, uint64_t first, VPackSlice const& slice);
RocksDBEntry(RocksDBEntryType type, uint64_t first, uint64_t second, VPackSlice const& slice);
RocksDBEntry(RocksDBEntryType type, uint64_t first, uint64_t second, uint64_t third, VPackSlice const& slice);
private:
RocksDBEntryType const _type;
std::string _keyBuffer;
std::string _valueBuffer;
};
} // namespace arangodb
#endif

View File

@ -0,0 +1,457 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Daniel H. Larkin
////////////////////////////////////////////////////////////////////////////////
#include "RocksDBEngine/RocksDBKey.h"
#include "Basics/Exceptions.h"
#include "RocksDBEngine/RocksDBCommon.h"
#include "RocksDBEngine/RocksDBTypes.h"
using namespace arangodb;
using namespace arangodb::rocksutils;
using namespace arangodb::velocypack;
const char RocksDBKey::_stringSeparator = '\0';
RocksDBKey RocksDBKey::Database(TRI_voc_tick_t databaseId) {
return RocksDBKey(RocksDBEntryType::Database, databaseId);
}
RocksDBKey RocksDBKey::Collection(TRI_voc_tick_t databaseId,
TRI_voc_cid_t collectionId) {
return RocksDBKey(RocksDBEntryType::Collection, databaseId, collectionId);
}
RocksDBKey RocksDBKey::Index(TRI_voc_tick_t databaseId,
TRI_voc_cid_t collectionId,
TRI_idx_iid_t indexId) {
return RocksDBKey(RocksDBEntryType::Index, databaseId, collectionId, indexId);
}
RocksDBKey RocksDBKey::Document(uint64_t collectionId,
TRI_voc_rid_t revisionId) {
return RocksDBKey(RocksDBEntryType::Document, collectionId, revisionId);
}
RocksDBKey RocksDBKey::PrimaryIndexValue(uint64_t indexId,
std::string const& primaryKey) {
return RocksDBKey(RocksDBEntryType::PrimaryIndexValue, indexId, primaryKey);
}
RocksDBKey RocksDBKey::EdgeIndexValue(uint64_t indexId,
std::string const& vertexId,
std::string const& primaryKey) {
return RocksDBKey(RocksDBEntryType::EdgeIndexValue, indexId, vertexId,
primaryKey);
}
RocksDBKey RocksDBKey::IndexValue(uint64_t indexId,
std::string const& primaryKey,
VPackSlice const& indexValues) {
return RocksDBKey(RocksDBEntryType::IndexValue, indexId, primaryKey,
indexValues);
}
RocksDBKey RocksDBKey::UniqueIndexValue(uint64_t indexId,
VPackSlice const& indexValues) {
return RocksDBKey(RocksDBEntryType::UniqueIndexValue, indexId, indexValues);
}
RocksDBKey RocksDBKey::View(TRI_voc_tick_t databaseId, TRI_voc_cid_t viewId) {
return RocksDBKey(RocksDBEntryType::View, databaseId, viewId);
}
RocksDBEntryType RocksDBKey::type(RocksDBKey const& key) {
return type(key._buffer.data(), key._buffer.size());
}
RocksDBEntryType RocksDBKey::type(rocksdb::Slice const& slice) {
return type(slice.data(), slice.size());
}
TRI_voc_tick_t RocksDBKey::databaseId(RocksDBKey const& key) {
return databaseId(key._buffer.data(), key._buffer.size());
}
TRI_voc_tick_t RocksDBKey::databaseId(rocksdb::Slice const& slice) {
return databaseId(slice.data(), slice.size());
}
TRI_voc_cid_t RocksDBKey::collectionId(RocksDBKey const& key) {
return collectionId(key._buffer.data(), key._buffer.size());
}
TRI_voc_cid_t RocksDBKey::collectionId(rocksdb::Slice const& slice) {
return collectionId(slice.data(), slice.size());
}
TRI_idx_iid_t RocksDBKey::indexId(RocksDBKey const& key) {
return indexId(key._buffer.data(), key._buffer.size());
}
TRI_idx_iid_t RocksDBKey::indexId(rocksdb::Slice const& slice) {
return indexId(slice.data(), slice.size());
}
TRI_voc_cid_t RocksDBKey::viewId(RocksDBKey const& key) {
return viewId(key._buffer.data(), key._buffer.size());
}
TRI_voc_cid_t RocksDBKey::viewId(rocksdb::Slice const& slice) {
return viewId(slice.data(), slice.size());
}
TRI_voc_rid_t RocksDBKey::revisionId(RocksDBKey const& key) {
return revisionId(key._buffer.data(), key._buffer.size());
}
TRI_voc_rid_t RocksDBKey::revisionId(rocksdb::Slice const& slice) {
return revisionId(slice.data(), slice.size());
}
std::string RocksDBKey::primaryKey(RocksDBKey const& key) {
return primaryKey(key._buffer.data(), key._buffer.size());
}
std::string RocksDBKey::primaryKey(rocksdb::Slice const& slice) {
return primaryKey(slice.data(), slice.size());
}
std::string RocksDBKey::vertexId(RocksDBKey const& key) {
return vertexId(key._buffer.data(), key._buffer.size());
}
std::string RocksDBKey::vertexId(rocksdb::Slice const& slice) {
return vertexId(slice.data(), slice.size());
}
VPackSlice RocksDBKey::indexedVPack(RocksDBKey const& key) {
return indexedVPack(key._buffer.data(), key._buffer.size());
}
VPackSlice RocksDBKey::indexedVPack(rocksdb::Slice const& slice) {
return indexedVPack(slice.data(), slice.size());
}
std::string const& RocksDBKey::key() const { return _buffer; }
bool RocksDBKey::isSameDatabase(RocksDBEntryType type, TRI_voc_tick_t id,
rocksdb::Slice const& slice) {
switch (type) {
case RocksDBEntryType::Collection:
case RocksDBEntryType::View: {
TRI_ASSERT(slice.size() ==
sizeof(char) + sizeof(uint64_t) + sizeof(uint64_t));
return id == uint64FromPersistent(slice.data() + sizeof(char));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBKey::RocksDBKey(RocksDBEntryType type, uint64_t first)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::Database: {
size_t length = sizeof(char) + sizeof(uint64_t);
_buffer.reserve(length);
_buffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_buffer, first); // databaseId
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBKey::RocksDBKey(RocksDBEntryType type, uint64_t first,
VPackSlice const& slice)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::UniqueIndexValue: {
size_t length = sizeof(char) + sizeof(uint64_t) +
static_cast<size_t>(slice.byteSize());
_buffer.reserve(length);
_buffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_buffer, first);
_buffer.append(reinterpret_cast<char const*>(slice.begin()),
static_cast<size_t>(slice.byteSize()));
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBKey::RocksDBKey(RocksDBEntryType type, uint64_t first, uint64_t second)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::Collection:
case RocksDBEntryType::Document:
case RocksDBEntryType::View: {
size_t length = sizeof(char) + (2 * sizeof(uint64_t));
_buffer.reserve(length);
_buffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_buffer,
first); // databaseId / collectionId / databaseId
uint64ToPersistent(_buffer,
second); // collectionId / collectionId / viewId
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBKey::RocksDBKey(RocksDBEntryType type, uint64_t first, uint64_t second,
uint64_t third)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::Index: {
size_t length =
sizeof(char) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t);
_buffer.reserve(length);
_buffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_buffer, first); // databaseId
uint64ToPersistent(_buffer, second); // collectionId
uint64ToPersistent(_buffer, third); // indexId
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBKey::RocksDBKey(RocksDBEntryType type, uint64_t first,
std::string const& second, VPackSlice const& slice)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::IndexValue: {
size_t length = sizeof(char) + sizeof(uint64_t) +
static_cast<size_t>(slice.byteSize()) + second.size();
_buffer.reserve(length);
_buffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_buffer, first);
_buffer.append(reinterpret_cast<char const*>(slice.begin()),
static_cast<size_t>(slice.byteSize()));
_buffer.append(second);
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBKey::RocksDBKey(RocksDBEntryType type, uint64_t first,
std::string const& second)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::PrimaryIndexValue: {
size_t length = sizeof(char) + sizeof(uint64_t) + second.size();
_buffer.reserve(length);
_buffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_buffer, first);
_buffer.append(second);
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBKey::RocksDBKey(RocksDBEntryType type, uint64_t first,
std::string const& second, std::string const& third)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::PrimaryIndexValue: {
size_t length = sizeof(char) + sizeof(uint64_t) + second.size() +
sizeof(char) + third.size() + sizeof(uint8_t);
_buffer.reserve(length);
_buffer.push_back(static_cast<char>(_type));
uint64ToPersistent(_buffer, first);
_buffer.append(second);
_buffer.push_back(_stringSeparator);
_buffer.append(third);
TRI_ASSERT(third.size() <= 254);
_buffer.push_back(static_cast<char>(third.size() & 0xff));
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBEntryType RocksDBKey::type(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
return static_cast<RocksDBEntryType>(data[0]);
}
TRI_voc_tick_t RocksDBKey::databaseId(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
RocksDBEntryType type = static_cast<RocksDBEntryType>(data[0]);
switch (type) {
case RocksDBEntryType::Database:
case RocksDBEntryType::Collection:
case RocksDBEntryType::Index:
case RocksDBEntryType::View: {
TRI_ASSERT(size >= (sizeof(char) + sizeof(uint64_t)));
return uint64FromPersistent(data + sizeof(char));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
TRI_voc_cid_t RocksDBKey::collectionId(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
RocksDBEntryType type = static_cast<RocksDBEntryType>(data[0]);
switch (type) {
case RocksDBEntryType::Collection:
case RocksDBEntryType::Index: {
TRI_ASSERT(size >= (sizeof(char) + (2 * sizeof(uint64_t))));
return uint64FromPersistent(data + sizeof(char) + sizeof(uint64_t));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
TRI_idx_iid_t RocksDBKey::indexId(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
RocksDBEntryType type = static_cast<RocksDBEntryType>(data[0]);
switch (type) {
case RocksDBEntryType::Index: {
TRI_ASSERT(size >= (sizeof(char) + (3 * sizeof(uint64_t))));
return uint64FromPersistent(data + sizeof(char) + (2 * sizeof(uint64_t)));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
TRI_voc_cid_t RocksDBKey::viewId(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
RocksDBEntryType type = static_cast<RocksDBEntryType>(data[0]);
switch (type) {
case RocksDBEntryType::View: {
TRI_ASSERT(size >= (sizeof(char) + (2 * sizeof(uint64_t))));
return uint64FromPersistent(data + sizeof(char) + sizeof(uint64_t));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
TRI_voc_rid_t RocksDBKey::revisionId(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
RocksDBEntryType type = static_cast<RocksDBEntryType>(data[0]);
switch (type) {
case RocksDBEntryType::Document: {
TRI_ASSERT(size >= (sizeof(char) + (2 * sizeof(uint64_t))));
return uint64FromPersistent(data + sizeof(char) + sizeof(uint64_t));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
std::string RocksDBKey::primaryKey(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
RocksDBEntryType type = static_cast<RocksDBEntryType>(data[0]);
switch (type) {
case RocksDBEntryType::PrimaryIndexValue: {
TRI_ASSERT(size > (sizeof(char) + sizeof(uint64_t) + sizeof(uint8_t)));
size_t keySize = size - (sizeof(char) + sizeof(uint64_t));
return std::string(data + sizeof(char) + sizeof(uint64_t), keySize);
}
case RocksDBEntryType::EdgeIndexValue: {
TRI_ASSERT(size > (sizeof(char) + sizeof(uint64_t) + sizeof(uint8_t)));
size_t keySize = static_cast<size_t>(data[size - 1]);
return std::string(data + (size - (keySize + sizeof(uint8_t))), keySize);
}
case RocksDBEntryType::IndexValue: {
TRI_ASSERT(size > (sizeof(char) + sizeof(uint64_t)));
VPackSlice slice(data + sizeof(char) + sizeof(uint64_t));
size_t sliceSize = static_cast<size_t>(slice.byteSize());
size_t keySize = size - (sizeof(char) + sizeof(uint64_t) + sliceSize);
return std::string(data + (size - keySize), keySize);
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
std::string RocksDBKey::vertexId(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
RocksDBEntryType type = static_cast<RocksDBEntryType>(data[0]);
switch (type) {
case RocksDBEntryType::EdgeIndexValue: {
TRI_ASSERT(size > (sizeof(char) + sizeof(uint64_t) + sizeof(uint8_t)));
size_t keySize = static_cast<size_t>(data[size - 1]);
size_t idSize = size - (sizeof(char) + sizeof(uint64_t) + sizeof(char) +
keySize + sizeof(uint8_t));
return std::string(data + sizeof(char) + sizeof(uint64_t), idSize);
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}
VPackSlice RocksDBKey::indexedVPack(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
RocksDBEntryType type = static_cast<RocksDBEntryType>(data[0]);
switch (type) {
case RocksDBEntryType::IndexValue:
case RocksDBEntryType::UniqueIndexValue: {
TRI_ASSERT(size > (sizeof(char) + sizeof(uint64_t)));
return VPackSlice(data + sizeof(char) + sizeof(uint64_t));
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
}

View File

@ -0,0 +1,125 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Daniel H. Larkin
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGO_ROCKSDB_ROCKSDB_KEY_H
#define ARANGO_ROCKSDB_ROCKSDB_KEY_H 1
#include "Basics/Common.h"
#include "RocksDBEngine/RocksDBTypes.h"
#include "VocBase/vocbase.h"
#include <rocksdb/slice.h>
#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>
namespace arangodb {
class RocksDBKey {
public:
RocksDBKey() = delete;
static RocksDBKey Database(TRI_voc_tick_t databaseId);
static RocksDBKey Collection(TRI_voc_tick_t databaseId,
TRI_voc_cid_t collectionId);
static RocksDBKey Index(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId,
TRI_idx_iid_t indexId);
static RocksDBKey Document(uint64_t collectionId, TRI_voc_rid_t revisionId);
static RocksDBKey PrimaryIndexValue(uint64_t indexId,
std::string const& primaryKey);
static RocksDBKey EdgeIndexValue(uint64_t indexId,
std::string const& vertexId,
std::string const& primaryKey);
static RocksDBKey IndexValue(uint64_t indexId, std::string const& primaryKey,
VPackSlice const& indexValues);
static RocksDBKey UniqueIndexValue(uint64_t indexId,
VPackSlice const& indexValues);
static RocksDBKey View(TRI_voc_tick_t databaseId, TRI_voc_cid_t viewId);
public:
static RocksDBEntryType type(RocksDBKey const&);
static RocksDBEntryType type(rocksdb::Slice const&);
static TRI_voc_tick_t databaseId(RocksDBKey const&);
static TRI_voc_tick_t databaseId(rocksdb::Slice const&);
static TRI_voc_cid_t collectionId(RocksDBKey const&);
static TRI_voc_cid_t collectionId(rocksdb::Slice const&);
static TRI_idx_iid_t indexId(RocksDBKey const&);
static TRI_idx_iid_t indexId(rocksdb::Slice const&);
static TRI_voc_cid_t viewId(RocksDBKey const&);
static TRI_voc_cid_t viewId(rocksdb::Slice const&);
static TRI_voc_rid_t revisionId(RocksDBKey const&);
static TRI_voc_rid_t revisionId(rocksdb::Slice const&);
static std::string primaryKey(RocksDBKey const&);
static std::string primaryKey(rocksdb::Slice const&);
static std::string vertexId(RocksDBKey const&);
static std::string vertexId(rocksdb::Slice const&);
static VPackSlice indexedVPack(RocksDBKey const&);
static VPackSlice indexedVPack(rocksdb::Slice const&);
public:
std::string const& key() const;
static bool isSameDatabase(RocksDBEntryType type, TRI_voc_tick_t id,
rocksdb::Slice const& slice);
private:
RocksDBKey(RocksDBEntryType type, uint64_t first);
RocksDBKey(RocksDBEntryType type, uint64_t first, uint64_t second);
RocksDBKey(RocksDBEntryType type, uint64_t first, uint64_t second,
uint64_t third);
RocksDBKey(RocksDBEntryType type, uint64_t first, VPackSlice const& slice);
RocksDBKey(RocksDBEntryType type, uint64_t first, std::string const& second,
VPackSlice const& slice);
RocksDBKey(RocksDBEntryType type, uint64_t first, std::string const& second);
RocksDBKey(RocksDBEntryType type, uint64_t first, std::string const& second,
std::string const& third);
private:
static RocksDBEntryType type(char const* data, size_t size);
static TRI_voc_tick_t databaseId(char const* data, size_t size);
static TRI_voc_cid_t collectionId(char const* data, size_t size);
static TRI_idx_iid_t indexId(char const* data, size_t size);
static TRI_voc_cid_t viewId(char const* data, size_t size);
static TRI_voc_rid_t revisionId(char const* data, size_t size);
static std::string primaryKey(char const* data, size_t size);
static std::string vertexId(char const* data, size_t size);
static VPackSlice indexedVPack(char const* data, size_t size);
private:
static const char _stringSeparator;
RocksDBEntryType const _type;
std::string _buffer;
};
} // namespace arangodb
#endif

View File

@ -27,10 +27,9 @@
#include "Basics/StaticStrings.h"
#include "Basics/VelocyPackHelper.h"
#include "Indexes/SimpleAttributeEqualityMatcher.h"
#include "RocksDBEngine/RocksDBEntry.h"
#include "Transaction/Context.h"
#include "Transaction/Helpers.h"
#include "Transaction/Methods.h"
#include "Transaction/Context.h"
#include "VocBase/LogicalCollection.h"
#include <velocypack/Builder.h>
@ -43,57 +42,57 @@ using namespace arangodb;
/// @brief hard-coded vector of the index attributes
/// note that the attribute names must be hard-coded here to avoid an init-order
/// fiasco with StaticStrings::FromString etc.
static std::vector<std::vector<arangodb::basics::AttributeName>> const IndexAttributes
{{arangodb::basics::AttributeName("_id", false)},
{arangodb::basics::AttributeName("_key", false)}};
static std::vector<std::vector<arangodb::basics::AttributeName>> const
IndexAttributes{{arangodb::basics::AttributeName("_id", false)},
{arangodb::basics::AttributeName("_key", false)}};
RocksDBPrimaryMockIndexIterator::RocksDBPrimaryMockIndexIterator(LogicalCollection* collection,
transaction::Methods* trx,
ManagedDocumentResult* mmdr,
RocksDBPrimaryMockIndex const* index,
std::unique_ptr<VPackBuilder>& keys)
RocksDBPrimaryMockIndexIterator::RocksDBPrimaryMockIndexIterator(
LogicalCollection* collection, transaction::Methods* trx,
ManagedDocumentResult* mmdr, RocksDBPrimaryMockIndex const* index,
std::unique_ptr<VPackBuilder>& keys)
: IndexIterator(collection, trx, mmdr, index),
_index(index),
_keys(keys.get()),
_index(index),
_keys(keys.get()),
_iterator(_keys->slice()) {
keys.release(); // now we have ownership for _keys
keys.release(); // now we have ownership for _keys
TRI_ASSERT(_keys->slice().isArray());
}
RocksDBPrimaryMockIndexIterator::~RocksDBPrimaryMockIndexIterator() {
if (_keys != nullptr) {
// return the VPackBuilder to the transaction context
// return the VPackBuilder to the transaction context
_trx->transactionContextPtr()->returnBuilder(_keys.release());
}
}
bool RocksDBPrimaryMockIndexIterator::next(TokenCallback const& cb, size_t limit) {
bool RocksDBPrimaryMockIndexIterator::next(TokenCallback const& cb,
size_t limit) {
THROW_ARANGO_NOT_YET_IMPLEMENTED();
return false;
}
void RocksDBPrimaryMockIndexIterator::reset() { _iterator.reset(); }
RocksDBAllIndexIterator::RocksDBAllIndexIterator(LogicalCollection* collection,
transaction::Methods* trx,
ManagedDocumentResult* mmdr,
RocksDBPrimaryMockIndex const* index,
bool reverse)
: IndexIterator(collection, trx, mmdr, index), _reverse(reverse), _total(0) {}
RocksDBAllIndexIterator::RocksDBAllIndexIterator(
LogicalCollection* collection, transaction::Methods* trx,
ManagedDocumentResult* mmdr, RocksDBPrimaryMockIndex const* index,
bool reverse)
: IndexIterator(collection, trx, mmdr, index),
_reverse(reverse),
_total(0) {}
bool RocksDBAllIndexIterator::next(TokenCallback const& cb, size_t limit) {
// TODO
return false;
}
void RocksDBAllIndexIterator::reset() {
void RocksDBAllIndexIterator::reset() {
// TODO
}
RocksDBAnyIndexIterator::RocksDBAnyIndexIterator(LogicalCollection* collection, transaction::Methods* trx,
ManagedDocumentResult* mmdr,
RocksDBPrimaryMockIndex const* index)
RocksDBAnyIndexIterator::RocksDBAnyIndexIterator(
LogicalCollection* collection, transaction::Methods* trx,
ManagedDocumentResult* mmdr, RocksDBPrimaryMockIndex const* index)
: IndexIterator(collection, trx, mmdr, index) {}
bool RocksDBAnyIndexIterator::next(TokenCallback const& cb, size_t limit) {
@ -101,33 +100,34 @@ bool RocksDBAnyIndexIterator::next(TokenCallback const& cb, size_t limit) {
return true;
}
void RocksDBAnyIndexIterator::reset() {
THROW_ARANGO_NOT_YET_IMPLEMENTED();
}
void RocksDBAnyIndexIterator::reset() { THROW_ARANGO_NOT_YET_IMPLEMENTED(); }
RocksDBPrimaryMockIndex::RocksDBPrimaryMockIndex(arangodb::LogicalCollection* collection, VPackSlice const& info)
: Index(basics::VelocyPackHelper::stringUInt64(info, "objectId"), collection,
RocksDBPrimaryMockIndex::RocksDBPrimaryMockIndex(
arangodb::LogicalCollection* collection, VPackSlice const& info)
: Index(basics::VelocyPackHelper::stringUInt64(info, "objectId"),
collection,
std::vector<std::vector<arangodb::basics::AttributeName>>(
{{arangodb::basics::AttributeName(StaticStrings::KeyString, false)}}),
{{arangodb::basics::AttributeName(StaticStrings::KeyString,
false)}}),
true, false),
_objectId(basics::VelocyPackHelper::stringUInt64(info, "objectId")){
}
_objectId(basics::VelocyPackHelper::stringUInt64(info, "objectId")) {}
RocksDBPrimaryMockIndex::~RocksDBPrimaryMockIndex() {}
/// @brief return the number of documents from the index
size_t RocksDBPrimaryMockIndex::size() const {
size_t RocksDBPrimaryMockIndex::size() const {
// TODO
return 0;
}
/// @brief return the memory usage of the index
size_t RocksDBPrimaryMockIndex::memory() const {
return 0; // TODO
return 0; // TODO
}
/// @brief return a VelocyPack representation of the index
void RocksDBPrimaryMockIndex::toVelocyPack(VPackBuilder& builder, bool withFigures) const {
void RocksDBPrimaryMockIndex::toVelocyPack(VPackBuilder& builder,
bool withFigures) const {
Index::toVelocyPack(builder, withFigures);
// hard-coded
builder.add("unique", VPackValue(true));
@ -140,7 +140,9 @@ void RocksDBPrimaryMockIndex::toVelocyPackFigures(VPackBuilder& builder) const {
// TODO: implement
}
RocksDBToken RocksDBPrimaryMockIndex::lookupKey(transaction::Methods* trx, VPackSlice slice, ManagedDocumentResult& result) {
RocksDBToken RocksDBPrimaryMockIndex::lookupKey(transaction::Methods* trx,
VPackSlice slice,
ManagedDocumentResult& result) {
std::string key = slice.copyString();
std::lock_guard<std::mutex> lock(_keyRevMutex);
LOG_TOPIC(ERR, Logger::FIXME) << "LOOKUP. THE KEY IS: " << key;
@ -151,23 +153,28 @@ RocksDBToken RocksDBPrimaryMockIndex::lookupKey(transaction::Methods* trx, VPack
return RocksDBToken((*it).second);
}
int RocksDBPrimaryMockIndex::insert(transaction::Methods*, TRI_voc_rid_t revisionId, VPackSlice const& slice, bool) {
int RocksDBPrimaryMockIndex::insert(transaction::Methods*,
TRI_voc_rid_t revisionId,
VPackSlice const& slice, bool) {
std::string key = slice.get("_key").copyString();
std::lock_guard<std::mutex> lock(_keyRevMutex);
LOG_TOPIC(ERR, Logger::FIXME) << "INSERT. THE KEY IS: " << key << "; THE REVISION IS: " << revisionId;
LOG_TOPIC(ERR, Logger::FIXME) << "INSERT. THE KEY IS: " << key
<< "; THE REVISION IS: " << revisionId;
auto result = _keyRevMap.emplace(key, revisionId);
if(result.second){
if (result.second) {
return TRI_ERROR_NO_ERROR;
}
return TRI_ERROR_INTERNAL;
}
int RocksDBPrimaryMockIndex::remove(transaction::Methods*, TRI_voc_rid_t revisionId, VPackSlice const& slice, bool) {
int RocksDBPrimaryMockIndex::remove(transaction::Methods*,
TRI_voc_rid_t revisionId,
VPackSlice const& slice, bool) {
std::string key = slice.get("_key").copyString();
std::lock_guard<std::mutex> lock(_keyRevMutex);
LOG_TOPIC(ERR, Logger::FIXME) << "REMOVE. THE KEY IS: " << key;
auto result = _keyRevMap.erase(key); //result number of deleted elements
if(result){
auto result = _keyRevMap.erase(key); // result number of deleted elements
if (result) {
return TRI_ERROR_NO_ERROR;
}
return TRI_ERROR_INTERNAL;
@ -184,7 +191,6 @@ bool RocksDBPrimaryMockIndex::supportsFilterCondition(
arangodb::aql::AstNode const* node,
arangodb::aql::Variable const* reference, size_t itemsInIndex,
size_t& estimatedItems, double& estimatedCost) const {
SimpleAttributeEqualityMatcher matcher(IndexAttributes);
return matcher.matchOne(this, node, reference, itemsInIndex, estimatedItems,
estimatedCost);
@ -192,11 +198,9 @@ bool RocksDBPrimaryMockIndex::supportsFilterCondition(
/// @brief creates an IndexIterator for the given Condition
IndexIterator* RocksDBPrimaryMockIndex::iteratorForCondition(
transaction::Methods* trx,
ManagedDocumentResult* mmdr,
transaction::Methods* trx, ManagedDocumentResult* mmdr,
arangodb::aql::AstNode const* node,
arangodb::aql::Variable const* reference, bool reverse) const {
THROW_ARANGO_NOT_YET_IMPLEMENTED();
return nullptr;
}
@ -205,7 +209,6 @@ IndexIterator* RocksDBPrimaryMockIndex::iteratorForCondition(
arangodb::aql::AstNode* RocksDBPrimaryMockIndex::specializeCondition(
arangodb::aql::AstNode* node,
arangodb::aql::Variable const* reference) const {
SimpleAttributeEqualityMatcher matcher(IndexAttributes);
return matcher.specializeOne(this, node, reference);
}
@ -213,15 +216,15 @@ arangodb::aql::AstNode* RocksDBPrimaryMockIndex::specializeCondition(
/// @brief request an iterator over all elements in the index in
/// a sequential order.
IndexIterator* RocksDBPrimaryMockIndex::allIterator(transaction::Methods* trx,
ManagedDocumentResult* mmdr,
bool reverse) const {
ManagedDocumentResult* mmdr,
bool reverse) const {
return new RocksDBAllIndexIterator(_collection, trx, mmdr, this, reverse);
}
/// @brief request an iterator over all elements in the index in
/// a random order. It is guaranteed that each element is found
/// exactly once unless the collection is modified.
IndexIterator* RocksDBPrimaryMockIndex::anyIterator(transaction::Methods* trx,
ManagedDocumentResult* mmdr) const {
IndexIterator* RocksDBPrimaryMockIndex::anyIterator(
transaction::Methods* trx, ManagedDocumentResult* mmdr) const {
return new RocksDBAnyIndexIterator(_collection, trx, mmdr, this);
}

View File

@ -36,9 +36,11 @@ enum class RocksDBEntryType : char {
Collection = '1',
Index = '2',
Document = '3',
IndexValue = '4',
UniqueIndexValue = '5',
View = '6'
PrimaryIndexValue = '4',
EdgeIndexValue = '5',
IndexValue = '6',
UniqueIndexValue = '7',
View = '8'
};
rocksdb::Slice const& rocksDBSlice(RocksDBEntryType const& type);

View File

@ -0,0 +1,182 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Daniel H. Larkin
////////////////////////////////////////////////////////////////////////////////
#include "RocksDBEngine/RocksDBValue.h"
#include "Basics/Exceptions.h"
#include "RocksDBEngine/RocksDBCommon.h"
using namespace arangodb;
using namespace arangodb::rocksutils;
using namespace arangodb::velocypack;
RocksDBValue RocksDBValue::Database(VPackSlice const& data) {
return RocksDBValue(RocksDBEntryType::Database, data);
}
RocksDBValue RocksDBValue::Collection(VPackSlice const& data) {
return RocksDBValue(RocksDBEntryType::Collection, data);
}
RocksDBValue RocksDBValue::Index(VPackSlice const& data) {
return RocksDBValue(RocksDBEntryType::Index, data);
}
RocksDBValue RocksDBValue::Document(VPackSlice const& data) {
return RocksDBValue(RocksDBEntryType::Document, data);
}
RocksDBValue RocksDBValue::PrimaryIndexValue(TRI_voc_rid_t revisionId) {
return RocksDBValue(RocksDBEntryType::PrimaryIndexValue, revisionId);
}
RocksDBValue RocksDBValue::EdgeIndexValue() {
return RocksDBValue(RocksDBEntryType::EdgeIndexValue);
}
RocksDBValue RocksDBValue::IndexValue() {
return RocksDBValue(RocksDBEntryType::IndexValue);
}
RocksDBValue RocksDBValue::UniqueIndexValue(std::string const& primaryKey) {
return RocksDBValue(RocksDBEntryType::UniqueIndexValue, primaryKey);
}
RocksDBValue RocksDBValue::View(VPackSlice const& data) {
return RocksDBValue(RocksDBEntryType::View, data);
}
TRI_voc_rid_t RocksDBValue::revisionId(RocksDBValue const& value) {
return revisionId(value._buffer.data(), value._buffer.size());
}
TRI_voc_rid_t RocksDBValue::revisionId(rocksdb::Slice const& slice) {
return revisionId(slice.data(), slice.size());
}
TRI_voc_rid_t RocksDBValue::revisionId(std::string const& s) {
return revisionId(s.data(), s.size());
}
std::string RocksDBValue::primaryKey(RocksDBValue const& value) {
return primaryKey(value._buffer.data(), value._buffer.size());
}
std::string RocksDBValue::primaryKey(rocksdb::Slice const& slice) {
return primaryKey(slice.data(), slice.size());
}
std::string RocksDBValue::primaryKey(std::string const& s) {
return primaryKey(s.data(), s.size());
}
VPackSlice RocksDBValue::data(RocksDBValue const& value) {
return data(value._buffer.data(), value._buffer.size());
}
VPackSlice RocksDBValue::data(rocksdb::Slice const& slice) {
return data(slice.data(), slice.size());
}
VPackSlice RocksDBValue::data(std::string const& s) {
return data(s.data(), s.size());
}
std::string const& RocksDBValue::value() const { return _buffer; }
RocksDBValue::RocksDBValue(RocksDBEntryType type) : _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::EdgeIndexValue:
case RocksDBEntryType::IndexValue: {
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBValue::RocksDBValue(RocksDBEntryType type, uint64_t data)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::PrimaryIndexValue: {
_buffer.reserve(sizeof(uint64_t));
uint64ToPersistent(_buffer, data); // revision id
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBValue::RocksDBValue(RocksDBEntryType type, std::string const& data)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::UniqueIndexValue: {
_buffer.reserve(data.size());
_buffer.append(data); // primary key
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
RocksDBValue::RocksDBValue(RocksDBEntryType type, VPackSlice const& data)
: _type(type), _buffer() {
switch (_type) {
case RocksDBEntryType::Database:
case RocksDBEntryType::Collection:
case RocksDBEntryType::Index:
case RocksDBEntryType::Document:
case RocksDBEntryType::View: {
_buffer.reserve(static_cast<size_t>(data.byteSize()));
_buffer.append(reinterpret_cast<char const*>(data.begin()),
static_cast<size_t>(data.byteSize()));
break;
}
default:
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
}
}
TRI_voc_rid_t RocksDBValue::revisionId(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size == sizeof(uint64_t));
return uint64FromPersistent(data);
}
std::string RocksDBValue::primaryKey(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
return std::string(data, size);
}
VPackSlice RocksDBValue::data(char const* data, size_t size) {
TRI_ASSERT(data != nullptr);
TRI_ASSERT(size >= sizeof(char));
return VPackSlice(data);
}

View File

@ -0,0 +1,88 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2017 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Daniel H. Larkin
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGO_ROCKSDB_ROCKSDB_VALUE_H
#define ARANGO_ROCKSDB_ROCKSDB_VALUE_H 1
#include "Basics/Common.h"
#include "RocksDBEngine/RocksDBTypes.h"
#include "VocBase/vocbase.h"
#include <rocksdb/slice.h>
#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>
namespace arangodb {
class RocksDBValue {
public:
RocksDBValue() = delete;
static RocksDBValue Database(VPackSlice const& data);
static RocksDBValue Collection(VPackSlice const& data);
static RocksDBValue Index(VPackSlice const& data);
static RocksDBValue Document(VPackSlice const& data);
static RocksDBValue PrimaryIndexValue(TRI_voc_rid_t revisionId);
static RocksDBValue EdgeIndexValue();
static RocksDBValue IndexValue();
static RocksDBValue UniqueIndexValue(std::string const& primaryKey);
static RocksDBValue View(VPackSlice const& data);
public:
static TRI_voc_rid_t revisionId(RocksDBValue const&);
static TRI_voc_rid_t revisionId(rocksdb::Slice const&);
static TRI_voc_rid_t revisionId(std::string const&);
static std::string primaryKey(RocksDBValue const&);
static std::string primaryKey(rocksdb::Slice const&);
static std::string primaryKey(std::string const&);
static VPackSlice data(RocksDBValue const&);
static VPackSlice data(rocksdb::Slice const&);
static VPackSlice data(std::string const&);
public:
std::string const& value() const;
private:
RocksDBValue(RocksDBEntryType type);
RocksDBValue(RocksDBEntryType type, uint64_t data);
RocksDBValue(RocksDBEntryType type, std::string const& data);
RocksDBValue(RocksDBEntryType type, VPackSlice const& data);
private:
static RocksDBEntryType type(char const* data, size_t size);
static TRI_voc_rid_t revisionId(char const* data, size_t size);
static std::string primaryKey(char const* data, size_t size);
static VPackSlice data(char const* data, size_t size);
private:
RocksDBEntryType const _type;
std::string _buffer;
};
} // namespace arangodb
#endif