mirror of https://gitee.com/bigwinds/arangodb
changed storage format
This commit is contained in:
parent
f20a0a8c3d
commit
3ad939ea41
|
@ -328,30 +328,22 @@ void RocksDBEdgeIndexIterator::lookupInRocksDB(StringRef fromTo) {
|
|||
rocksdb::Comparator const* cmp = _index->comparator();
|
||||
|
||||
_builder.openArray();
|
||||
RocksDBToken token;
|
||||
auto end = _bounds.end();
|
||||
while (_iterator->Valid() &&
|
||||
(cmp->Compare(_iterator->key(), end) < 0)) {
|
||||
StringRef edgeKey = RocksDBKey::primaryKey(_iterator->key());
|
||||
Result res = rocksColl->lookupDocumentToken(_trx, edgeKey, token);
|
||||
if (res.ok()) {
|
||||
ManagedDocumentResult mmdr;
|
||||
if (rocksColl->readDocument(_trx, token, mmdr)) {
|
||||
_builder.add(VPackValue(token.revisionId()));
|
||||
VPackSlice doc(mmdr.vpack());
|
||||
TRI_ASSERT(doc.isObject());
|
||||
_builder.add(doc);
|
||||
} else {
|
||||
// Data Inconsistency.
|
||||
// We have a revision id without a document...
|
||||
TRI_ASSERT(false);
|
||||
}
|
||||
#ifdef USE_MAINTAINER_MODE
|
||||
TRI_voc_rid_t revisionId = RocksDBKey::revisionId(_iterator->key());
|
||||
RocksDBToken token(revisionId);
|
||||
|
||||
ManagedDocumentResult mmdr;
|
||||
if (rocksColl->readDocument(_trx, token, mmdr)) {
|
||||
_builder.add(VPackValue(token.revisionId()));
|
||||
VPackSlice doc(mmdr.vpack());
|
||||
TRI_ASSERT(doc.isObject());
|
||||
_builder.add(doc);
|
||||
} else {
|
||||
// Index inconsistency, we indexed a primaryKey => revision that is
|
||||
// not known any more
|
||||
TRI_ASSERT(res.ok());
|
||||
#endif
|
||||
// Data Inconsistency.
|
||||
// We have a revision id without a document...
|
||||
TRI_ASSERT(false);
|
||||
}
|
||||
_iterator->Next();
|
||||
}
|
||||
|
@ -455,12 +447,12 @@ void RocksDBEdgeIndex::toVelocyPack(VPackBuilder& builder, bool withFigures,
|
|||
int RocksDBEdgeIndex::insert(transaction::Methods* trx,
|
||||
TRI_voc_rid_t revisionId, VPackSlice const& doc,
|
||||
bool isRollback) {
|
||||
VPackSlice primaryKey = doc.get(StaticStrings::KeyString);
|
||||
//VPackSlice primaryKey = doc.get(StaticStrings::KeyString);
|
||||
VPackSlice fromTo = doc.get(_directionAttr);
|
||||
TRI_ASSERT(primaryKey.isString() && fromTo.isString());
|
||||
TRI_ASSERT(fromTo.isString());
|
||||
auto fromToRef = StringRef(fromTo);
|
||||
RocksDBKey key =
|
||||
RocksDBKey::EdgeIndexValue(_objectId, fromToRef, StringRef(primaryKey));
|
||||
RocksDBKey::EdgeIndexValue(_objectId, fromToRef, revisionId);
|
||||
// blacklist key in cache
|
||||
blackListKey(fromToRef);
|
||||
|
||||
|
@ -486,12 +478,12 @@ int RocksDBEdgeIndex::insertRaw(RocksDBMethods*, TRI_voc_rid_t,
|
|||
int RocksDBEdgeIndex::remove(transaction::Methods* trx,
|
||||
TRI_voc_rid_t revisionId, VPackSlice const& doc,
|
||||
bool isRollback) {
|
||||
VPackSlice primaryKey = doc.get(StaticStrings::KeyString);
|
||||
//VPackSlice primaryKey = doc.get(StaticStrings::KeyString);
|
||||
VPackSlice fromTo = doc.get(_directionAttr);
|
||||
auto fromToRef = StringRef(fromTo);
|
||||
TRI_ASSERT(primaryKey.isString() && fromTo.isString());
|
||||
TRI_ASSERT(fromTo.isString());
|
||||
RocksDBKey key =
|
||||
RocksDBKey::EdgeIndexValue(_objectId, fromToRef, StringRef(primaryKey));
|
||||
RocksDBKey::EdgeIndexValue(_objectId, fromToRef, revisionId);
|
||||
|
||||
// blacklist key in cache
|
||||
blackListKey(fromToRef);
|
||||
|
@ -521,12 +513,12 @@ void RocksDBEdgeIndex::batchInsert(
|
|||
std::shared_ptr<arangodb::basics::LocalTaskQueue> queue) {
|
||||
RocksDBMethods* mthd = rocksutils::toRocksMethods(trx);
|
||||
for (std::pair<TRI_voc_rid_t, VPackSlice> const& doc : documents) {
|
||||
VPackSlice primaryKey = doc.second.get(StaticStrings::KeyString);
|
||||
//VPackSlice primaryKey = doc.second.get(StaticStrings::KeyString);
|
||||
VPackSlice fromTo = doc.second.get(_directionAttr);
|
||||
TRI_ASSERT(primaryKey.isString() && fromTo.isString());
|
||||
TRI_ASSERT(fromTo.isString());
|
||||
auto fromToRef = StringRef(fromTo);
|
||||
RocksDBKey key =
|
||||
RocksDBKey::EdgeIndexValue(_objectId, fromToRef, StringRef(primaryKey));
|
||||
RocksDBKey::EdgeIndexValue(_objectId, fromToRef, doc.first);
|
||||
|
||||
blackListKey(fromToRef);
|
||||
Result r = mthd->Put(_cf, rocksdb::Slice(key.string()), rocksdb::Slice(),
|
||||
|
@ -657,11 +649,10 @@ void RocksDBEdgeIndex::warmup(arangodb::transaction::Methods* trx) {
|
|||
std::string previous = "";
|
||||
VPackBuilder builder;
|
||||
ManagedDocumentResult mmdr;
|
||||
RocksDBToken token;
|
||||
bool needsInsert = false;
|
||||
|
||||
rocksutils::iterateBounds(bounds, [&](rocksdb::Iterator* it) {
|
||||
auto key = it->key();
|
||||
rocksdb::Slice key = it->key();
|
||||
StringRef v = RocksDBKey::vertexId(key);
|
||||
if (previous.empty()) {
|
||||
// First call.
|
||||
|
@ -707,14 +698,11 @@ void RocksDBEdgeIndex::warmup(arangodb::transaction::Methods* trx) {
|
|||
needsInsert = true;
|
||||
builder.openArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
if (needsInsert) {
|
||||
StringRef edgeKey = RocksDBKey::primaryKey(key);
|
||||
Result res = rocksColl->lookupDocumentToken(trx, edgeKey, token);
|
||||
if (res.ok() && rocksColl->readDocument(trx, token, mmdr)) {
|
||||
TRI_voc_rid_t revisionId = RocksDBKey::revisionId(key);
|
||||
RocksDBToken token(revisionId);
|
||||
if (rocksColl->readDocument(trx, token, mmdr)) {
|
||||
builder.add(VPackValue(token.revisionId()));
|
||||
VPackSlice doc(mmdr.vpack());
|
||||
TRI_ASSERT(doc.isObject());
|
||||
|
|
|
@ -201,14 +201,13 @@ int RocksDBFulltextIndex::insert(transaction::Methods* trx,
|
|||
RocksDBMethods* mthd = rocksutils::toRocksMethods(trx);
|
||||
// now we are going to construct the value to insert into rocksdb
|
||||
// unique indexes have a different key structure
|
||||
StringRef docKey(doc.get(StaticStrings::KeyString));
|
||||
RocksDBValue value = RocksDBValue::IndexValue();
|
||||
|
||||
int res = TRI_ERROR_NO_ERROR;
|
||||
// size_t const count = words.size();
|
||||
for (std::string const& word : words) {
|
||||
RocksDBKey key =
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), docKey);
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), revisionId);
|
||||
|
||||
Result r = mthd->Put(_cf, key, value.string(), rocksutils::index);
|
||||
if (!r.ok()) {
|
||||
|
@ -220,14 +219,14 @@ int RocksDBFulltextIndex::insert(transaction::Methods* trx,
|
|||
for (size_t j = 0; j < i; ++j) {
|
||||
std::string const& word = words[j];
|
||||
RocksDBKey key =
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), docKey);
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), revisionId);
|
||||
rtrx->Delete(key.string());
|
||||
}
|
||||
}*/
|
||||
return res;
|
||||
}
|
||||
|
||||
int RocksDBFulltextIndex::insertRaw(RocksDBMethods* batch, TRI_voc_rid_t,
|
||||
int RocksDBFulltextIndex::insertRaw(RocksDBMethods* batch, TRI_voc_rid_t revisionId,
|
||||
arangodb::velocypack::Slice const& doc) {
|
||||
std::set<std::string> words = wordlist(doc);
|
||||
if (words.empty()) {
|
||||
|
@ -236,12 +235,12 @@ int RocksDBFulltextIndex::insertRaw(RocksDBMethods* batch, TRI_voc_rid_t,
|
|||
|
||||
// now we are going to construct the value to insert into rocksdb
|
||||
// unique indexes have a different key structure
|
||||
StringRef docKey(doc.get(StaticStrings::KeyString));
|
||||
//StringRef docKey(doc.get(StaticStrings::KeyString));
|
||||
RocksDBValue value = RocksDBValue::IndexValue();
|
||||
|
||||
for (std::string const& word : words) {
|
||||
RocksDBKey key =
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), docKey);
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), revisionId);
|
||||
batch->Put(_cf, key, value.string());
|
||||
}
|
||||
|
||||
|
@ -261,11 +260,10 @@ int RocksDBFulltextIndex::remove(transaction::Methods* trx,
|
|||
RocksDBMethods* mthd = rocksutils::toRocksMethods(trx);
|
||||
// now we are going to construct the value to insert into rocksdb
|
||||
// unique indexes have a different key structure
|
||||
StringRef docKey(doc.get(StaticStrings::KeyString));
|
||||
int res = TRI_ERROR_NO_ERROR;
|
||||
for (std::string const& word : words) {
|
||||
RocksDBKey key =
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), docKey);
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), revisionId);
|
||||
|
||||
Result r = mthd->Delete(_cf, key);
|
||||
if (!r.ok()) {
|
||||
|
@ -276,15 +274,14 @@ int RocksDBFulltextIndex::remove(transaction::Methods* trx,
|
|||
return res;
|
||||
}
|
||||
|
||||
int RocksDBFulltextIndex::removeRaw(RocksDBMethods* batch, TRI_voc_rid_t,
|
||||
int RocksDBFulltextIndex::removeRaw(RocksDBMethods* batch, TRI_voc_rid_t revisionId,
|
||||
arangodb::velocypack::Slice const& doc) {
|
||||
std::set<std::string> words = wordlist(doc);
|
||||
// now we are going to construct the value to insert into rocksdb
|
||||
// unique indexes have a different key structure
|
||||
StringRef docKey(doc.get(StaticStrings::KeyString));
|
||||
for (std::string const& word : words) {
|
||||
RocksDBKey key =
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), docKey);
|
||||
RocksDBKey::FulltextIndexValue(_objectId, StringRef(word), revisionId);
|
||||
batch->Delete(_cf, key);
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
@ -462,7 +459,7 @@ Result RocksDBFulltextIndex::executeQuery(transaction::Methods* trx,
|
|||
FulltextQuery const& query,
|
||||
size_t maxResults,
|
||||
VPackBuilder& builder) {
|
||||
std::set<std::string> resultSet;
|
||||
std::set<TRI_voc_rid_t> resultSet;
|
||||
for (FulltextQueryToken const& token : query) {
|
||||
applyQueryToken(trx, token, resultSet);
|
||||
}
|
||||
|
@ -477,14 +474,12 @@ Result RocksDBFulltextIndex::executeQuery(transaction::Methods* trx,
|
|||
|
||||
builder.openArray();
|
||||
// get the first N results
|
||||
std::set<std::string>::iterator it = resultSet.cbegin();
|
||||
std::set<TRI_voc_rid_t>::iterator it = resultSet.cbegin();
|
||||
while (maxResults > 0 && it != resultSet.cend()) {
|
||||
RocksDBToken token = idx->lookupKey(trx, StringRef(*it));
|
||||
if (token.revisionId()) {
|
||||
if (physical->readDocument(trx, token, mmdr)) {
|
||||
mmdr.addToBuilder(builder, true);
|
||||
maxResults--;
|
||||
}
|
||||
RocksDBToken token(*it);
|
||||
if (token.revisionId() && physical->readDocument(trx, token, mmdr)) {
|
||||
mmdr.addToBuilder(builder, true);
|
||||
maxResults--;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
@ -505,7 +500,7 @@ static RocksDBKeyBounds MakeBounds(uint64_t oid,
|
|||
|
||||
Result RocksDBFulltextIndex::applyQueryToken(transaction::Methods* trx,
|
||||
FulltextQueryToken const& token,
|
||||
std::set<std::string>& resultSet) {
|
||||
std::set<TRI_voc_rid_t>& resultSet) {
|
||||
RocksDBMethods* mthds = rocksutils::toRocksMethods(trx);
|
||||
// why can't I have an assignment operator when I want one
|
||||
RocksDBKeyBounds bounds = MakeBounds(_objectId, token);
|
||||
|
@ -518,7 +513,7 @@ Result RocksDBFulltextIndex::applyQueryToken(transaction::Methods* trx,
|
|||
iter->Seek(bounds.start());
|
||||
|
||||
// set is used to perform an intersection with the result set
|
||||
std::set<std::string> intersect;
|
||||
std::set<TRI_voc_rid_t> intersect;
|
||||
// apply left to right logic, merging all current results with ALL previous
|
||||
while (iter->Valid() && cmp->Compare(iter->key(), end) < 0) {
|
||||
TRI_ASSERT(_objectId == RocksDBKey::objectId(iter->key()));
|
||||
|
@ -528,13 +523,13 @@ Result RocksDBFulltextIndex::applyQueryToken(transaction::Methods* trx,
|
|||
return rocksutils::convertStatus(s);
|
||||
}
|
||||
|
||||
StringRef key = RocksDBKey::primaryKey(iter->key());
|
||||
TRI_voc_rid_t revisionId = RocksDBKey::revisionId(iter->key());
|
||||
if (token.operation == FulltextQueryToken::AND) {
|
||||
intersect.insert(key.toString());
|
||||
intersect.insert(revisionId);
|
||||
} else if (token.operation == FulltextQueryToken::OR) {
|
||||
resultSet.insert(key.toString());
|
||||
resultSet.insert(revisionId);
|
||||
} else if (token.operation == FulltextQueryToken::EXCLUDE) {
|
||||
resultSet.erase(key.toString());
|
||||
resultSet.erase(revisionId);
|
||||
}
|
||||
iter->Next();
|
||||
}
|
||||
|
@ -542,7 +537,7 @@ Result RocksDBFulltextIndex::applyQueryToken(transaction::Methods* trx,
|
|||
if (resultSet.empty() || intersect.empty()) {
|
||||
resultSet.clear();
|
||||
} else {
|
||||
std::set<std::string> output;
|
||||
std::set<TRI_voc_rid_t> output;
|
||||
std::set_intersection(resultSet.begin(), resultSet.end(),
|
||||
intersect.begin(), intersect.end(),
|
||||
std::inserter(output, output.begin()));
|
||||
|
|
|
@ -141,7 +141,7 @@ class RocksDBFulltextIndex final : public RocksDBIndex {
|
|||
|
||||
arangodb::Result applyQueryToken(transaction::Methods* trx,
|
||||
FulltextQueryToken const&,
|
||||
std::set<std::string>& resultSet);
|
||||
std::set<TRI_voc_rid_t>& resultSet);
|
||||
};
|
||||
} // namespace arangodb
|
||||
|
||||
|
|
|
@ -164,6 +164,14 @@ TRI_voc_rid_t RocksDBKey::revisionId(rocksdb::Slice const& slice) {
|
|||
return revisionId(slice.data(), slice.size());
|
||||
}
|
||||
|
||||
arangodb::StringRef RocksDBKey::primaryKey(RocksDBKey const& key) {
|
||||
return primaryKey(key._buffer.data(), key._buffer.size());
|
||||
}
|
||||
|
||||
arangodb::StringRef RocksDBKey::primaryKey(rocksdb::Slice const& slice) {
|
||||
return primaryKey(slice.data(), slice.size());
|
||||
}
|
||||
|
||||
StringRef RocksDBKey::vertexId(RocksDBKey const& key) {
|
||||
return vertexId(key._buffer.data(), key._buffer.size());
|
||||
}
|
||||
|
@ -420,12 +428,19 @@ TRI_voc_rid_t RocksDBKey::revisionId(char const* data, size_t size) {
|
|||
TRI_ASSERT(size >= (sizeof(char) + (2 * sizeof(uint64_t))));
|
||||
return uint64FromPersistent(data + sizeof(char) + sizeof(uint64_t));
|
||||
}
|
||||
case RocksDBEntryType::EdgeIndexValue:
|
||||
case RocksDBEntryType::IndexValue:
|
||||
case RocksDBEntryType::FulltextIndexValue: {
|
||||
TRI_ASSERT(size >= (sizeof(char) + (2 * sizeof(uint64_t))));
|
||||
// last 8 bytes should by revision
|
||||
return uint64FromPersistent(data + size - sizeof(uint64_t));
|
||||
}
|
||||
|
||||
default:
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
arangodb::StringRef RocksDBKey::primaryKey(char const* data, size_t size) {
|
||||
TRI_ASSERT(data != nullptr);
|
||||
TRI_ASSERT(size >= sizeof(char));
|
||||
|
@ -437,19 +452,11 @@ arangodb::StringRef RocksDBKey::primaryKey(char const* data, size_t size) {
|
|||
return arangodb::StringRef(data + sizeof(char) + sizeof(uint64_t),
|
||||
keySize);
|
||||
}
|
||||
case RocksDBEntryType::EdgeIndexValue:
|
||||
case RocksDBEntryType::IndexValue:
|
||||
case RocksDBEntryType::FulltextIndexValue: {
|
||||
TRI_ASSERT(size > (sizeof(char) + sizeof(uint64_t) + sizeof(uint8_t)));
|
||||
size_t keySize = static_cast<size_t>(data[size - 1]);
|
||||
return arangodb::StringRef(data + (size - (keySize + sizeof(uint8_t))),
|
||||
keySize);
|
||||
}
|
||||
|
||||
default:
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
StringRef RocksDBKey::vertexId(char const* data, size_t size) {
|
||||
TRI_ASSERT(data != nullptr);
|
||||
|
|
|
@ -161,7 +161,6 @@ class RocksDBKey {
|
|||
return type(slice.data(), slice.size());
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Extracts the object id
|
||||
///
|
||||
|
@ -218,8 +217,8 @@ class RocksDBKey {
|
|||
/// May be called only on the following key types: PrimaryIndexValue,
|
||||
/// EdgeIndexValue, IndexValue, FulltextIndexValue. Other types will throw.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//static StringRef primaryKey(RocksDBKey const&);
|
||||
//static StringRef primaryKey(rocksdb::Slice const&);
|
||||
static StringRef primaryKey(RocksDBKey const&);
|
||||
static StringRef primaryKey(rocksdb::Slice const&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Extracts the vertex ID from a key
|
||||
|
@ -276,7 +275,7 @@ class RocksDBKey {
|
|||
static TRI_voc_cid_t objectId(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 StringRef primaryKey(char const* data, size_t size);
|
||||
static StringRef primaryKey(char const* data, size_t size);
|
||||
static StringRef vertexId(char const* data, size_t size);
|
||||
static VPackSlice indexedVPack(char const* data, size_t size);
|
||||
|
||||
|
|
|
@ -80,11 +80,10 @@ static std::vector<arangodb::basics::AttributeName> const KeyAttribute{
|
|||
RocksDBVPackIndexIterator::RocksDBVPackIndexIterator(
|
||||
LogicalCollection* collection, transaction::Methods* trx,
|
||||
ManagedDocumentResult* mmdr, arangodb::RocksDBVPackIndex const* index,
|
||||
arangodb::RocksDBPrimaryIndex* primaryIndex, bool reverse,
|
||||
bool reverse,
|
||||
VPackSlice const& left, VPackSlice const& right)
|
||||
: IndexIterator(collection, trx, mmdr, index),
|
||||
_index(index),
|
||||
_primaryIndex(primaryIndex),
|
||||
_cmp(index->comparator()),
|
||||
_reverse(reverse),
|
||||
_bounds(index->_unique ? RocksDBKeyBounds::UniqueIndexRange(
|
||||
|
@ -141,16 +140,11 @@ bool RocksDBVPackIndexIterator::next(TokenCallback const& cb, size_t limit) {
|
|||
while (limit > 0) {
|
||||
TRI_ASSERT(_index->objectId() == RocksDBKey::objectId(_iterator->key()));
|
||||
|
||||
|
||||
|
||||
StringRef primaryKey = _index->_unique
|
||||
? RocksDBValue::primaryKey(_iterator->value())
|
||||
: RocksDBKey::primaryKey(_iterator->key());
|
||||
RocksDBToken token(_primaryIndex->lookupKey(_trx, primaryKey));
|
||||
cb(token);
|
||||
TRI_voc_rid_t revisionId = _index->_unique ? RocksDBValue::revisionId(_iterator->value())
|
||||
: RocksDBKey::revisionId(_iterator->key());
|
||||
cb(RocksDBToken(revisionId));
|
||||
|
||||
--limit;
|
||||
|
||||
if (_reverse) {
|
||||
_iterator->Prev();
|
||||
} else {
|
||||
|
@ -309,7 +303,6 @@ int RocksDBVPackIndex::fillElement(VPackBuilder& leased,
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
StringRef key(doc.get(StaticStrings::KeyString));
|
||||
if (_unique) {
|
||||
// Unique VPack index values are stored as follows:
|
||||
// - Key: 7 + 8-byte object ID of index + VPack array with index
|
||||
|
@ -325,20 +318,21 @@ int RocksDBVPackIndex::fillElement(VPackBuilder& leased,
|
|||
// + separator (NUL) byte + primary key
|
||||
// - Value: empty
|
||||
elements.emplace_back(
|
||||
RocksDBKey::IndexValue(_objectId, key, leased.slice()));
|
||||
RocksDBKey::IndexValue(_objectId, leased.slice(), revisionId));
|
||||
hashes.push_back(leased.slice().normalizedHash());
|
||||
}
|
||||
} else {
|
||||
// other path for handling array elements, too
|
||||
|
||||
std::vector<VPackSlice> sliceStack;
|
||||
buildIndexValues(leased, doc, 0, elements, sliceStack, hashes);
|
||||
buildIndexValues(leased, revisionId, doc, 0, elements, sliceStack, hashes);
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
void RocksDBVPackIndex::addIndexValue(VPackBuilder& leased,
|
||||
TRI_voc_rid_t revisionId,
|
||||
VPackSlice const& document,
|
||||
std::vector<RocksDBKey>& elements,
|
||||
std::vector<VPackSlice>& sliceStack,
|
||||
|
@ -350,7 +344,6 @@ void RocksDBVPackIndex::addIndexValue(VPackBuilder& leased,
|
|||
}
|
||||
leased.close();
|
||||
|
||||
StringRef key(document.get(StaticStrings::KeyString));
|
||||
if (_unique) {
|
||||
// Unique VPack index values are stored as follows:
|
||||
// - Key: 7 + 8-byte object ID of index + VPack array with index value(s)
|
||||
|
@ -363,14 +356,15 @@ void RocksDBVPackIndex::addIndexValue(VPackBuilder& leased,
|
|||
// + primary key
|
||||
// - Value: empty
|
||||
elements.emplace_back(
|
||||
RocksDBKey::IndexValue(_objectId, key, leased.slice()));
|
||||
RocksDBKey::IndexValue(_objectId, leased.slice(), revisionId));
|
||||
hashes.push_back(leased.slice().normalizedHash());
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief helper function to create a set of index combinations to insert
|
||||
void RocksDBVPackIndex::buildIndexValues(VPackBuilder& leased,
|
||||
VPackSlice const document,
|
||||
TRI_voc_rid_t revisionId,
|
||||
VPackSlice const doc,
|
||||
size_t level,
|
||||
std::vector<RocksDBKey>& elements,
|
||||
std::vector<VPackSlice>& sliceStack,
|
||||
|
@ -379,12 +373,12 @@ void RocksDBVPackIndex::buildIndexValues(VPackBuilder& leased,
|
|||
|
||||
// Stop the recursion:
|
||||
if (level == _paths.size()) {
|
||||
addIndexValue(leased, document, elements, sliceStack, hashes);
|
||||
addIndexValue(leased, revisionId, doc, elements, sliceStack, hashes);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_expanding[level] == -1) { // the trivial, non-expanding case
|
||||
VPackSlice slice = document.get(_paths[level]);
|
||||
VPackSlice slice = doc.get(_paths[level]);
|
||||
if (slice.isNone() || slice.isNull()) {
|
||||
if (_sparse) {
|
||||
return;
|
||||
|
@ -393,7 +387,7 @@ void RocksDBVPackIndex::buildIndexValues(VPackBuilder& leased,
|
|||
} else {
|
||||
sliceStack.emplace_back(slice);
|
||||
}
|
||||
buildIndexValues(leased, document, level + 1, elements, sliceStack, hashes);
|
||||
buildIndexValues(leased, revisionId, doc, level + 1, elements, sliceStack, hashes);
|
||||
sliceStack.pop_back();
|
||||
return;
|
||||
}
|
||||
|
@ -414,14 +408,14 @@ void RocksDBVPackIndex::buildIndexValues(VPackBuilder& leased,
|
|||
for (size_t i = level; i < _paths.size(); i++) {
|
||||
sliceStack.emplace_back(illegalSlice);
|
||||
}
|
||||
addIndexValue(leased, document, elements, sliceStack, hashes);
|
||||
addIndexValue(leased, revisionId, doc, elements, sliceStack, hashes);
|
||||
for (size_t i = level; i < _paths.size(); i++) {
|
||||
sliceStack.pop_back();
|
||||
}
|
||||
};
|
||||
size_t const n = _paths[level].size();
|
||||
// We have 0 <= _expanding[level] < n.
|
||||
VPackSlice current(document);
|
||||
VPackSlice current(doc);
|
||||
for (size_t i = 0; i <= static_cast<size_t>(_expanding[level]); i++) {
|
||||
if (!current.isObject()) {
|
||||
finishWithNones();
|
||||
|
@ -449,7 +443,7 @@ void RocksDBVPackIndex::buildIndexValues(VPackBuilder& leased,
|
|||
if (it == seen.end()) {
|
||||
seen.insert(something);
|
||||
sliceStack.emplace_back(something);
|
||||
buildIndexValues(leased, document, level + 1, elements, sliceStack,
|
||||
buildIndexValues(leased, revisionId, doc, level + 1, elements, sliceStack,
|
||||
hashes);
|
||||
sliceStack.pop_back();
|
||||
}
|
||||
|
@ -528,8 +522,7 @@ int RocksDBVPackIndex::insert(transaction::Methods* trx,
|
|||
|
||||
// now we are going to construct the value to insert into rocksdb
|
||||
// unique indexes have a different key structure
|
||||
StringRef docKey(doc.get(StaticStrings::KeyString));
|
||||
RocksDBValue value = _unique ? RocksDBValue::UniqueIndexValue(docKey)
|
||||
RocksDBValue value = _unique ? RocksDBValue::UniqueIndexValue(revisionId)
|
||||
: RocksDBValue::IndexValue();
|
||||
|
||||
RocksDBMethods* mthds = rocksutils::toRocksMethods(trx);
|
||||
|
@ -596,8 +589,7 @@ int RocksDBVPackIndex::insertRaw(RocksDBMethods* batch,
|
|||
|
||||
// now we are going to construct the value to insert into rocksdb
|
||||
// unique indexes have a different key structure
|
||||
StringRef docKey(doc.get(StaticStrings::KeyString));
|
||||
RocksDBValue value = _unique ? RocksDBValue::UniqueIndexValue(docKey)
|
||||
RocksDBValue value = _unique ? RocksDBValue::UniqueIndexValue(revisionId)
|
||||
: RocksDBValue::IndexValue();
|
||||
|
||||
for (RocksDBKey const& key : elements) {
|
||||
|
@ -808,8 +800,7 @@ RocksDBVPackIndexIterator* RocksDBVPackIndex::lookup(
|
|||
// _collection at least as long as trx is running.
|
||||
// Same for the iterator
|
||||
auto physical = static_cast<RocksDBCollection*>(_collection->getPhysical());
|
||||
auto idx = physical->primaryIndex();
|
||||
return new RocksDBVPackIndexIterator(_collection, trx, mmdr, this, idx,
|
||||
return new RocksDBVPackIndexIterator(_collection, trx, mmdr, this,
|
||||
reverse, leftBorder, rightBorder);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ class RocksDBVPackIndexIterator final : public IndexIterator {
|
|||
transaction::Methods* trx,
|
||||
ManagedDocumentResult* mmdr,
|
||||
arangodb::RocksDBVPackIndex const* index,
|
||||
arangodb::RocksDBPrimaryIndex* primaryIndex,
|
||||
bool reverse,
|
||||
arangodb::velocypack::Slice const& left,
|
||||
arangodb::velocypack::Slice const& right);
|
||||
|
@ -88,7 +87,6 @@ class RocksDBVPackIndexIterator final : public IndexIterator {
|
|||
bool outOfRange() const;
|
||||
|
||||
arangodb::RocksDBVPackIndex const* _index;
|
||||
arangodb::RocksDBPrimaryIndex* _primaryIndex;
|
||||
rocksdb::Comparator const* _cmp;
|
||||
std::unique_ptr<rocksdb::Iterator> _iterator;
|
||||
bool const _reverse;
|
||||
|
@ -216,7 +214,8 @@ protected:
|
|||
/// @brief helper function to build the key and value for rocksdb from the
|
||||
/// vector of slices
|
||||
/// @param hashes list of VPackSlice hashes for the estimator.
|
||||
void addIndexValue(velocypack::Builder& leased, VPackSlice const& document,
|
||||
void addIndexValue(velocypack::Builder& leased, TRI_voc_rid_t revisionId,
|
||||
VPackSlice const& document,
|
||||
std::vector<RocksDBKey>& elements,
|
||||
std::vector<VPackSlice>& sliceStack,
|
||||
std::vector<uint64_t>& hashes);
|
||||
|
@ -226,7 +225,8 @@ protected:
|
|||
/// @param elements vector of resulting index entries
|
||||
/// @param sliceStack working list of values to insert into the index
|
||||
/// @param hashes list of VPackSlice hashes for the estimator.
|
||||
void buildIndexValues(velocypack::Builder& leased, VPackSlice const document,
|
||||
void buildIndexValues(velocypack::Builder& leased, TRI_voc_rid_t revisionId,
|
||||
VPackSlice const document,
|
||||
size_t level, std::vector<RocksDBKey>& elements,
|
||||
std::vector<VPackSlice>& sliceStack,
|
||||
std::vector<uint64_t>& hashes);
|
||||
|
|
|
@ -45,17 +45,16 @@ RocksDBValue RocksDBValue::PrimaryIndexValue(TRI_voc_rid_t revisionId) {
|
|||
return RocksDBValue(RocksDBEntryType::PrimaryIndexValue, revisionId);
|
||||
}
|
||||
|
||||
RocksDBValue RocksDBValue::EdgeIndexValue(TRI_voc_rid_t revisionId) {
|
||||
return RocksDBValue(RocksDBEntryType::EdgeIndexValue, revisionId);
|
||||
RocksDBValue RocksDBValue::EdgeIndexValue() {
|
||||
return RocksDBValue(RocksDBEntryType::EdgeIndexValue);
|
||||
}
|
||||
|
||||
RocksDBValue RocksDBValue::IndexValue(TRI_voc_rid_t revisionId) {
|
||||
return RocksDBValue(RocksDBEntryType::IndexValue, revisionId);
|
||||
RocksDBValue RocksDBValue::IndexValue() {
|
||||
return RocksDBValue(RocksDBEntryType::IndexValue);
|
||||
}
|
||||
|
||||
RocksDBValue RocksDBValue::UniqueIndexValue(TRI_voc_rid_t revisionId,
|
||||
StringRef const& primaryKey) {
|
||||
return RocksDBValue(RocksDBEntryType::UniqueIndexValue, revisionId, primaryKey);
|
||||
RocksDBValue RocksDBValue::UniqueIndexValue(TRI_voc_rid_t revisionId) {
|
||||
return RocksDBValue(RocksDBEntryType::UniqueIndexValue, revisionId);
|
||||
}
|
||||
|
||||
RocksDBValue RocksDBValue::View(VPackSlice const& data) {
|
||||
|
@ -111,8 +110,7 @@ RocksDBValue::RocksDBValue(RocksDBEntryType type) : _type(type), _buffer() {}
|
|||
RocksDBValue::RocksDBValue(RocksDBEntryType type, uint64_t data)
|
||||
: _type(type), _buffer() {
|
||||
switch (_type) {
|
||||
case RocksDBEntryType::EdgeIndexValue:
|
||||
case RocksDBEntryType::IndexValue:
|
||||
case RocksDBEntryType::UniqueIndexValue:
|
||||
case RocksDBEntryType::PrimaryIndexValue: {
|
||||
_buffer.reserve(sizeof(uint64_t));
|
||||
uint64ToPersistent(_buffer, data); // revision id
|
||||
|
@ -124,24 +122,6 @@ RocksDBValue::RocksDBValue(RocksDBEntryType type, uint64_t data)
|
|||
}
|
||||
}
|
||||
|
||||
RocksDBValue::RocksDBValue(RocksDBEntryType type,
|
||||
uint64_t rev,
|
||||
arangodb::StringRef const& data)
|
||||
: _type(type), _buffer() {
|
||||
switch (_type) {
|
||||
|
||||
case RocksDBEntryType::UniqueIndexValue: {
|
||||
_buffer.reserve(sizeof(uint64_t) + data.length());
|
||||
uint64ToPersistent(_buffer, rev); // revision id
|
||||
_buffer.append(data.data(), data.length()); // primary key
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
RocksDBValue::RocksDBValue(RocksDBEntryType type, VPackSlice const& data)
|
||||
: _type(type), _buffer() {
|
||||
switch (_type) {
|
||||
|
|
|
@ -49,10 +49,9 @@ class RocksDBValue {
|
|||
static RocksDBValue Collection(VPackSlice const& data);
|
||||
static RocksDBValue Document(VPackSlice const& data);
|
||||
static RocksDBValue PrimaryIndexValue(TRI_voc_rid_t revisionId);
|
||||
static RocksDBValue EdgeIndexValue(TRI_voc_rid_t revisionId);
|
||||
static RocksDBValue IndexValue(TRI_voc_rid_t revisionId);
|
||||
static RocksDBValue UniqueIndexValue(TRI_voc_rid_t revisionId,
|
||||
arangodb::StringRef const& primaryKey);
|
||||
static RocksDBValue EdgeIndexValue();
|
||||
static RocksDBValue IndexValue();
|
||||
static RocksDBValue UniqueIndexValue(TRI_voc_rid_t revisionId);
|
||||
static RocksDBValue View(VPackSlice const& data);
|
||||
static RocksDBValue ReplicationApplierConfig(VPackSlice const& data);
|
||||
|
||||
|
@ -111,7 +110,6 @@ class RocksDBValue {
|
|||
RocksDBValue();
|
||||
explicit RocksDBValue(RocksDBEntryType type);
|
||||
RocksDBValue(RocksDBEntryType type, uint64_t data);
|
||||
RocksDBValue(RocksDBEntryType type, uint64_t rev, StringRef const& data);
|
||||
RocksDBValue(RocksDBEntryType type, VPackSlice const& data);
|
||||
|
||||
private:
|
||||
|
|
|
@ -222,12 +222,11 @@ SECTION("test_primary_index") {
|
|||
|
||||
/// @brief test edge index
|
||||
SECTION("test_edge_index") {
|
||||
RocksDBKey key1 = RocksDBKey::EdgeIndexValue(0, StringRef("a/1"), StringRef("foobar"));
|
||||
RocksDBKey key1 = RocksDBKey::EdgeIndexValue(0, StringRef("a/1"), 33);
|
||||
auto const& s1 = key1.string();
|
||||
|
||||
CHECK(s1.size() == sizeof(char) + sizeof(uint64_t) + strlen("a/1") + sizeof(char) + strlen("foobar") + sizeof(char));
|
||||
CHECK(s1 == std::string("5\0\0\0\0\0\0\0\0a/1\0foobar\x06", 20));
|
||||
|
||||
CHECK(s1 == std::string("5\0\0\0\0\0\0\0\0a/1\0\0\0!\0\0\0\0", 20));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue