mirror of https://gitee.com/bigwinds/arangodb
move collection keys into engine
This commit is contained in:
parent
36ff459cfb
commit
63868b4378
|
@ -383,6 +383,7 @@ set(ARANGOD_SOURCES
|
|||
MMFiles/MMFilesCleanupThread.cpp
|
||||
MMFiles/MMFilesCollection.cpp
|
||||
MMFiles/MMFilesCollectionExport.cpp
|
||||
MMFiles/MMFilesCollectionKeys.cpp
|
||||
MMFiles/MMFilesCollectorThread.cpp
|
||||
MMFiles/MMFilesCompactorThread.cpp
|
||||
MMFiles/MMFilesDatafile.cpp
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "MMFilesCollectionKeys.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "Basics/StringRef.h"
|
||||
#include "MMFiles/MMFilesCollection.h"
|
||||
#include "MMFiles/MMFilesDitch.h"
|
||||
#include "MMFiles/MMFilesLogfileManager.h"
|
||||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
#include "StorageEngine/StorageEngine.h"
|
||||
#include "Transaction/Helpers.h"
|
||||
#include "Utils/CollectionGuard.h"
|
||||
#include "Utils/SingleCollectionTransaction.h"
|
||||
#include "Transaction/StandaloneContext.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Iterator.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb;
|
||||
|
||||
MMFilesCollectionKeys::MMFilesCollectionKeys(TRI_vocbase_t* vocbase, std::string const& name,
|
||||
TRI_voc_tick_t blockerId, double ttl)
|
||||
: CollectionKeys(vocbase, name, ttl),
|
||||
_ditch(nullptr),
|
||||
_resolver(vocbase),
|
||||
_blockerId(blockerId) {
|
||||
TRI_ASSERT(_blockerId > 0);
|
||||
|
||||
// prevent the collection from being unloaded while the export is ongoing
|
||||
// this may throw
|
||||
_guard.reset(new arangodb::CollectionGuard(vocbase, _name.c_str(), false));
|
||||
|
||||
_collection = _guard->collection();
|
||||
TRI_ASSERT(_collection != nullptr);
|
||||
}
|
||||
|
||||
MMFilesCollectionKeys::~MMFilesCollectionKeys() {
|
||||
// remove compaction blocker
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->removeCompactionBlocker(_vocbase, _blockerId);
|
||||
|
||||
if (_ditch != nullptr) {
|
||||
_ditch->ditches()->freeMMFilesDocumentDitch(_ditch, false);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initially creates the list of keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MMFilesCollectionKeys::create(TRI_voc_tick_t maxTick) {
|
||||
MMFilesLogfileManager::instance()->waitForCollectorQueue(
|
||||
_collection->cid(), 30.0);
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->preventCompaction(_collection->vocbase(), [this](TRI_vocbase_t* vocbase) {
|
||||
// create a ditch under the compaction lock
|
||||
_ditch = arangodb::MMFilesCollection::toMMFilesCollection(_collection)
|
||||
->ditches()
|
||||
->createMMFilesDocumentDitch(false, __FILE__, __LINE__);
|
||||
});
|
||||
|
||||
// now we either have a ditch or not
|
||||
if (_ditch == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
_vpack.reserve(16384);
|
||||
|
||||
// copy all document tokens into the result under the read-lock
|
||||
{
|
||||
SingleCollectionTransaction trx(
|
||||
transaction::StandaloneContext::Create(_collection->vocbase()), _name,
|
||||
AccessMode::Type::READ);
|
||||
|
||||
int res = trx.begin();
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
|
||||
ManagedDocumentResult mmdr;
|
||||
trx.invokeOnAllElements(
|
||||
_collection->name(), [this, &trx, &maxTick, &mmdr](DocumentIdentifierToken const& token) {
|
||||
if (_collection->readDocumentConditional(&trx, token, maxTick, mmdr)) {
|
||||
_vpack.emplace_back(mmdr.vpack());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
trx.finish(res);
|
||||
}
|
||||
|
||||
// now sort all document tokens without the read-lock
|
||||
std::sort(_vpack.begin(), _vpack.end(),
|
||||
[](uint8_t const* lhs, uint8_t const* rhs) -> bool {
|
||||
return (StringRef(transaction::helpers::extractKeyFromDocument(VPackSlice(lhs))) < StringRef(transaction::helpers::extractKeyFromDocument(VPackSlice(rhs))));
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashes a chunk of keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::tuple<std::string, std::string, uint64_t> MMFilesCollectionKeys::hashChunk(
|
||||
size_t from, size_t to) const {
|
||||
if (from >= _vpack.size() || to > _vpack.size() || from >= to ||
|
||||
to == 0) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
VPackSlice first(_vpack.at(from));
|
||||
VPackSlice last(_vpack.at(to - 1));
|
||||
|
||||
TRI_ASSERT(first.isObject());
|
||||
TRI_ASSERT(last.isObject());
|
||||
|
||||
uint64_t hash = 0x012345678;
|
||||
|
||||
for (size_t i = from; i < to; ++i) {
|
||||
VPackSlice current(_vpack.at(i));
|
||||
TRI_ASSERT(current.isObject());
|
||||
|
||||
// we can get away with the fast hash function here, as key values are
|
||||
// restricted to strings
|
||||
hash ^= transaction::helpers::extractKeyFromDocument(current).hashString();
|
||||
hash ^= transaction::helpers::extractRevSliceFromDocument(current).hash();
|
||||
}
|
||||
|
||||
return std::make_tuple(
|
||||
transaction::helpers::extractKeyFromDocument(first).copyString(),
|
||||
transaction::helpers::extractKeyFromDocument(last).copyString(),
|
||||
hash);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dumps keys into the result
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MMFilesCollectionKeys::dumpKeys(VPackBuilder& result, size_t chunk,
|
||||
size_t chunkSize) const {
|
||||
size_t from = chunk * chunkSize;
|
||||
size_t to = (chunk + 1) * chunkSize;
|
||||
|
||||
if (to > _vpack.size()) {
|
||||
to = _vpack.size();
|
||||
}
|
||||
|
||||
if (from >= _vpack.size() || from >= to || to == 0) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
for (size_t i = from; i < to; ++i) {
|
||||
VPackSlice current(_vpack.at(i));
|
||||
TRI_ASSERT(current.isObject());
|
||||
|
||||
result.openArray();
|
||||
result.add(current.get(StaticStrings::KeyString));
|
||||
result.add(current.get(StaticStrings::RevString));
|
||||
result.close();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dumps documents into the result
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MMFilesCollectionKeys::dumpDocs(arangodb::velocypack::Builder& result, size_t chunk,
|
||||
size_t chunkSize, VPackSlice const& ids) const {
|
||||
if (!ids.isArray()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
for (auto const& it : VPackArrayIterator(ids)) {
|
||||
if (!it.isNumber()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
size_t position = chunk * chunkSize + it.getNumber<size_t>();
|
||||
|
||||
if (position >= _vpack.size()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
VPackSlice current(_vpack.at(position));
|
||||
TRI_ASSERT(current.isObject());
|
||||
|
||||
result.add(current);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_MMFILES_MMFILES_COLLECTION_KEYS_H
|
||||
#define ARANGOD_MMFILES_MMFILES_COLLECTION_KEYS_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Utils/CollectionKeys.h"
|
||||
#include "Utils/CollectionNameResolver.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Slice.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
struct TRI_vocbase_t;
|
||||
|
||||
namespace arangodb {
|
||||
class CollectionGuard;
|
||||
class MMFilesDocumentDitch;
|
||||
|
||||
typedef TRI_voc_tick_t CollectionKeysId;
|
||||
|
||||
class MMFilesCollectionKeys final : public CollectionKeys {
|
||||
public:
|
||||
MMFilesCollectionKeys(MMFilesCollectionKeys const&) = delete;
|
||||
MMFilesCollectionKeys& operator=(MMFilesCollectionKeys const&) = delete;
|
||||
|
||||
MMFilesCollectionKeys(TRI_vocbase_t*, std::string const& name,
|
||||
TRI_voc_tick_t blockerId, double ttl);
|
||||
|
||||
~MMFilesCollectionKeys();
|
||||
|
||||
public:
|
||||
size_t count() const override {
|
||||
return _vpack.size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initially creates the list of keys
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void create(TRI_voc_tick_t) override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashes a chunk of keys
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::tuple<std::string, std::string, uint64_t> hashChunk(size_t,
|
||||
size_t) const override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dumps keys into the result
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void dumpKeys(arangodb::velocypack::Builder&, size_t, size_t) const override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dumps documents into the result
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void dumpDocs(arangodb::velocypack::Builder&, size_t, size_t,
|
||||
arangodb::velocypack::Slice const&) const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<arangodb::CollectionGuard> _guard;
|
||||
arangodb::MMFilesDocumentDitch* _ditch;
|
||||
arangodb::CollectionNameResolver _resolver;
|
||||
TRI_voc_tick_t _blockerId;
|
||||
std::vector<uint8_t const*> _vpack;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -34,6 +34,7 @@
|
|||
#include "GeneralServer/GeneralServer.h"
|
||||
#include "Indexes/Index.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "MMFiles/MMFilesCollectionKeys.h"
|
||||
#include "MMFiles/MMFilesLogfileManager.h"
|
||||
#include "MMFiles/mmfiles-replication-dump.h"
|
||||
#include "Replication/InitialSyncer.h"
|
||||
|
@ -44,7 +45,6 @@
|
|||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
#include "StorageEngine/StorageEngine.h"
|
||||
#include "Utils/CollectionGuard.h"
|
||||
#include "Utils/CollectionKeys.h"
|
||||
#include "Utils/CollectionKeysRepository.h"
|
||||
#include "Utils/CollectionNameResolver.h"
|
||||
#include "Utils/OperationOptions.h"
|
||||
|
@ -2348,7 +2348,7 @@ void RestReplicationHandler::handleCommandCreateKeys() {
|
|||
|
||||
// initialize a container with the keys
|
||||
auto keys =
|
||||
std::make_unique<CollectionKeys>(_vocbase, col->name(), id, 300.0);
|
||||
std::make_unique<MMFilesCollectionKeys>(_vocbase, col->name(), id, 300.0);
|
||||
|
||||
std::string const idString(std::to_string(keys->id()));
|
||||
|
||||
|
@ -2402,7 +2402,7 @@ void RestReplicationHandler::handleCommandGetKeys() {
|
|||
auto keysRepository = _vocbase->collectionKeys();
|
||||
TRI_ASSERT(keysRepository != nullptr);
|
||||
|
||||
auto collectionKeysId = static_cast<arangodb::CollectionKeysId>(
|
||||
auto collectionKeysId = static_cast<CollectionKeysId>(
|
||||
arangodb::basics::StringUtils::uint64(id));
|
||||
|
||||
auto collectionKeys = keysRepository->find(collectionKeysId);
|
||||
|
@ -2501,7 +2501,7 @@ void RestReplicationHandler::handleCommandFetchKeys() {
|
|||
auto keysRepository = _vocbase->collectionKeys();
|
||||
TRI_ASSERT(keysRepository != nullptr);
|
||||
|
||||
auto collectionKeysId = static_cast<arangodb::CollectionKeysId>(
|
||||
auto collectionKeysId = static_cast<CollectionKeysId>(
|
||||
arangodb::basics::StringUtils::uint64(id));
|
||||
|
||||
auto collectionKeys = keysRepository->find(collectionKeysId);
|
||||
|
@ -2563,7 +2563,7 @@ void RestReplicationHandler::handleCommandRemoveKeys() {
|
|||
auto keys = _vocbase->collectionKeys();
|
||||
TRI_ASSERT(keys != nullptr);
|
||||
|
||||
auto collectionKeysId = static_cast<arangodb::CollectionKeysId>(
|
||||
auto collectionKeysId = static_cast<CollectionKeysId>(
|
||||
arangodb::basics::StringUtils::uint64(id));
|
||||
bool found = keys->remove(collectionKeysId);
|
||||
|
||||
|
|
|
@ -22,35 +22,14 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CollectionKeys.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
#include "Basics/StringRef.h"
|
||||
#include "MMFiles/MMFilesLogfileManager.h" //TODO -- REMOVE
|
||||
#include "MMFiles/MMFilesCollection.h"
|
||||
#include "MMFiles/MMFilesDitch.h"
|
||||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
#include "StorageEngine/StorageEngine.h"
|
||||
#include "Transaction/Helpers.h"
|
||||
#include "Utils/CollectionGuard.h"
|
||||
#include "Utils/SingleCollectionTransaction.h"
|
||||
#include "Transaction/StandaloneContext.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/ticks.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Iterator.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb;
|
||||
|
||||
CollectionKeys::CollectionKeys(TRI_vocbase_t* vocbase, std::string const& name,
|
||||
TRI_voc_tick_t blockerId, double ttl)
|
||||
CollectionKeys::CollectionKeys(TRI_vocbase_t* vocbase, std::string const& name, double ttl)
|
||||
: _vocbase(vocbase),
|
||||
_collection(nullptr),
|
||||
_ditch(nullptr),
|
||||
_name(name),
|
||||
_resolver(vocbase),
|
||||
_blockerId(blockerId),
|
||||
_id(0),
|
||||
_ttl(ttl),
|
||||
_expires(0.0),
|
||||
|
@ -58,168 +37,4 @@ CollectionKeys::CollectionKeys(TRI_vocbase_t* vocbase, std::string const& name,
|
|||
_isUsed(false) {
|
||||
_id = TRI_NewTickServer();
|
||||
_expires = TRI_microtime() + _ttl;
|
||||
TRI_ASSERT(_blockerId > 0);
|
||||
|
||||
// prevent the collection from being unloaded while the export is ongoing
|
||||
// this may throw
|
||||
_guard.reset(new arangodb::CollectionGuard(vocbase, _name.c_str(), false));
|
||||
|
||||
_collection = _guard->collection();
|
||||
TRI_ASSERT(_collection != nullptr);
|
||||
}
|
||||
|
||||
CollectionKeys::~CollectionKeys() {
|
||||
// remove compaction blocker
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->removeCompactionBlocker(_vocbase, _blockerId);
|
||||
|
||||
if (_ditch != nullptr) {
|
||||
_ditch->ditches()->freeMMFilesDocumentDitch(_ditch, false);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initially creates the list of keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CollectionKeys::create(TRI_voc_tick_t maxTick) {
|
||||
MMFilesLogfileManager::instance()->waitForCollectorQueue(
|
||||
_collection->cid(), 30.0);
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->preventCompaction(_collection->vocbase(), [this](TRI_vocbase_t* vocbase) {
|
||||
// create a ditch under the compaction lock
|
||||
_ditch = arangodb::MMFilesCollection::toMMFilesCollection(_collection)
|
||||
->ditches()
|
||||
->createMMFilesDocumentDitch(false, __FILE__, __LINE__);
|
||||
});
|
||||
|
||||
// now we either have a ditch or not
|
||||
if (_ditch == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
_vpack.reserve(16384);
|
||||
|
||||
// copy all document tokens into the result under the read-lock
|
||||
{
|
||||
SingleCollectionTransaction trx(
|
||||
transaction::StandaloneContext::Create(_collection->vocbase()), _name,
|
||||
AccessMode::Type::READ);
|
||||
|
||||
int res = trx.begin();
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
|
||||
ManagedDocumentResult mmdr;
|
||||
trx.invokeOnAllElements(
|
||||
_collection->name(), [this, &trx, &maxTick, &mmdr](DocumentIdentifierToken const& token) {
|
||||
if (_collection->readDocumentConditional(&trx, token, maxTick, mmdr)) {
|
||||
_vpack.emplace_back(mmdr.vpack());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
trx.finish(res);
|
||||
}
|
||||
|
||||
// now sort all document tokens without the read-lock
|
||||
std::sort(_vpack.begin(), _vpack.end(),
|
||||
[](uint8_t const* lhs, uint8_t const* rhs) -> bool {
|
||||
return (StringRef(transaction::helpers::extractKeyFromDocument(VPackSlice(lhs))) < StringRef(transaction::helpers::extractKeyFromDocument(VPackSlice(rhs))));
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashes a chunk of keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::tuple<std::string, std::string, uint64_t> CollectionKeys::hashChunk(
|
||||
size_t from, size_t to) const {
|
||||
if (from >= _vpack.size() || to > _vpack.size() || from >= to ||
|
||||
to == 0) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
VPackSlice first(_vpack.at(from));
|
||||
VPackSlice last(_vpack.at(to - 1));
|
||||
|
||||
TRI_ASSERT(first.isObject());
|
||||
TRI_ASSERT(last.isObject());
|
||||
|
||||
uint64_t hash = 0x012345678;
|
||||
|
||||
for (size_t i = from; i < to; ++i) {
|
||||
VPackSlice current(_vpack.at(i));
|
||||
TRI_ASSERT(current.isObject());
|
||||
|
||||
// we can get away with the fast hash function here, as key values are
|
||||
// restricted to strings
|
||||
hash ^= transaction::helpers::extractKeyFromDocument(current).hashString();
|
||||
hash ^= transaction::helpers::extractRevSliceFromDocument(current).hash();
|
||||
}
|
||||
|
||||
return std::make_tuple(
|
||||
transaction::helpers::extractKeyFromDocument(first).copyString(),
|
||||
transaction::helpers::extractKeyFromDocument(last).copyString(),
|
||||
hash);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dumps keys into the result
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CollectionKeys::dumpKeys(VPackBuilder& result, size_t chunk,
|
||||
size_t chunkSize) const {
|
||||
size_t from = chunk * chunkSize;
|
||||
size_t to = (chunk + 1) * chunkSize;
|
||||
|
||||
if (to > _vpack.size()) {
|
||||
to = _vpack.size();
|
||||
}
|
||||
|
||||
if (from >= _vpack.size() || from >= to || to == 0) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
for (size_t i = from; i < to; ++i) {
|
||||
VPackSlice current(_vpack.at(i));
|
||||
TRI_ASSERT(current.isObject());
|
||||
|
||||
result.openArray();
|
||||
result.add(current.get(StaticStrings::KeyString));
|
||||
result.add(current.get(StaticStrings::RevString));
|
||||
result.close();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dumps documents into the result
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CollectionKeys::dumpDocs(arangodb::velocypack::Builder& result, size_t chunk,
|
||||
size_t chunkSize, VPackSlice const& ids) const {
|
||||
if (!ids.isArray()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
for (auto const& it : VPackArrayIterator(ids)) {
|
||||
if (!it.isNumber()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
size_t position = chunk * chunkSize + it.getNumber<size_t>();
|
||||
|
||||
if (position >= _vpack.size()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
VPackSlice current(_vpack.at(position));
|
||||
TRI_ASSERT(current.isObject());
|
||||
|
||||
result.add(current);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#define ARANGOD_UTILS_COLLECTION_KEYS_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Utils/CollectionNameResolver.h"
|
||||
#include "VocBase/ManagedDocumentResult.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
|
@ -40,8 +38,7 @@ namespace velocypack {
|
|||
class Slice;
|
||||
}
|
||||
|
||||
class CollectionGuard;
|
||||
class MMFilesDocumentDitch;
|
||||
class LogicalCollection;
|
||||
|
||||
typedef TRI_voc_tick_t CollectionKeysId;
|
||||
|
||||
|
@ -50,10 +47,10 @@ class CollectionKeys {
|
|||
CollectionKeys(CollectionKeys const&) = delete;
|
||||
CollectionKeys& operator=(CollectionKeys const&) = delete;
|
||||
|
||||
CollectionKeys(TRI_vocbase_t*, std::string const&, TRI_voc_tick_t,
|
||||
CollectionKeys(TRI_vocbase_t*, std::string const& name,
|
||||
double ttl);
|
||||
|
||||
~CollectionKeys();
|
||||
virtual ~CollectionKeys() = default;
|
||||
|
||||
public:
|
||||
CollectionKeysId id() const { return _id; }
|
||||
|
@ -81,50 +78,43 @@ class CollectionKeys {
|
|||
_isUsed = false;
|
||||
}
|
||||
|
||||
size_t count() const {
|
||||
return _vpack.size();
|
||||
}
|
||||
virtual size_t count() const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initially creates the list of keys
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void create(TRI_voc_tick_t);
|
||||
virtual void create(TRI_voc_tick_t) = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hashes a chunk of keys
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::tuple<std::string, std::string, uint64_t> hashChunk(size_t,
|
||||
size_t) const;
|
||||
virtual std::tuple<std::string, std::string, uint64_t> hashChunk(size_t,
|
||||
size_t) const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dumps keys into the result
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void dumpKeys(arangodb::velocypack::Builder&, size_t, size_t) const;
|
||||
virtual void dumpKeys(arangodb::velocypack::Builder&, size_t, size_t) const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dumps documents into the result
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void dumpDocs(arangodb::velocypack::Builder&, size_t, size_t,
|
||||
arangodb::velocypack::Slice const&) const;
|
||||
virtual void dumpDocs(arangodb::velocypack::Builder&, size_t, size_t,
|
||||
arangodb::velocypack::Slice const&) const = 0;
|
||||
|
||||
private:
|
||||
protected:
|
||||
TRI_vocbase_t* _vocbase;
|
||||
std::unique_ptr<arangodb::CollectionGuard> _guard;
|
||||
arangodb::LogicalCollection* _collection;
|
||||
arangodb::MMFilesDocumentDitch* _ditch;
|
||||
std::string const _name;
|
||||
arangodb::CollectionNameResolver _resolver;
|
||||
TRI_voc_tick_t _blockerId;
|
||||
CollectionKeysId _id;
|
||||
double _ttl;
|
||||
double _expires;
|
||||
bool _isDeleted;
|
||||
bool _isUsed;
|
||||
std::vector<uint8_t const*> _vpack;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CollectionKeysRepository.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Basics/MutexLocker.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
using namespace arangodb;
|
||||
|
|
Loading…
Reference in New Issue