diff --git a/arangod/MMFiles/MMFilesCollection.cpp b/arangod/MMFiles/MMFilesCollection.cpp index 2138e73a62..af391d58fc 100644 --- a/arangod/MMFiles/MMFilesCollection.cpp +++ b/arangod/MMFiles/MMFilesCollection.cpp @@ -167,7 +167,7 @@ int MMFilesCollection::OpenIteratorHandleDocumentMarker(TRI_df_marker_t const* m if (state->_trackKeys) { VPackValueLength length; char const* p = keySlice.getString(length); - collection->keyGenerator()->track(p, length); + physical->keyGenerator()->track(p, length); } ++state->_documents; @@ -262,7 +262,7 @@ int MMFilesCollection::OpenIteratorHandleDeletionMarker(TRI_df_marker_t const* m if (state->_trackKeys) { VPackValueLength length; char const* p = keySlice.getString(length); - collection->keyGenerator()->track(p, length); + physical->keyGenerator()->track(p, length); } ++state->_deletions; @@ -400,11 +400,13 @@ MMFilesCollection::MMFilesCollection(LogicalCollection* collection, VPackSlice c setCompactionStatus("compaction not yet started"); } -MMFilesCollection::MMFilesCollection(LogicalCollection* logical, PhysicalCollection* physical): - PhysicalCollection(logical, VPackSlice::emptyObjectSlice()), - _ditches(logical) -{ +MMFilesCollection::MMFilesCollection(LogicalCollection* logical, + PhysicalCollection* physical) + : PhysicalCollection(logical, VPackSlice::emptyObjectSlice()), + _ditches(logical) { + _keyOptions = VPackBuilder::clone(physical->keyOptions()).steal(); MMFilesCollection& mmfiles = *static_cast(physical); + _keyGenerator.reset(KeyGenerator::factory(mmfiles.keyOptions())); _initialCount = mmfiles._initialCount; _revisionError = mmfiles._revisionError; _lastRevision = mmfiles._lastRevision; diff --git a/arangod/MMFiles/MMFilesCollection.h b/arangod/MMFiles/MMFilesCollection.h index 34b50ceea0..ce64547a09 100644 --- a/arangod/MMFiles/MMFilesCollection.h +++ b/arangod/MMFiles/MMFilesCollection.h @@ -95,7 +95,7 @@ class MMFilesCollection final : public PhysicalCollection { _documents(0), _operations(0), _initialCount(-1), - _trackKeys(collection->keyGenerator()->trackKeys()) { + _trackKeys(collection->getPhysical()->keyGenerator()->trackKeys()) { TRI_ASSERT(collection != nullptr); TRI_ASSERT(trx != nullptr); } diff --git a/arangod/V8Server/v8-collection.cpp b/arangod/V8Server/v8-collection.cpp index aa51e303c7..00f3af2aad 100644 --- a/arangod/V8Server/v8-collection.cpp +++ b/arangod/V8Server/v8-collection.cpp @@ -1347,7 +1347,7 @@ static void JS_PropertiesVocbaseCol( result->Set(TRI_V8_ASCII_STRING("numberOfShards"), v8::Number::New(isolate, c->numberOfShards())); - auto keyOpts = info->keyOptions(); + auto keyOpts = info->getPhysical()->keyOptions(); if (keyOpts.isObject() && keyOpts.length() > 0) { TRI_GET_GLOBAL_STRING(KeyOptionsKey); result->Set(KeyOptionsKey, TRI_VPackToV8(isolate, keyOpts)->ToObject()); @@ -1452,7 +1452,7 @@ static void JS_PropertiesVocbaseCol( try { VPackBuilder optionsBuilder; optionsBuilder.openObject(); - collection->keyGenerator()->toVelocyPack(optionsBuilder); + collection->getPhysical()->keyGenerator()->toVelocyPack(optionsBuilder); optionsBuilder.close(); result->Set(KeyOptionsKey, TRI_VPackToV8(isolate, optionsBuilder.slice())->ToObject()); diff --git a/arangod/VocBase/LogicalCollection.cpp b/arangod/VocBase/LogicalCollection.cpp index a5bb550844..72c778a5e3 100644 --- a/arangod/VocBase/LogicalCollection.cpp +++ b/arangod/VocBase/LogicalCollection.cpp @@ -116,18 +116,6 @@ static std::string const ReadStringValue(VPackSlice info, } return Helper::getStringValue(info, name, def); } - -static std::shared_ptr const> -CopySliceValue(VPackSlice info, std::string const& name) { - if (!info.isObject()) { - return nullptr; - } - info = info.get(name); - if (info.isNone()) { - return nullptr; - } - return VPackBuilder::clone(info).steal(); -} } /// @brief This the "copy" constructor used in the cluster @@ -149,7 +137,6 @@ LogicalCollection::LogicalCollection(LogicalCollection const& other) _isSystem(other.isSystem()), _isVolatile(other.isVolatile()), _waitForSync(other.waitForSync()), - _keyOptions(other._keyOptions), _version(other._version), _indexBuckets(other.indexBuckets()), _indexes(), @@ -160,10 +147,7 @@ LogicalCollection::LogicalCollection(LogicalCollection const& other) _vocbase(other.vocbase()), _cleanupIndexes(0), _persistentIndexes(0), - _physical(other.getPhysical()->clone(this,other.getPhysical())), - _keyGenerator() { - _keyGenerator.reset(KeyGenerator::factory(other.keyOptions())); - + _physical(other.getPhysical()->clone(this, other.getPhysical())) { if (ServerState::instance()->isDBServer() || !ServerState::instance()->isRunningInCluster()) { _followers.reset(new FollowerInfo(this)); @@ -198,7 +182,6 @@ LogicalCollection::LogicalCollection(TRI_vocbase_t* vocbase, Helper::readBooleanValue(info, "isSystem", false)), _isVolatile(Helper::readBooleanValue(info, "isVolatile", false)), _waitForSync(Helper::readBooleanValue(info, "waitForSync", false)), - _keyOptions(CopySliceValue(info, "keyOptions")), _version(Helper::readNumericValue(info, "version", currentVersion())), _indexBuckets(Helper::readNumericValue( info, "indexBuckets", DatabaseFeature::defaultIndexBuckets())), @@ -209,8 +192,7 @@ LogicalCollection::LogicalCollection(TRI_vocbase_t* vocbase, _vocbase(vocbase), _cleanupIndexes(0), _persistentIndexes(0), - _physical(EngineSelectorFeature::ENGINE->createPhysicalCollection(this,info)), - _keyGenerator() { + _physical(EngineSelectorFeature::ENGINE->createPhysicalCollection(this,info)) { getPhysical()->setPath(ReadStringValue(info, "path", "")); if (!IsAllowedName(info)) { THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_NAME); @@ -332,8 +314,6 @@ LogicalCollection::LogicalCollection(TRI_vocbase_t* vocbase, "invalid number of shard keys"); } - _keyGenerator.reset(KeyGenerator::factory(info.get("keyOptions"))); - auto shardsSlice = info.get("shards"); if (shardsSlice.isObject()) { for (auto const& shardSlice : VPackObjectIterator(shardsSlice)) { @@ -649,14 +629,6 @@ std::unique_ptr const& LogicalCollection::followers() const { void LogicalCollection::setDeleted(bool newValue) { _isDeleted = newValue; } -// SECTION: Key Options -VPackSlice LogicalCollection::keyOptions() const { - if (_keyOptions == nullptr) { - return Helper::NullValue(); - } - return VPackSlice(_keyOptions->data()); -} - // SECTION: Indexes uint32_t LogicalCollection::indexBuckets() const { return _indexBuckets; } @@ -691,7 +663,14 @@ void LogicalCollection::getPropertiesVPack(VPackBuilder& result, bool translateC result.add("journalSize", VPackValue(getPhysical()->journalSize())); //MMFiles result.add("doCompact", VPackValue(getPhysical()->doCompact())); //MMFiles result.add("indexBuckets", VPackValue(_indexBuckets)); //MMFiles - + // MMFiles + if (getPhysical()->keyGenerator() != nullptr) { + result.add(VPackValue("keyOptions")); + result.openObject(); + getPhysical()->keyGenerator()->toVelocyPack(result); + result.close(); + } + result.add("replicationFactor", VPackValue(_replicationFactor)); if (!_distributeShardsLike.empty()) { if (translateCids) { @@ -705,13 +684,6 @@ void LogicalCollection::getPropertiesVPack(VPackBuilder& result, bool translateC } } - if (_keyGenerator != nullptr) { - result.add(VPackValue("keyOptions")); - result.openObject(); - _keyGenerator->toVelocyPack(result); - result.close(); - } - result.add(VPackValue("shardKeys")); result.openArray(); for (auto const& key : _shardKeys) { diff --git a/arangod/VocBase/LogicalCollection.h b/arangod/VocBase/LogicalCollection.h index 48c099c59a..574a0f16ef 100644 --- a/arangod/VocBase/LogicalCollection.h +++ b/arangod/VocBase/LogicalCollection.h @@ -54,7 +54,6 @@ struct DocumentIdentifierToken; class FollowerInfo; class Index; class IndexIterator; -class KeyGenerator; class ManagedDocumentResult; struct OperationOptions; class PhysicalCollection; @@ -171,15 +170,6 @@ class LogicalCollection { void setDeleted(bool); - // SECTION: Key Options - velocypack::Slice keyOptions() const; - - // Get a reference to this KeyGenerator. - // Caller is not allowed to free it. - inline KeyGenerator* keyGenerator() const { - return _keyGenerator.get(); - } - PhysicalCollection* getPhysical() const { return _physical.get(); } std::unique_ptr getAllIterator(transaction::Methods* trx, ManagedDocumentResult* mdr, bool reverse); @@ -375,11 +365,6 @@ private: bool const _isVolatile; bool _waitForSync; - // SECTION: Key Options - // TODO Really VPack? - std::shared_ptr const> - _keyOptions; // options for key creation - uint32_t _version; // SECTION: Indexes @@ -410,8 +395,6 @@ private: std::unique_ptr _physical; - std::unique_ptr _keyGenerator; - mutable basics::ReadWriteLock _lock; // lock protecting the status and name diff --git a/arangod/VocBase/PhysicalCollection.cpp b/arangod/VocBase/PhysicalCollection.cpp index c8b3a1f918..4be17fa0ba 100644 --- a/arangod/VocBase/PhysicalCollection.cpp +++ b/arangod/VocBase/PhysicalCollection.cpp @@ -25,6 +25,7 @@ #include "Basics/encoding.h" #include "Basics/StaticStrings.h" +#include "Basics/VelocyPackHelper.h" #include "StorageEngine/TransactionState.h" #include "Transaction/Methods.h" #include "VocBase/KeyGenerator.h" @@ -40,6 +41,17 @@ using namespace arangodb; +PhysicalCollection::PhysicalCollection(LogicalCollection* collection, + VPackSlice const& info) + : _logicalCollection(collection), _keyOptions(nullptr), _keyGenerator() { + TRI_ASSERT(info.isObject()); + auto keyOpts = info.get("keyOptions"); + + _keyGenerator.reset(KeyGenerator::factory(keyOpts)); + if (!keyOpts.isNone()) { + _keyOptions = VPackBuilder::clone(keyOpts).steal(); + } +} void PhysicalCollection::figures(std::shared_ptr& builder){ this->figuresSpecific(builder); @@ -192,8 +204,7 @@ int PhysicalCollection::newObjectForInsert( if (s.isNone()) { TRI_ASSERT(!isRestore); // need key in case of restore newRev = TRI_HybridLogicalClock(); - std::string keyString = - _logicalCollection->keyGenerator()->generate(TRI_NewTickServer()); + std::string keyString = keyGenerator()->generate(TRI_NewTickServer()); if (keyString.empty()) { return TRI_ERROR_ARANGO_OUT_OF_KEYS; } @@ -204,8 +215,7 @@ int PhysicalCollection::newObjectForInsert( return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD; } else { std::string keyString = s.copyString(); - int res = - _logicalCollection->keyGenerator()->validate(keyString, isRestore); + int res = keyGenerator()->validate(keyString, isRestore); if (res != TRI_ERROR_NO_ERROR) { return res; } @@ -332,3 +342,11 @@ int PhysicalCollection::checkRevision(transaction::Methods* trx, } return TRI_ERROR_NO_ERROR; } + +// SECTION: Key Options +VPackSlice PhysicalCollection::keyOptions() const { + if (_keyOptions == nullptr) { + return arangodb::basics::VelocyPackHelper::NullValue(); + } + return VPackSlice(_keyOptions->data()); +} diff --git a/arangod/VocBase/PhysicalCollection.h b/arangod/VocBase/PhysicalCollection.h index 347bc0eff8..04f4e5356b 100644 --- a/arangod/VocBase/PhysicalCollection.h +++ b/arangod/VocBase/PhysicalCollection.h @@ -40,13 +40,15 @@ class Methods; struct DocumentIdentifierToken; class Index; class IndexIterator; +class KeyGenerator; class LogicalCollection; class ManagedDocumentResult; struct OperationOptions; class PhysicalCollection { protected: - explicit PhysicalCollection(LogicalCollection* collection, VPackSlice const& info) : _logicalCollection(collection) {} + PhysicalCollection(LogicalCollection* collection, + arangodb::velocypack::Slice const& info); public: virtual ~PhysicalCollection() = default; @@ -165,6 +167,16 @@ class PhysicalCollection { TRI_voc_tick_t& resultMarkerTick, bool lock, TRI_voc_rid_t const& revisionId, TRI_voc_rid_t& prevRev) = 0; + // Get a reference to this KeyGenerator. + // Caller is not allowed to free it. + inline KeyGenerator* keyGenerator() const { + return _keyGenerator.get(); + } + + // SECTION: Key Options + velocypack::Slice keyOptions() const; + + protected: // SECTION: Document pre commit preperation @@ -206,6 +218,15 @@ class PhysicalCollection { protected: LogicalCollection* _logicalCollection; + + // SECTION: Key Options + // TODO Really VPack? + std::shared_ptr const> + _keyOptions; // options for key creation + + + std::unique_ptr _keyGenerator; + }; } // namespace arangodb