From f17ff29518ca3da4cff50b2cf9d81e7f0139473f Mon Sep 17 00:00:00 2001 From: jsteemann Date: Thu, 23 Mar 2017 15:24:00 +0100 Subject: [PATCH] added stubs for indexes --- arangod/CMakeLists.txt | 27 ++- arangod/Indexes/IndexFactory.h | 42 ++-- arangod/MMFiles/MMFilesCleanupThread.h | 4 +- arangod/MMFiles/MMFilesCollection.cpp | 9 +- arangod/MMFiles/MMFilesCollection.h | 7 +- arangod/MMFiles/MMFilesCompactorThread.h | 5 +- arangod/MMFiles/MMFilesDatafile.h | 4 +- arangod/MMFiles/MMFilesDatafileHelper.h | 4 +- arangod/MMFiles/MMFilesDocumentOperation.h | 1 - arangod/MMFiles/MMFilesDocumentPosition.h | 4 +- arangod/MMFiles/MMFilesEdgeIndex.h | 4 +- arangod/MMFiles/MMFilesEngine.h | 4 +- arangod/MMFiles/MMFilesIndexFactory.h | 30 +-- arangod/MMFiles/MMFilesPrimaryIndex.h | 1 - arangod/MMFiles/MMFilesRevisionsCache.h | 4 +- arangod/MMFiles/MMFilesView.h | 4 +- arangod/MMFiles/MMFilesWalMarker.h | 4 +- arangod/RocksDBEngine/RocksDBCollection.cpp | 123 ++++++++++- arangod/RocksDBEngine/RocksDBCollection.h | 11 +- arangod/RocksDBEngine/RocksDBEdgeIndex.cpp | 205 ++++++++++++++++++ arangod/RocksDBEngine/RocksDBEdgeIndex.h | 122 +++++++++++ arangod/RocksDBEngine/RocksDBEngine.cpp | 4 +- arangod/RocksDBEngine/RocksDBEngine.h | 4 +- arangod/RocksDBEngine/RocksDBIndexFactory.cpp | 96 +++++++- arangod/RocksDBEngine/RocksDBIndexFactory.h | 30 +-- arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp | 189 ++++++++++++++++ arangod/RocksDBEngine/RocksDBPrimaryIndex.h | 157 ++++++++++++++ .../RocksDBTransactionCollection.h | 1 - arangod/RocksDBEngine/RocksDBView.h | 4 +- 29 files changed, 987 insertions(+), 117 deletions(-) create mode 100644 arangod/RocksDBEngine/RocksDBEdgeIndex.cpp create mode 100644 arangod/RocksDBEngine/RocksDBEdgeIndex.h create mode 100644 arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp create mode 100644 arangod/RocksDBEngine/RocksDBPrimaryIndex.h diff --git a/arangod/CMakeLists.txt b/arangod/CMakeLists.txt index d5dc42ec80..53aa54da56 100644 --- a/arangod/CMakeLists.txt +++ b/arangod/CMakeLists.txt @@ -276,16 +276,6 @@ SET(ARANGOD_SOURCES RestServer/ViewTypesFeature.cpp RestServer/VocbaseContext.cpp RestServer/WorkMonitorFeature.cpp - RocksDBEngine/RocksDBCollection.cpp - RocksDBEngine/RocksDBComparator.cpp - RocksDBEngine/RocksDBEngine.cpp - RocksDBEngine/RocksDBEntry.cpp - RocksDBEngine/RocksDBIndexFactory.cpp - RocksDBEngine/RocksDBTransactionCollection.cpp - RocksDBEngine/RocksDBTransactionContextData.cpp - RocksDBEngine/RocksDBTransactionState.cpp - RocksDBEngine/RocksDBTypes.cpp - RocksDBEngine/RocksDBView.cpp Scheduler/Acceptor.cpp Scheduler/AcceptorTcp.cpp Scheduler/Job.cpp @@ -436,6 +426,23 @@ set(ARANGOD_SOURCES MMFiles/MMFilesWalSlots.cpp MMFiles/mmfiles-replication-dump.cpp ) + +# add sources for rocksdb engine +set(ARANGOD_SOURCES + ${ARANGOD_SOURCES} + RocksDBEngine/RocksDBCollection.cpp + RocksDBEngine/RocksDBComparator.cpp + RocksDBEngine/RocksDBEdgeIndex.cpp + RocksDBEngine/RocksDBEngine.cpp + RocksDBEngine/RocksDBEntry.cpp + RocksDBEngine/RocksDBIndexFactory.cpp + RocksDBEngine/RocksDBPrimaryIndex.cpp + RocksDBEngine/RocksDBTransactionCollection.cpp + RocksDBEngine/RocksDBTransactionContextData.cpp + RocksDBEngine/RocksDBTransactionState.cpp + RocksDBEngine/RocksDBTypes.cpp + RocksDBEngine/RocksDBView.cpp +) if (NOT MSVC) set(ARANGOD_SOURCES ${ARANGOD_SOURCES} Scheduler/AcceptorUnixDomain.cpp Scheduler/SocketUnixDomain.cpp) diff --git a/arangod/Indexes/IndexFactory.h b/arangod/Indexes/IndexFactory.h index 4e0c8f48eb..248be886fb 100644 --- a/arangod/Indexes/IndexFactory.h +++ b/arangod/Indexes/IndexFactory.h @@ -28,32 +28,34 @@ namespace arangodb { - class Index; - class LogicalCollection; +class Index; +class LogicalCollection; - namespace velocypack { - class Builder; - class Slice; - } +namespace velocypack { + class Builder; + class Slice; +} - class IndexFactory { - public: - IndexFactory() {} +class IndexFactory { + public: + IndexFactory() = default; + IndexFactory(IndexFactory const&) = delete; + IndexFactory& operator=(IndexFactory const&) = delete; - virtual ~IndexFactory() {} + virtual ~IndexFactory() = default; - virtual int enhanceIndexDefinition( - arangodb::velocypack::Slice const definition, - arangodb::velocypack::Builder& enhanced, bool isCreation) const = 0; + virtual int enhanceIndexDefinition( + arangodb::velocypack::Slice const definition, + arangodb::velocypack::Builder& enhanced, bool isCreation) const = 0; - virtual std::shared_ptr prepareIndexFromSlice( - arangodb::velocypack::Slice info, bool generateKey, - arangodb::LogicalCollection* col, bool isClusterConstructor) const = 0; + virtual std::shared_ptr prepareIndexFromSlice( + arangodb::velocypack::Slice info, bool generateKey, + arangodb::LogicalCollection* col, bool isClusterConstructor) const = 0; - virtual void fillSystemIndexes( - arangodb::LogicalCollection* col, - std::vector>& systemIndexes) const = 0; - }; + virtual void fillSystemIndexes( + arangodb::LogicalCollection* col, + std::vector>& systemIndexes) const = 0; +}; } // namespace arangodb diff --git a/arangod/MMFiles/MMFilesCleanupThread.h b/arangod/MMFiles/MMFilesCleanupThread.h index e2678cb985..19aa040c06 100644 --- a/arangod/MMFiles/MMFilesCleanupThread.h +++ b/arangod/MMFiles/MMFilesCleanupThread.h @@ -21,8 +21,8 @@ /// @author Dr. Frank Celler //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MM_FILES_CLEANUP_THREAD_H -#define ARANGOD_STORAGE_ENGINE_MM_FILES_CLEANUP_THREAD_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_CLEANUP_THREAD_H +#define ARANGOD_MMFILES_MMFILES_CLEANUP_THREAD_H 1 #include "Basics/Common.h" #include "Basics/ConditionVariable.h" diff --git a/arangod/MMFiles/MMFilesCollection.cpp b/arangod/MMFiles/MMFilesCollection.cpp index 04e8bc6a71..a95b1b316a 100644 --- a/arangod/MMFiles/MMFilesCollection.cpp +++ b/arangod/MMFiles/MMFilesCollection.cpp @@ -1880,7 +1880,7 @@ void MMFilesCollection::prepareIndexes(VPackSlice indexesSlice) { } if (ServerState::instance()->isRunningInCluster()) { - addIndexCoordinator(idx, false); + addIndexCoordinator(idx); } else { addIndex(idx); } @@ -1966,7 +1966,7 @@ std::shared_ptr MMFilesCollection::createIndex(transaction::Methods* trx, if (ServerState::instance()->isCoordinator()) { // In the coordinator case we do not fill the index // We only inform the others. - addIndexCoordinator(idx, true); + addIndexCoordinator(idx); created = true; return idx; } @@ -2075,7 +2075,7 @@ void MMFilesCollection::addIndex(std::shared_ptr idx) { } void MMFilesCollection::addIndexCoordinator( - std::shared_ptr idx, bool distribute) { + std::shared_ptr idx) { auto const id = idx->id(); for (auto const& it : _indexes) { if (it->id() == id) { @@ -2085,9 +2085,6 @@ void MMFilesCollection::addIndexCoordinator( } _indexes.emplace_back(idx); - if (distribute) { - THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED); - } } int MMFilesCollection::restoreIndex(transaction::Methods* trx, diff --git a/arangod/MMFiles/MMFilesCollection.h b/arangod/MMFiles/MMFilesCollection.h index 835cbb88ce..fea0a65207 100644 --- a/arangod/MMFiles/MMFilesCollection.h +++ b/arangod/MMFiles/MMFilesCollection.h @@ -21,8 +21,8 @@ /// @author Dr. Frank Celler //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MM_FILES_COLLECTION_H -#define ARANGOD_STORAGE_ENGINE_MM_FILES_COLLECTION_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_COLLECTION_H +#define ARANGOD_MMFILES_MMFILES_COLLECTION_H 1 #include "Basics/Common.h" #include "Basics/ReadWriteLock.h" @@ -461,8 +461,7 @@ class MMFilesCollection final : public PhysicalCollection { void addIndex(std::shared_ptr idx); - void addIndexCoordinator(std::shared_ptr idx, - bool distribute); + void addIndexCoordinator(std::shared_ptr idx); bool removeIndex(TRI_idx_iid_t iid); diff --git a/arangod/MMFiles/MMFilesCompactorThread.h b/arangod/MMFiles/MMFilesCompactorThread.h index 5ef2030b6b..abdddc58fd 100644 --- a/arangod/MMFiles/MMFilesCompactorThread.h +++ b/arangod/MMFiles/MMFilesCompactorThread.h @@ -21,8 +21,8 @@ /// @author Dr. Frank Celler //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MM_FILES_COMPACTOR_THREAD_H -#define ARANGOD_STORAGE_ENGINE_MM_FILES_COMPACTOR_THREAD_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_COMPACTOR_THREAD_H +#define ARANGOD_MMFILES_MMFILES_COMPACTOR_THREAD_H 1 #include "Basics/Common.h" #include "Basics/ConditionVariable.h" @@ -39,7 +39,6 @@ class LogicalCollection; namespace transaction { class Methods; } -; class MMFilesCompactorThread final : public Thread { private: diff --git a/arangod/MMFiles/MMFilesDatafile.h b/arangod/MMFiles/MMFilesDatafile.h index 649da0f7a7..b4c25108e6 100644 --- a/arangod/MMFiles/MMFilesDatafile.h +++ b/arangod/MMFiles/MMFilesDatafile.h @@ -21,8 +21,8 @@ /// @author Dr. Frank Celler //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MMFILES_DATAFILE_H -#define ARANGOD_STORAGE_ENGINE_MMFILES_DATAFILE_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_DATAFILE_H +#define ARANGOD_MMFILES_MMFILES_DATAFILE_H 1 #include "Basics/Common.h" #include "VocBase/vocbase.h" diff --git a/arangod/MMFiles/MMFilesDatafileHelper.h b/arangod/MMFiles/MMFilesDatafileHelper.h index bb4613a822..5d96ba8b97 100644 --- a/arangod/MMFiles/MMFilesDatafileHelper.h +++ b/arangod/MMFiles/MMFilesDatafileHelper.h @@ -21,8 +21,8 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MMFILES_DATAFILE_HELPER_H -#define ARANGOD_STORAGE_ENGINE_MMFILES_DATAFILE_HELPER_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_DATAFILE_HELPER_H +#define ARANGOD_MMFILES_MMFILES_DATAFILE_HELPER_H 1 #include "Basics/Common.h" #include "Basics/encoding.h" diff --git a/arangod/MMFiles/MMFilesDocumentOperation.h b/arangod/MMFiles/MMFilesDocumentOperation.h index c04014a37c..73bdadabea 100644 --- a/arangod/MMFiles/MMFilesDocumentOperation.h +++ b/arangod/MMFiles/MMFilesDocumentOperation.h @@ -32,7 +32,6 @@ class LogicalCollection; namespace transaction { class Methods; } -; struct MMFilesDocumentOperation { enum class StatusType : uint8_t { diff --git a/arangod/MMFiles/MMFilesDocumentPosition.h b/arangod/MMFiles/MMFilesDocumentPosition.h index b01785f33d..593d7e87e7 100644 --- a/arangod/MMFiles/MMFilesDocumentPosition.h +++ b/arangod/MMFiles/MMFilesDocumentPosition.h @@ -21,8 +21,8 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MMFILES_DOCUMENT_POSITION_H -#define ARANGOD_STORAGE_ENGINE_MMFILES_DOCUMENT_POSITION_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_DOCUMENT_POSITION_H +#define ARANGOD_MMFILES_MMFILES_DOCUMENT_POSITION_H 1 #include "Basics/Common.h" #include "MMFiles/MMFilesDatafileHelper.h" diff --git a/arangod/MMFiles/MMFilesEdgeIndex.h b/arangod/MMFiles/MMFilesEdgeIndex.h index 57c1d1ea1d..6425c0a81d 100644 --- a/arangod/MMFiles/MMFilesEdgeIndex.h +++ b/arangod/MMFiles/MMFilesEdgeIndex.h @@ -21,8 +21,8 @@ /// @author Dr. Frank Celler //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_MMFILES_EDGE_INDEX_H -#define ARANGOD_MMFILES_EDGE_INDEX_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_EDGE_INDEX_H +#define ARANGOD_MMFILES_MMFILES_EDGE_INDEX_H 1 #include "Basics/AssocMulti.h" #include "Basics/Common.h" diff --git a/arangod/MMFiles/MMFilesEngine.h b/arangod/MMFiles/MMFilesEngine.h index 89c45bc4f2..1921cac73d 100644 --- a/arangod/MMFiles/MMFilesEngine.h +++ b/arangod/MMFiles/MMFilesEngine.h @@ -22,8 +22,8 @@ /// @author Jan Christoph Uhde //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MMFILES_ENGINE_H -#define ARANGOD_STORAGE_ENGINE_MMFILES_ENGINE_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_ENGINE_H +#define ARANGOD_MMFILES_MMFILES_ENGINE_H 1 #include "Basics/Common.h" #include "Basics/Mutex.h" diff --git a/arangod/MMFiles/MMFilesIndexFactory.h b/arangod/MMFiles/MMFilesIndexFactory.h index 0367895de6..cdd1053d05 100644 --- a/arangod/MMFiles/MMFilesIndexFactory.h +++ b/arangod/MMFiles/MMFilesIndexFactory.h @@ -28,25 +28,25 @@ namespace arangodb { - class MMFilesIndexFactory : public IndexFactory { - public: - MMFilesIndexFactory() : IndexFactory() { - } +class MMFilesIndexFactory final : public IndexFactory { + public: + MMFilesIndexFactory() : IndexFactory() {} - ~MMFilesIndexFactory() override {} + ~MMFilesIndexFactory() {} - int enhanceIndexDefinition( - arangodb::velocypack::Slice const definition, - arangodb::velocypack::Builder& enhanced, bool isCreation) const override; + int enhanceIndexDefinition( + arangodb::velocypack::Slice const definition, + arangodb::velocypack::Builder& enhanced, bool isCreation) const override; - std::shared_ptr prepareIndexFromSlice( - arangodb::velocypack::Slice info, bool generateKey, - LogicalCollection* col, bool isClusterConstructor) const override; + std::shared_ptr prepareIndexFromSlice( + arangodb::velocypack::Slice info, bool generateKey, + LogicalCollection* col, bool isClusterConstructor) const override; + + void fillSystemIndexes(arangodb::LogicalCollection* col, + std::vector>& + systemIndexes) const override; +}; - void fillSystemIndexes(arangodb::LogicalCollection* col, - std::vector>& - systemIndexes) const override; - }; } #endif diff --git a/arangod/MMFiles/MMFilesPrimaryIndex.h b/arangod/MMFiles/MMFilesPrimaryIndex.h index ffb123ea59..024a63e9f8 100644 --- a/arangod/MMFiles/MMFilesPrimaryIndex.h +++ b/arangod/MMFiles/MMFilesPrimaryIndex.h @@ -42,7 +42,6 @@ struct MMFilesSimpleIndexElement; namespace transaction { class Methods; } -; typedef arangodb::basics::AssocUnique MMFilesPrimaryIndexImpl; diff --git a/arangod/MMFiles/MMFilesRevisionsCache.h b/arangod/MMFiles/MMFilesRevisionsCache.h index 378c541a58..b714d85f03 100644 --- a/arangod/MMFiles/MMFilesRevisionsCache.h +++ b/arangod/MMFiles/MMFilesRevisionsCache.h @@ -21,8 +21,8 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MMFILES_REVISIONS_CACHE_H -#define ARANGOD_STORAGE_ENGINE_MMFILES_REVISIONS_CACHE_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_REVISIONS_CACHE_H +#define ARANGOD_MMFILES_MMFILES_REVISIONS_CACHE_H 1 #include "Basics/Common.h" #include "Basics/AssocUnique.h" diff --git a/arangod/MMFiles/MMFilesView.h b/arangod/MMFiles/MMFilesView.h index b4dc7bfe18..419e03d483 100644 --- a/arangod/MMFiles/MMFilesView.h +++ b/arangod/MMFiles/MMFilesView.h @@ -21,8 +21,8 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MM_FILES_VIEW_H -#define ARANGOD_STORAGE_ENGINE_MM_FILES_VIEW_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_VIEW_H +#define ARANGOD_MMFILES_MMFILES_VIEW_H 1 #include "Basics/Common.h" #include "Basics/ReadWriteLock.h" diff --git a/arangod/MMFiles/MMFilesWalMarker.h b/arangod/MMFiles/MMFilesWalMarker.h index e9e107086f..9e2b10dc80 100644 --- a/arangod/MMFiles/MMFilesWalMarker.h +++ b/arangod/MMFiles/MMFilesWalMarker.h @@ -21,8 +21,8 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MMFILES_WAL_MARKER_H -#define ARANGOD_STORAGE_ENGINE_MMFILES_WAL_MARKER_H 1 +#ifndef ARANGOD_MMFILES_MMFILES_WAL_MARKER_H +#define ARANGOD_MMFILES_MMFILES_WAL_MARKER_H 1 #include "Basics/Common.h" #include "Basics/encoding.h" diff --git a/arangod/RocksDBEngine/RocksDBCollection.cpp b/arangod/RocksDBEngine/RocksDBCollection.cpp index 0a00e187e5..fb45460943 100644 --- a/arangod/RocksDBEngine/RocksDBCollection.cpp +++ b/arangod/RocksDBEngine/RocksDBCollection.cpp @@ -1,8 +1,38 @@ -#include "RocksDBCollection.h" -#include -#include +//////////////////////////////////////////////////////////////////////////////// +/// 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-Christoph Uhde +//////////////////////////////////////////////////////////////////////////////// + +#include "Basics/Result.h" +#include "Basics/VelocyPackHelper.h" +#include "Indexes/Index.h" #include "Indexes/IndexIterator.h" +#include "RocksDBCollection.h" +#include "StorageEngine/EngineSelectorFeature.h" +#include "StorageEngine/StorageEngine.h" #include "VocBase/LogicalCollection.h" +#include "VocBase/ticks.h" + +#include +#include using namespace arangodb; @@ -104,7 +134,44 @@ bool RocksDBCollection::isFullyCollected() const { void RocksDBCollection::prepareIndexes( arangodb::velocypack::Slice indexesSlice) { - THROW_ARANGO_NOT_IMPLEMENTED(); + createInitialIndexes(); + if (indexesSlice.isArray()) { + StorageEngine* engine = EngineSelectorFeature::ENGINE; + IndexFactory const* idxFactory = engine->indexFactory(); + TRI_ASSERT(idxFactory != nullptr); + for (auto const& v : VPackArrayIterator(indexesSlice)) { + if (arangodb::basics::VelocyPackHelper::getBooleanValue(v, "error", + false)) { + // We have an error here. + // Do not add index. + // TODO Handle Properly + continue; + } + + auto idx = + idxFactory->prepareIndexFromSlice(v, false, _logicalCollection, true); + + if (idx->type() == Index::TRI_IDX_TYPE_PRIMARY_INDEX || + idx->type() == Index::TRI_IDX_TYPE_EDGE_INDEX) { + continue; + } + + if (ServerState::instance()->isRunningInCluster()) { + addIndexCoordinator(idx); + } else { + addIndex(idx); + } + } + } + +#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() << "'"; + for (auto const& it : _indexes) { + LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "- " << it.get(); + } + } +#endif } /// @brief Find index by definition @@ -230,3 +297,51 @@ void RocksDBCollection::deferDropCollection( void RocksDBCollection::figuresSpecific(std::shared_ptr&) { THROW_ARANGO_NOT_IMPLEMENTED(); } + +/// @brief creates the initial indexes for the collection +void RocksDBCollection::createInitialIndexes() { + if (!_indexes.empty()) { + return; + } + + std::vector> systemIndexes; + StorageEngine* engine = EngineSelectorFeature::ENGINE; + IndexFactory const* idxFactory = engine->indexFactory(); + TRI_ASSERT(idxFactory != nullptr); + + idxFactory->fillSystemIndexes(_logicalCollection, systemIndexes); + for (auto const& it : systemIndexes) { + addIndex(it); + } +} + +void RocksDBCollection::addIndex(std::shared_ptr idx) { + // primary index must be added at position 0 + TRI_ASSERT(idx->type() != arangodb::Index::TRI_IDX_TYPE_PRIMARY_INDEX || + _indexes.empty()); + + auto const id = idx->id(); + for (auto const& it : _indexes) { + if (it->id() == id) { + // already have this particular index. do not add it again + return; + } + } + + TRI_UpdateTickServer(static_cast(id)); + + _indexes.emplace_back(idx); +} + +void RocksDBCollection::addIndexCoordinator( + std::shared_ptr idx) { + auto const id = idx->id(); + for (auto const& it : _indexes) { + if (it->id() == id) { + // already have this particular index. do not add it again + return; + } + } + + _indexes.emplace_back(idx); +} diff --git a/arangod/RocksDBEngine/RocksDBCollection.h b/arangod/RocksDBEngine/RocksDBCollection.h index dc7abad89c..858c88ea5c 100644 --- a/arangod/RocksDBEngine/RocksDBCollection.h +++ b/arangod/RocksDBEngine/RocksDBCollection.h @@ -18,11 +18,11 @@ /// /// Copyright holder is ArangoDB GmbH, Cologne, Germany /// -/// @author Dr. Frank Celler +/// @author Jan-Christoph Uhde //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_ROCKSDB_FILES_COLLECTION_H -#define ARANGOD_STORAGE_ENGINE_ROCKSDB_FILES_COLLECTION_H 1 +#ifndef ARANGOD_ROCKSDB_ENGINE_ROCKSDB_COLLECTION_H +#define ARANGOD_ROCKSDB_ENGINE_ROCKSDB_COLLECTION_H 1 #include "Basics/Common.h" #include "Basics/ReadWriteLock.h" @@ -175,7 +175,12 @@ class RocksDBCollection final : public PhysicalCollection { private: /// @brief return engine-specific figures void figuresSpecific(std::shared_ptr&) override; + /// @brief creates the initial indexes for the collection + void createInitialIndexes(); + void addIndex(std::shared_ptr idx); + void addIndexCoordinator(std::shared_ptr idx); }; + } #endif diff --git a/arangod/RocksDBEngine/RocksDBEdgeIndex.cpp b/arangod/RocksDBEngine/RocksDBEdgeIndex.cpp new file mode 100644 index 0000000000..99a38c65ff --- /dev/null +++ b/arangod/RocksDBEngine/RocksDBEdgeIndex.cpp @@ -0,0 +1,205 @@ +//////////////////////////////////////////////////////////////////////////////// +/// 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 "RocksDBEdgeIndex.h" +#include "Aql/AstNode.h" +#include "Aql/SortCondition.h" +#include "Basics/Exceptions.h" +#include "Basics/StaticStrings.h" +#include "Basics/StringRef.h" +#include "Basics/fasthash.h" +#include "Basics/hashes.h" +#include "Indexes/IndexLookupContext.h" +#include "Indexes/SimpleAttributeEqualityMatcher.h" +#include "StorageEngine/TransactionState.h" +#include "Transaction/Helpers.h" +#include "Transaction/Methods.h" +#include "Utils/CollectionNameResolver.h" +#include "Transaction/Context.h" +#include "VocBase/LogicalCollection.h" + +#include +#include + +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> const + IndexAttributes{{arangodb::basics::AttributeName("_from", false)}, + {arangodb::basics::AttributeName("_to", false)}}; + +RocksDBEdgeIndexIterator::RocksDBEdgeIndexIterator(LogicalCollection* collection, transaction::Methods* trx, + ManagedDocumentResult* mmdr, + arangodb::RocksDBEdgeIndex const* index, + std::unique_ptr& keys) + : IndexIterator(collection, trx, mmdr, index), + _keys(keys.get()), + _iterator(_keys->slice()) { + keys.release(); // now we have ownership for _keys +} + +RocksDBEdgeIndexIterator::~RocksDBEdgeIndexIterator() { + if (_keys != nullptr) { + // return the VPackBuilder to the transaction context + _trx->transactionContextPtr()->returnBuilder(_keys.release()); + } +} + + +bool RocksDBEdgeIndexIterator::next(TokenCallback const& cb, size_t limit) { + THROW_ARANGO_NOT_IMPLEMENTED(); +} + +void RocksDBEdgeIndexIterator::reset() { + THROW_ARANGO_NOT_IMPLEMENTED(); +} + +RocksDBEdgeIndex::RocksDBEdgeIndex(TRI_idx_iid_t iid, arangodb::LogicalCollection* collection) + : Index(iid, collection, + std::vector>( + {{arangodb::basics::AttributeName(StaticStrings::FromString, + false)}, + {arangodb::basics::AttributeName(StaticStrings::ToString, + false)}}), + false, false) { + TRI_ASSERT(iid != 0); +} + +RocksDBEdgeIndex::~RocksDBEdgeIndex() {} + +/// @brief return a selectivity estimate for the index +double RocksDBEdgeIndex::selectivityEstimate(arangodb::StringRef const* attribute) const { + THROW_ARANGO_NOT_IMPLEMENTED(); + return 0.0; +} + +/// @brief return the memory usage for the index +size_t RocksDBEdgeIndex::memory() const { + THROW_ARANGO_NOT_IMPLEMENTED(); + return 0; +} + +/// @brief return a VelocyPack representation of the index +void RocksDBEdgeIndex::toVelocyPack(VPackBuilder& builder, bool withFigures) const { + Index::toVelocyPack(builder, withFigures); + + // hard-coded + builder.add("unique", VPackValue(false)); + builder.add("sparse", VPackValue(false)); +} + +/// @brief return a VelocyPack representation of the index figures +void RocksDBEdgeIndex::toVelocyPackFigures(VPackBuilder& builder) const { + Index::toVelocyPackFigures(builder); + // TODO + THROW_ARANGO_NOT_IMPLEMENTED(); +} + +int RocksDBEdgeIndex::insert(transaction::Methods* trx, TRI_voc_rid_t revisionId, + VPackSlice const& doc, bool isRollback) { + THROW_ARANGO_NOT_IMPLEMENTED(); + return TRI_ERROR_NO_ERROR; +} + +int RocksDBEdgeIndex::remove(transaction::Methods* trx, TRI_voc_rid_t revisionId, + VPackSlice const& doc, bool isRollback) { + THROW_ARANGO_NOT_IMPLEMENTED(); + return TRI_ERROR_NO_ERROR; +} + +/// @brief unload the index data from memory +int RocksDBEdgeIndex::unload() { + // nothing to do here + return TRI_ERROR_NO_ERROR; +} + +/// @brief provides a size hint for the edge index +int RocksDBEdgeIndex::sizeHint(transaction::Methods* trx, size_t size) { + // nothing to do here + return TRI_ERROR_NO_ERROR; +} + +/// @brief checks whether the index supports the condition +bool RocksDBEdgeIndex::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); +} + +/// @brief creates an IndexIterator for the given Condition +IndexIterator* RocksDBEdgeIndex::iteratorForCondition( + transaction::Methods* trx, + ManagedDocumentResult* mmdr, + arangodb::aql::AstNode const* node, + arangodb::aql::Variable const* reference, bool reverse) const { + THROW_ARANGO_NOT_IMPLEMENTED(); + return nullptr; +} + +/// @brief specializes the condition for use with the index +arangodb::aql::AstNode* RocksDBEdgeIndex::specializeCondition( + arangodb::aql::AstNode* node, + arangodb::aql::Variable const* reference) const { + SimpleAttributeEqualityMatcher matcher(IndexAttributes); + return matcher.specializeOne(this, node, reference); +} + +/// @brief Transform the list of search slices to search values. +/// This will multiply all IN entries and simply return all other +/// entries. +void RocksDBEdgeIndex::expandInSearchValues(VPackSlice const slice, + VPackBuilder& builder) const { + TRI_ASSERT(slice.isArray()); + builder.openArray(); + for (auto const& side : VPackArrayIterator(slice)) { + if (side.isNull()) { + builder.add(side); + } else { + TRI_ASSERT(side.isArray()); + builder.openArray(); + for (auto const& item : VPackArrayIterator(side)) { + TRI_ASSERT(item.isObject()); + if (item.hasKey(StaticStrings::IndexEq)) { + TRI_ASSERT(!item.hasKey(StaticStrings::IndexIn)); + builder.add(item); + } else { + TRI_ASSERT(item.hasKey(StaticStrings::IndexIn)); + VPackSlice list = item.get(StaticStrings::IndexIn); + TRI_ASSERT(list.isArray()); + for (auto const& it : VPackArrayIterator(list)) { + builder.openObject(); + builder.add(StaticStrings::IndexEq, it); + builder.close(); + } + } + } + builder.close(); + } + } + builder.close(); +} diff --git a/arangod/RocksDBEngine/RocksDBEdgeIndex.h b/arangod/RocksDBEngine/RocksDBEdgeIndex.h new file mode 100644 index 0000000000..245612d6ba --- /dev/null +++ b/arangod/RocksDBEngine/RocksDBEdgeIndex.h @@ -0,0 +1,122 @@ +//////////////////////////////////////////////////////////////////////////////// +/// 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_ROCKSDB_ENGINE_ROCKSDB_EDGE_INDEX_H +#define ARANGOD_ROCKSDB_ENGINE_ROCKSDB_EDGE_INDEX_H 1 + +#include "Basics/Common.h" +#include "Indexes/Index.h" +#include "Indexes/IndexIterator.h" +#include "VocBase/voc-types.h" +#include "VocBase/vocbase.h" + +#include +#include + +namespace arangodb { +class RocksDBEdgeIndex; + +class RocksDBEdgeIndexIterator final : public IndexIterator { + public: + RocksDBEdgeIndexIterator(LogicalCollection* collection, transaction::Methods* trx, + ManagedDocumentResult* mmdr, + arangodb::RocksDBEdgeIndex const* index, + std::unique_ptr& keys); + + ~RocksDBEdgeIndexIterator(); + + char const* typeName() const override { return "edge-index-iterator"; } + + bool next(TokenCallback const& cb, size_t limit) override; + + void reset() override; + + private: + std::unique_ptr _keys; + arangodb::velocypack::ArrayIterator _iterator; +}; + +class RocksDBEdgeIndex final : public Index { + public: + RocksDBEdgeIndex() = delete; + + RocksDBEdgeIndex(TRI_idx_iid_t, arangodb::LogicalCollection*); + + ~RocksDBEdgeIndex(); + + public: + IndexType type() const override { return Index::TRI_IDX_TYPE_EDGE_INDEX; } + + char const* typeName() const override { return "edge"; } + + bool allowExpansion() const override { return false; } + + bool canBeDropped() const override { return false; } + + bool isSorted() const override { return false; } + + bool hasSelectivityEstimate() const override { return true; } + + double selectivityEstimate( + arangodb::StringRef const* = nullptr) const override; + + size_t memory() const override; + + void toVelocyPack(VPackBuilder&, bool) const override; + + void toVelocyPackFigures(VPackBuilder&) const override; + + int insert(transaction::Methods*, TRI_voc_rid_t, + arangodb::velocypack::Slice const&, bool isRollback) override; + + int remove(transaction::Methods*, TRI_voc_rid_t, + arangodb::velocypack::Slice const&, bool isRollback) override; + + int unload() override; + + int sizeHint(transaction::Methods*, size_t) override; + + bool hasBatchInsert() const override { return false; } + + bool supportsFilterCondition(arangodb::aql::AstNode const*, + arangodb::aql::Variable const*, size_t, size_t&, + double&) const override; + + IndexIterator* iteratorForCondition(transaction::Methods*, + ManagedDocumentResult*, + arangodb::aql::AstNode const*, + arangodb::aql::Variable const*, + bool) const override; + + arangodb::aql::AstNode* specializeCondition( + arangodb::aql::AstNode*, arangodb::aql::Variable const*) const override; + + /// @brief Transform the list of search slices to search values. + /// This will multiply all IN entries and simply return all other + /// entries. + void expandInSearchValues(arangodb::velocypack::Slice const, + arangodb::velocypack::Builder&) const override; +}; +} + +#endif diff --git a/arangod/RocksDBEngine/RocksDBEngine.cpp b/arangod/RocksDBEngine/RocksDBEngine.cpp index 3f8917997f..bddc83ec74 100644 --- a/arangod/RocksDBEngine/RocksDBEngine.cpp +++ b/arangod/RocksDBEngine/RocksDBEngine.cpp @@ -35,6 +35,7 @@ #include "RestServer/ViewTypesFeature.h" #include "RocksDBEngine/RocksDBCollection.h" #include "RocksDBEngine/RocksDBEntry.h" +#include "RocksDBEngine/RocksDBIndexFactory.h" #include "RocksDBEngine/RocksDBTypes.h" #include "RocksDBEngine/RocksDBView.h" #include "VocBase/ticks.h" @@ -63,8 +64,7 @@ std::string const RocksDBEngine::FeatureName("RocksDBEngine"); // create the storage engine RocksDBEngine::RocksDBEngine(application_features::ApplicationServer* server) - : StorageEngine(server, EngineName, FeatureName, nullptr /*new - MMFilesIndexFactory()*/), + : StorageEngine(server, EngineName, FeatureName, new RocksDBIndexFactory()), _db(nullptr) { //inherits order from StorageEngine } diff --git a/arangod/RocksDBEngine/RocksDBEngine.h b/arangod/RocksDBEngine/RocksDBEngine.h index d31735a29d..4827a22818 100644 --- a/arangod/RocksDBEngine/RocksDBEngine.h +++ b/arangod/RocksDBEngine/RocksDBEngine.h @@ -22,8 +22,8 @@ /// @author Jan Christoph Uhde //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_ROCKSDB_ENGINE_H -#define ARANGOD_STORAGE_ENGINE_ROCKSDB_ENGINE_H 1 +#ifndef ARANGOD_ROCKSDB_ENGINE_ROCKSDB_ENGINE_H +#define ARANGOD_ROCKSDB_ENGINE_ROCKSDB_ENGINE_H 1 #include "Basics/Common.h" #include "Basics/Mutex.h" diff --git a/arangod/RocksDBEngine/RocksDBIndexFactory.cpp b/arangod/RocksDBEngine/RocksDBIndexFactory.cpp index 91c669c5b6..0568454a36 100644 --- a/arangod/RocksDBEngine/RocksDBIndexFactory.cpp +++ b/arangod/RocksDBEngine/RocksDBIndexFactory.cpp @@ -22,13 +22,11 @@ //////////////////////////////////////////////////////////////////////////////// #include "RocksDBIndexFactory.h" -#include "Basics/StaticStrings.h" -#include "Basics/StringRef.h" #include "Basics/StringUtils.h" #include "Basics/VelocyPackHelper.h" - -#include "Cluster/ServerState.h" #include "Indexes/Index.h" +#include "RocksDBEngine/RocksDBEdgeIndex.h" +#include "RocksDBEngine/RocksDBPrimaryIndex.h" #include "VocBase/voc-types.h" #include @@ -36,26 +34,104 @@ #include #include -#include - using namespace arangodb; int RocksDBIndexFactory::enhanceIndexDefinition(VPackSlice const definition, VPackBuilder& enhanced, bool create) const { - throw std::runtime_error("not implemented"); + THROW_ARANGO_NOT_IMPLEMENTED(); return 0; } std::shared_ptr RocksDBIndexFactory::prepareIndexFromSlice( arangodb::velocypack::Slice info, bool generateKey, LogicalCollection* col, bool isClusterConstructor) const { - throw std::runtime_error("not implemented"); - return nullptr; + if (!info.isObject()) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_BAD_PARAMETER); + } + + // extract type + VPackSlice value = info.get("type"); + + if (!value.isString()) { + // Compatibility with old v8-vocindex. + if (generateKey) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } else { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "invalid index type definition"); + } + } + + std::string tmp = value.copyString(); + arangodb::Index::IndexType const type = arangodb::Index::type(tmp.c_str()); + + std::shared_ptr newIdx; + + TRI_idx_iid_t iid = 0; + value = info.get("id"); + if (value.isString()) { + iid = basics::StringUtils::uint64(value.copyString()); + } else if (value.isNumber()) { + iid = + basics::VelocyPackHelper::getNumericValue(info, "id", 0); + } else if (!generateKey) { + // In the restore case it is forbidden to NOT have id + THROW_ARANGO_EXCEPTION_MESSAGE( + TRI_ERROR_INTERNAL, "cannot restore index without index identifier"); + } + + if (iid == 0 && !isClusterConstructor) { + // Restore is not allowed to generate in id + TRI_ASSERT(generateKey); + iid = arangodb::Index::generateId(); + } + + switch (type) { + case arangodb::Index::TRI_IDX_TYPE_UNKNOWN: { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid index type"); + } + case arangodb::Index::TRI_IDX_TYPE_PRIMARY_INDEX: { + if (!isClusterConstructor) { + // this indexes cannot be created directly + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "cannot create primary index"); + } + newIdx.reset(new arangodb::RocksDBPrimaryIndex(col)); + break; + } + case arangodb::Index::TRI_IDX_TYPE_EDGE_INDEX: { + if (!isClusterConstructor) { + // this indexes cannot be created directly + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "cannot create edge index"); + } + newIdx.reset(new arangodb::RocksDBEdgeIndex(iid, col)); + break; + } + + default: { + THROW_ARANGO_NOT_IMPLEMENTED(); + break; + } + } + + if (newIdx == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return newIdx; } void RocksDBIndexFactory::fillSystemIndexes( arangodb::LogicalCollection* col, std::vector>& systemIndexes) const { - throw std::runtime_error("not implemented"); + // create primary index + systemIndexes.emplace_back( + std::make_shared(col)); + + // create edges index + if (col->type() == TRI_COL_TYPE_EDGE) { + systemIndexes.emplace_back( + std::make_shared(1, col)); + } } diff --git a/arangod/RocksDBEngine/RocksDBIndexFactory.h b/arangod/RocksDBEngine/RocksDBIndexFactory.h index 49a5a7abe7..7395f1c20b 100644 --- a/arangod/RocksDBEngine/RocksDBIndexFactory.h +++ b/arangod/RocksDBEngine/RocksDBIndexFactory.h @@ -28,25 +28,25 @@ namespace arangodb { - class RocksDBIndexFactory : public IndexFactory { - public: - RocksDBIndexFactory() : IndexFactory() { - } +class RocksDBIndexFactory final : public IndexFactory { + public: + RocksDBIndexFactory() : IndexFactory() {} - ~RocksDBIndexFactory() override {} + ~RocksDBIndexFactory() {} - int enhanceIndexDefinition( - arangodb::velocypack::Slice const definition, - arangodb::velocypack::Builder& enhanced, bool isCreation) const override; + int enhanceIndexDefinition( + arangodb::velocypack::Slice const definition, + arangodb::velocypack::Builder& enhanced, bool isCreation) const override; - std::shared_ptr prepareIndexFromSlice( - arangodb::velocypack::Slice info, bool generateKey, - LogicalCollection* col, bool isClusterConstructor) const override; + std::shared_ptr prepareIndexFromSlice( + arangodb::velocypack::Slice info, bool generateKey, + LogicalCollection* col, bool isClusterConstructor) const override; + + void fillSystemIndexes(arangodb::LogicalCollection* col, + std::vector>& + systemIndexes) const override; +}; - void fillSystemIndexes(arangodb::LogicalCollection* col, - std::vector>& - systemIndexes) const override; - }; } #endif diff --git a/arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp b/arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp new file mode 100644 index 0000000000..d031241a6b --- /dev/null +++ b/arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp @@ -0,0 +1,189 @@ +//////////////////////////////////////////////////////////////////////////////// +/// 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 "RocksDBPrimaryIndex.h" +#include "Aql/AstNode.h" +#include "Basics/Exceptions.h" +#include "Basics/StaticStrings.h" +#include "Indexes/SimpleAttributeEqualityMatcher.h" +#include "Transaction/Helpers.h" +#include "Transaction/Methods.h" +#include "Transaction/Context.h" +#include "VocBase/LogicalCollection.h" + +#include +#include +#include +#include + +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> const IndexAttributes + {{arangodb::basics::AttributeName("_id", false)}, + {arangodb::basics::AttributeName("_key", false)}}; + +RocksDBPrimaryIndexIterator::RocksDBPrimaryIndexIterator(LogicalCollection* collection, + transaction::Methods* trx, + ManagedDocumentResult* mmdr, + RocksDBPrimaryIndex const* index, + std::unique_ptr& keys) + : IndexIterator(collection, trx, mmdr, index), + _index(index), + _keys(keys.get()), + _iterator(_keys->slice()) { + + keys.release(); // now we have ownership for _keys + TRI_ASSERT(_keys->slice().isArray()); +} + +RocksDBPrimaryIndexIterator::~RocksDBPrimaryIndexIterator() { + if (_keys != nullptr) { + // return the VPackBuilder to the transaction context + _trx->transactionContextPtr()->returnBuilder(_keys.release()); + } +} + +bool RocksDBPrimaryIndexIterator::next(TokenCallback const& cb, size_t limit) { + THROW_ARANGO_NOT_IMPLEMENTED(); + return false; +} + +void RocksDBPrimaryIndexIterator::reset() { _iterator.reset(); } + +RocksDBAllIndexIterator::RocksDBAllIndexIterator(LogicalCollection* collection, + transaction::Methods* trx, + ManagedDocumentResult* mmdr, + RocksDBPrimaryIndex const* index, + bool reverse) + : IndexIterator(collection, trx, mmdr, index), _reverse(reverse), _total(0) {} + +bool RocksDBAllIndexIterator::next(TokenCallback const& cb, size_t limit) { + THROW_ARANGO_NOT_IMPLEMENTED(); + return true; +} + +void RocksDBAllIndexIterator::reset() { + THROW_ARANGO_NOT_IMPLEMENTED(); +} + +RocksDBAnyIndexIterator::RocksDBAnyIndexIterator(LogicalCollection* collection, transaction::Methods* trx, + ManagedDocumentResult* mmdr, + RocksDBPrimaryIndex const* index) + : IndexIterator(collection, trx, mmdr, index) {} + +bool RocksDBAnyIndexIterator::next(TokenCallback const& cb, size_t limit) { + THROW_ARANGO_NOT_IMPLEMENTED(); + return true; +} + +void RocksDBAnyIndexIterator::reset() { + THROW_ARANGO_NOT_IMPLEMENTED(); +} + +RocksDBPrimaryIndex::RocksDBPrimaryIndex(arangodb::LogicalCollection* collection) + : Index(0, collection, + std::vector>( + {{arangodb::basics::AttributeName(StaticStrings::KeyString, false)}}), + true, false) { +} + +RocksDBPrimaryIndex::~RocksDBPrimaryIndex() {} + +/// @brief return the number of documents from the index +size_t RocksDBPrimaryIndex::size() const { + // TODO + return 0; +} + +/// @brief return the memory usage of the index +size_t RocksDBPrimaryIndex::memory() const { + return 0; // TODO +} + +/// @brief return a VelocyPack representation of the index +void RocksDBPrimaryIndex::toVelocyPack(VPackBuilder& builder, bool withFigures) const { + Index::toVelocyPack(builder, withFigures); + // hard-coded + builder.add("unique", VPackValue(true)); + builder.add("sparse", VPackValue(false)); +} + +/// @brief return a VelocyPack representation of the index figures +void RocksDBPrimaryIndex::toVelocyPackFigures(VPackBuilder& builder) const { + Index::toVelocyPackFigures(builder); + // TODO: implement +} + +int RocksDBPrimaryIndex::insert(transaction::Methods*, TRI_voc_rid_t, VPackSlice const&, bool) { +#ifdef ARANGODB_ENABLE_MAINTAINER_MODE + LOG_TOPIC(WARN, arangodb::Logger::FIXME) << "insert() called for primary index"; +#endif + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "insert() called for primary index"); +} + +int RocksDBPrimaryIndex::remove(transaction::Methods*, TRI_voc_rid_t, VPackSlice const&, bool) { +#ifdef ARANGODB_ENABLE_MAINTAINER_MODE + LOG_TOPIC(WARN, arangodb::Logger::FIXME) << "remove() called for primary index"; +#endif + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "remove() called for primary index"); +} + +/// @brief unload the index data from memory +int RocksDBPrimaryIndex::unload() { + // nothing to do + return TRI_ERROR_NO_ERROR; +} + +/// @brief checks whether the index supports the condition +bool RocksDBPrimaryIndex::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); +} + +/// @brief creates an IndexIterator for the given Condition +IndexIterator* RocksDBPrimaryIndex::iteratorForCondition( + transaction::Methods* trx, + ManagedDocumentResult* mmdr, + arangodb::aql::AstNode const* node, + arangodb::aql::Variable const* reference, bool reverse) const { + + THROW_ARANGO_NOT_IMPLEMENTED(); + return nullptr; +} + +/// @brief specializes the condition for use with the index +arangodb::aql::AstNode* RocksDBPrimaryIndex::specializeCondition( + arangodb::aql::AstNode* node, + arangodb::aql::Variable const* reference) const { + + SimpleAttributeEqualityMatcher matcher(IndexAttributes); + return matcher.specializeOne(this, node, reference); +} diff --git a/arangod/RocksDBEngine/RocksDBPrimaryIndex.h b/arangod/RocksDBEngine/RocksDBPrimaryIndex.h new file mode 100644 index 0000000000..707be45bb0 --- /dev/null +++ b/arangod/RocksDBEngine/RocksDBPrimaryIndex.h @@ -0,0 +1,157 @@ +//////////////////////////////////////////////////////////////////////////////// +/// 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_ROCKSDB_ENGINE_ROCKSDB_PRIMARY_INDEX_H +#define ARANGOD_ROCKSDB_ENGINE_ROCKSDB_PRIMARY_INDEX_H 1 + +#include "Basics/Common.h" +#include "Indexes/Index.h" +#include "Indexes/IndexIterator.h" +#include "VocBase/vocbase.h" +#include "VocBase/voc-types.h" + +#include +#include +#include + +namespace arangodb { + +class RocksDBPrimaryIndex; +namespace transaction { +class Methods; +} + +class RocksDBPrimaryIndexIterator final : public IndexIterator { + public: + RocksDBPrimaryIndexIterator(LogicalCollection* collection, + transaction::Methods* trx, + ManagedDocumentResult* mmdr, + RocksDBPrimaryIndex const* index, + std::unique_ptr& keys); + + ~RocksDBPrimaryIndexIterator(); + + char const* typeName() const override { return "primary-index-iterator"; } + + bool next(TokenCallback const& cb, size_t limit) override; + + void reset() override; + + private: + RocksDBPrimaryIndex const* _index; + std::unique_ptr _keys; + arangodb::velocypack::ArrayIterator _iterator; +}; + +class RocksDBAllIndexIterator final : public IndexIterator { + public: + RocksDBAllIndexIterator(LogicalCollection* collection, + transaction::Methods* trx, + ManagedDocumentResult* mmdr, + RocksDBPrimaryIndex const* index, + bool reverse); + + ~RocksDBAllIndexIterator() {} + + char const* typeName() const override { return "all-index-iterator"; } + + bool next(TokenCallback const& cb, size_t limit) override; + + void reset() override; + + private: + bool const _reverse; + uint64_t _total; +}; + +class RocksDBAnyIndexIterator final : public IndexIterator { + public: + RocksDBAnyIndexIterator(LogicalCollection* collection, transaction::Methods* trx, + ManagedDocumentResult* mmdr, + RocksDBPrimaryIndex const* index); + + ~RocksDBAnyIndexIterator() {} + + char const* typeName() const override { return "any-index-iterator"; } + + bool next(TokenCallback const& cb, size_t limit) override; + + void reset() override; +}; + +class RocksDBPrimaryIndex final : public Index { + friend class RocksDBPrimaryIndexIterator; + + public: + RocksDBPrimaryIndex() = delete; + + explicit RocksDBPrimaryIndex(arangodb::LogicalCollection*); + + ~RocksDBPrimaryIndex(); + + public: + IndexType type() const override { + return Index::TRI_IDX_TYPE_PRIMARY_INDEX; + } + + char const* typeName() const override { return "primary"; } + + bool allowExpansion() const override { return false; } + + bool canBeDropped() const override { return false; } + + bool isSorted() const override { return false; } + + bool hasSelectivityEstimate() const override { return true; } + + double selectivityEstimate(arangodb::StringRef const* = nullptr) const override { return 1.0; } + + size_t size() const; + + size_t memory() const override; + + void toVelocyPack(VPackBuilder&, bool) const override; + void toVelocyPackFigures(VPackBuilder&) const override; + + int insert(transaction::Methods*, TRI_voc_rid_t, arangodb::velocypack::Slice const&, bool isRollback) override; + + int remove(transaction::Methods*, TRI_voc_rid_t, arangodb::velocypack::Slice const&, bool isRollback) override; + + int unload() override; + + bool supportsFilterCondition(arangodb::aql::AstNode const*, + arangodb::aql::Variable const*, size_t, size_t&, + double&) const override; + + IndexIterator* iteratorForCondition(transaction::Methods*, + ManagedDocumentResult*, + arangodb::aql::AstNode const*, + arangodb::aql::Variable const*, + bool) const override; + + arangodb::aql::AstNode* specializeCondition( + arangodb::aql::AstNode*, arangodb::aql::Variable const*) const override; +}; +} + +#endif diff --git a/arangod/RocksDBEngine/RocksDBTransactionCollection.h b/arangod/RocksDBEngine/RocksDBTransactionCollection.h index 9f240e7ad8..13ec6d15d3 100644 --- a/arangod/RocksDBEngine/RocksDBTransactionCollection.h +++ b/arangod/RocksDBEngine/RocksDBTransactionCollection.h @@ -34,7 +34,6 @@ struct RocksDBDocumentOperation; namespace transaction { class Methods; } -; class TransactionState; /// @brief collection used in a transaction diff --git a/arangod/RocksDBEngine/RocksDBView.h b/arangod/RocksDBEngine/RocksDBView.h index c5108fdc1e..8401bf83e8 100644 --- a/arangod/RocksDBEngine/RocksDBView.h +++ b/arangod/RocksDBEngine/RocksDBView.h @@ -21,8 +21,8 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_MM_FILES_VIEW_H -#define ARANGOD_STORAGE_ENGINE_MM_FILES_VIEW_H 1 +#ifndef ARANGOD_ROCKSDB_ENGINE_ROCKSDB_VIEW_H +#define ARANGOD_ROCKSDB_ENGINE_ROCKSDB_VIEW_H 1 #include "Basics/Common.h" #include "Basics/ReadWriteLock.h"