diff --git a/arangod/CMakeLists.txt b/arangod/CMakeLists.txt index a1b876dee6..1f6b60cf81 100644 --- a/arangod/CMakeLists.txt +++ b/arangod/CMakeLists.txt @@ -268,7 +268,9 @@ add_executable(${BIN_ARANGOD} Scheduler/TimerTask.cpp Statistics/StatisticsFeature.cpp Statistics/statistics.cpp - StorageEngine/ArangoEngine.cpp + StorageEngine/EngineSelectorFeature.cpp + StorageEngine/MMFilesEngine.cpp + StorageEngine/OtherEngine.cpp Utils/AqlTransaction.cpp Utils/CollectionExport.cpp Utils/CollectionKeys.cpp diff --git a/arangod/RestServer/arangod.cpp b/arangod/RestServer/arangod.cpp index 89059a9d26..3abd0f424c 100644 --- a/arangod/RestServer/arangod.cpp +++ b/arangod/RestServer/arangod.cpp @@ -67,6 +67,9 @@ #include "Ssl/SslFeature.h" #include "Ssl/SslServerFeature.h" #include "Statistics/StatisticsFeature.h" +#include "StorageEngine/EngineSelectorFeature.h" +#include "StorageEngine/MMFilesEngine.h" +#include "StorageEngine/OtherEngine.h" #include "V8Server/FoxxQueuesFeature.h" #include "V8Server/V8DealerFeature.h" #include "Wal/LogfileManager.h" @@ -116,6 +119,7 @@ static int runServer(int argc, char** argv) { server.addFeature(new DatabaseServerFeature(&server)); server.addFeature(new DispatcherFeature(&server)); server.addFeature(new EndpointFeature(&server)); + server.addFeature(new EngineSelectorFeature(&server)); server.addFeature(new FileDescriptorsFeature(&server)); server.addFeature(new FoxxQueuesFeature(&server)); server.addFeature(new FrontendFeature(&server)); @@ -158,15 +162,21 @@ static int runServer(int argc, char** argv) { server.addFeature(supervisor.release()); #endif + // storage engines + server.addFeature(new MMFilesEngine(&server)); + server.addFeature(new OtherEngine(&server)); + try { server.run(argc, argv); } catch (std::exception const& ex) { LOG(ERR) << "arangod terminated because of an unhandled exception: " << ex.what(); + Logger::flush(); ret = EXIT_FAILURE; } catch (...) { LOG(ERR) << "arangod terminated because of an unhandled exception of " "unknown type"; + Logger::flush(); ret = EXIT_FAILURE; } diff --git a/arangod/StorageEngine/EngineSelectorFeature.cpp b/arangod/StorageEngine/EngineSelectorFeature.cpp new file mode 100644 index 0000000000..15a97b7680 --- /dev/null +++ b/arangod/StorageEngine/EngineSelectorFeature.cpp @@ -0,0 +1,71 @@ +//////////////////////////////////////////////////////////////////////////////// +/// DISCLAIMER +/// +/// Copyright 2016 ArangoDB 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 Dr. Frank Celler +//////////////////////////////////////////////////////////////////////////////// + +#include "EngineSelectorFeature.h" +#include "ApplicationFeatures/ApplicationServer.h" +#include "ProgramOptions/ProgramOptions.h" +#include "ProgramOptions/Section.h" +#include "StorageEngine/MMFilesEngine.h" +#include "StorageEngine/OtherEngine.h" +#include "StorageEngine/StorageEngine.h" + +using namespace arangodb; +using namespace arangodb::options; + +EngineSelectorFeature::EngineSelectorFeature( + application_features::ApplicationServer* server) + : ApplicationFeature(server, "EngineSelector"), _engine(MMFilesEngine::EngineName) { + setOptional(false); + requiresElevatedPrivileges(false); + startsAfter("Logger"); +} + +void EngineSelectorFeature::collectOptions(std::shared_ptr options) { + options->addOption("--server.storage-engine", + "storage engine type", + new DiscreteValuesParameter(&_engine, availableEngines())); +} + +void EngineSelectorFeature::prepare() { + // deactivate all engines but the selected one + for (auto& engine : availableEngines()) { + StorageEngine* e = application_features::ApplicationServer::getFeature(engine + "Engine"); + + if (engine == _engine) { + // this is the selected engine + LOG(TRACE) << "enabling storage engine " << engine; + e->enable(); + } else { + // turn off all other storage engines + LOG(TRACE) << "disabling storage engine " << engine; + e->disable(); + } + } +} + +// all available storage engines +std::unordered_set EngineSelectorFeature::availableEngines() { + return std::unordered_set{ + MMFilesEngine::EngineName, + OtherEngine::EngineName + }; +} diff --git a/arangod/StorageEngine/EngineSelectorFeature.h b/arangod/StorageEngine/EngineSelectorFeature.h new file mode 100644 index 0000000000..8e3c690c47 --- /dev/null +++ b/arangod/StorageEngine/EngineSelectorFeature.h @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////////// +/// DISCLAIMER +/// +/// Copyright 2016 ArangoDB 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 Dr. Frank Celler +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ARANGODB_STORAGE_ENGINE_ENGINE_SELECTOR_FEATURE_H +#define ARANGODB_STORAGE_ENGINE_ENGINE_SELECTOR_FEATURE_H 1 + +#include "ApplicationFeatures/ApplicationFeature.h" +#include "ProgramOptions/ProgramOptions.h" + +namespace arangodb { +class EngineSelectorFeature final : public application_features::ApplicationFeature { + public: + explicit EngineSelectorFeature(application_features::ApplicationServer* server); + + public: + void collectOptions(std::shared_ptr) override final; + void prepare() override final; + + static std::unordered_set availableEngines(); + + private: + std::string _engine; +}; +} + +#endif diff --git a/arangod/StorageEngine/MMFilesEngine.cpp b/arangod/StorageEngine/MMFilesEngine.cpp new file mode 100644 index 0000000000..9f139323bd --- /dev/null +++ b/arangod/StorageEngine/MMFilesEngine.cpp @@ -0,0 +1,193 @@ +//////////////////////////////////////////////////////////////////////////////// +/// 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 "MMFilesEngine.h" + +using namespace arangodb; + +std::string const MMFilesEngine::EngineName("mmfiles"); + +// create the storage engine +MMFilesEngine::MMFilesEngine(application_features::ApplicationServer* server) + : StorageEngine(server, "mmfilesEngine") { +} + +MMFilesEngine::~MMFilesEngine() { +} + +// add the storage engine's specifc options to the global list of options +void MMFilesEngine::collectOptions(std::shared_ptr) { +} + +// validate the storage engine's specific options +void MMFilesEngine::validateOptions(std::shared_ptr) { +} + +// preparation phase for storage engine. can be used for internal setup. +// the storage engine must not start any threads here or write any files +void MMFilesEngine::prepare() { +} + +// start the engine. now it's allowed to start engine-specific threads, +// write files etc. +void MMFilesEngine::start() { +} + +// stop the storage engine. this can be used to flush all data to disk, +// shutdown threads etc. it is guaranteed that there will be no read and +// write requests to the storage engine after this call +void MMFilesEngine::stop() { +} + +// fill the Builder object with an array of databases that were detected +// by the storage engine. this method must sort out databases that were not +// fully created (see "createDatabase" below). called at server start only +void MMFilesEngine::getDatabases(arangodb::velocypack::Builder& result) { +} + +// fill the Builder object with an array of collections (and their corresponding +// indexes) that were detected by the storage engine. called at server start only +void MMFilesEngine::getCollectionsAndIndexes(arangodb::velocypack::Builder& result) { +} + +// determine the maximum revision id previously handed out by the storage +// engine. this value is used as a lower bound for further HLC values handed out by +// the server. called at server start only, after getDatabases() and getCollectionsAndIndexes() +uint64_t MMFilesEngine::getMaxRevision() { + return 0; // TODO +} + +// asks the storage engine to create a database as specified in the VPack +// Slice object and persist the creation info. It is guaranteed by the server that +// no other active database with the same name and id exists when this function +// is called. If this operation fails somewhere in the middle, the storage +// engine is required to fully clean up the creation and throw only then, +// so that subsequent database creation requests will not fail. +// the WAL entry for the database creation will be written *after* the call +// to "createDatabase" returns +void MMFilesEngine::createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& data) { +} + +// asks the storage engine to drop the specified database and persist the +// deletion info. Note that physical deletion of the database data must not +// be carried out by this call, as there may +// still be readers of the database's data. It is recommended that this operation +// only sets a deletion flag for the database but let's an async task perform +// the actual deletion. The async task can later call the callback function to +// check whether the physical deletion of the database is possible. +// the WAL entry for database deletion will be written *after* the call +// to "dropDatabase" returns +void MMFilesEngine::dropDatabase(TRI_voc_tick_t id, std::function const& canRemovePhysically) { +} + +// asks the storage engine to create a collection as specified in the VPack +// Slice object and persist the creation info. It is guaranteed by the server +// that no other active collection with the same name and id exists in the same +// database when this function is called. If this operation fails somewhere in +// the middle, the storage engine is required to fully clean up the creation +// and throw only then, so that subsequent collection creation requests will not fail. +// the WAL entry for the collection creation will be written *after* the call +// to "createCollection" returns +void MMFilesEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) { +} + +// asks the storage engine to drop the specified collection and persist the +// deletion info. Note that physical deletion of the collection data must not +// be carried out by this call, as there may +// still be readers of the collection's data. It is recommended that this operation +// only sets a deletion flag for the collection but let's an async task perform +// the actual deletion. +// the WAL entry for collection deletion will be written *after* the call +// to "dropCollection" returns +void MMFilesEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + std::function const& canRemovePhysically) { +} + +// asks the storage engine to rename the collection as specified in the VPack +// Slice object and persist the renaming info. It is guaranteed by the server +// that no other active collection with the same name and id exists in the same +// database when this function is called. If this operation fails somewhere in +// the middle, the storage engine is required to fully revert the rename operation +// and throw only then, so that subsequent collection creation/rename requests will +// not fail. the WAL entry for the rename will be written *after* the call +// to "renameCollection" returns +void MMFilesEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) { +} + +// asks the storage engine to change properties of the collection as specified in +// the VPack Slice object and persist them. If this operation fails +// somewhere in the middle, the storage engine is required to fully revert the +// property changes and throw only then, so that subsequent operations will not fail. +// the WAL entry for the propery change will be written *after* the call +// to "changeCollection" returns +void MMFilesEngine::changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) { +} + +// asks the storage engine to create an index as specified in the VPack +// Slice object and persist the creation info. The database id, collection id +// and index data are passed in the Slice object. Note that this function +// is not responsible for inserting the individual documents into the index. +// If this operation fails somewhere in the middle, the storage engine is required +// to fully clean up the creation and throw only then, so that subsequent index +// creation requests will not fail. +// the WAL entry for the index creation will be written *after* the call +// to "createIndex" returns +void MMFilesEngine::createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) { +} + +// asks the storage engine to drop the specified index and persist the deletion +// info. Note that physical deletion of the index must not be carried out by this call, +// as there may still be users of the index. It is recommended that this operation +// only sets a deletion flag for the index but let's an async task perform +// the actual deletion. +// the WAL entry for index deletion will be written *after* the call +// to "dropIndex" returns +void MMFilesEngine::dropIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + TRI_idx_iid_t id) { +} + +// iterate all documents of the underlying collection +// this is called when a collection is openend, and all its documents need to be added to +// indexes etc. +void MMFilesEngine::iterateDocuments(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + std::function const& cb) { +} + +// adds a document to the storage engine +// this will be called by the WAL collector when surviving documents are being moved +// into the storage engine's realm +void MMFilesEngine::addDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + arangodb::velocypack::Slice const& document) { +} + +// removes a document from the storage engine +// this will be called by the WAL collector when non-surviving documents are being removed +// from the storage engine's realm +void MMFilesEngine::removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + arangodb::velocypack::Slice const& document) { +} + diff --git a/arangod/StorageEngine/ArangoEngine.h b/arangod/StorageEngine/MMFilesEngine.h similarity index 95% rename from arangod/StorageEngine/ArangoEngine.h rename to arangod/StorageEngine/MMFilesEngine.h index 0494274525..13dbd1fe89 100644 --- a/arangod/StorageEngine/ArangoEngine.h +++ b/arangod/StorageEngine/MMFilesEngine.h @@ -21,21 +21,21 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_STORAGE_ENGINE_ARANGO_ENGINE_H -#define ARANGOD_STORAGE_ENGINE_ARANGO_ENGINE_H 1 +#ifndef ARANGOD_STORAGE_ENGINE_MMFILES_ENGINE_H +#define ARANGOD_STORAGE_ENGINE_MMFILES_ENGINE_H 1 #include "Basics/Common.h" #include "StorageEngine/StorageEngine.h" namespace arangodb { -class ArangoEngine final : public StorageEngine { +class MMFilesEngine final : public StorageEngine { public: // create the storage engine - explicit ArangoEngine(application_features::ApplicationServer*); + explicit MMFilesEngine(application_features::ApplicationServer*); - ~ArangoEngine(); + ~MMFilesEngine(); // inherited from ApplicationFeature // --------------------------------- @@ -63,11 +63,8 @@ class ArangoEngine final : public StorageEngine { // -------------------- // return the name of the storage engine - char const* typeName() const override { return "arango"; } + char const* typeName() const override { return EngineName.c_str(); } - // return the version string of the storage engine - char const* versionString() const override { return "arango-0.0.1"; } - // inventory functionality // ----------------------- @@ -194,6 +191,9 @@ class ArangoEngine final : public StorageEngine { // from the storage engine's realm void removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, arangodb::velocypack::Slice const& document) override; + + public: + static std::string const EngineName; }; } diff --git a/arangod/StorageEngine/ArangoEngine.cpp b/arangod/StorageEngine/OtherEngine.cpp similarity index 75% rename from arangod/StorageEngine/ArangoEngine.cpp rename to arangod/StorageEngine/OtherEngine.cpp index 0e863574f3..5dee8a2100 100644 --- a/arangod/StorageEngine/ArangoEngine.cpp +++ b/arangod/StorageEngine/OtherEngine.cpp @@ -21,57 +21,59 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#include "ArangoEngine.h" +#include "OtherEngine.h" using namespace arangodb; +std::string const OtherEngine::EngineName("other"); + // create the storage engine -ArangoEngine::ArangoEngine(application_features::ApplicationServer* server) - : StorageEngine(server, "ArangoEngine") { +OtherEngine::OtherEngine(application_features::ApplicationServer* server) + : StorageEngine(server, "otherEngine") { } -ArangoEngine::~ArangoEngine() { +OtherEngine::~OtherEngine() { } // add the storage engine's specifc options to the global list of options -void ArangoEngine::collectOptions(std::shared_ptr) { +void OtherEngine::collectOptions(std::shared_ptr) { } // validate the storage engine's specific options -void ArangoEngine::validateOptions(std::shared_ptr) { +void OtherEngine::validateOptions(std::shared_ptr) { } // preparation phase for storage engine. can be used for internal setup. // the storage engine must not start any threads here or write any files -void ArangoEngine::prepare() { +void OtherEngine::prepare() { } // start the engine. now it's allowed to start engine-specific threads, // write files etc. -void ArangoEngine::start() { +void OtherEngine::start() { } // stop the storage engine. this can be used to flush all data to disk, // shutdown threads etc. it is guaranteed that there will be no read and // write requests to the storage engine after this call -void ArangoEngine::stop() { +void OtherEngine::stop() { } // fill the Builder object with an array of databases that were detected // by the storage engine. this method must sort out databases that were not // fully created (see "createDatabase" below). called at server start only -void ArangoEngine::getDatabases(arangodb::velocypack::Builder& result) { +void OtherEngine::getDatabases(arangodb::velocypack::Builder& result) { } // fill the Builder object with an array of collections (and their corresponding // indexes) that were detected by the storage engine. called at server start only -void ArangoEngine::getCollectionsAndIndexes(arangodb::velocypack::Builder& result) { +void OtherEngine::getCollectionsAndIndexes(arangodb::velocypack::Builder& result) { } // determine the maximum revision id previously handed out by the storage // engine. this value is used as a lower bound for further HLC values handed out by // the server. called at server start only, after getDatabases() and getCollectionsAndIndexes() -uint64_t ArangoEngine::getMaxRevision() { +uint64_t OtherEngine::getMaxRevision() { return 0; // TODO } @@ -83,7 +85,7 @@ uint64_t ArangoEngine::getMaxRevision() { // so that subsequent database creation requests will not fail. // the WAL entry for the database creation will be written *after* the call // to "createDatabase" returns -void ArangoEngine::createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& data) { +void OtherEngine::createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& data) { } // asks the storage engine to drop the specified database and persist the @@ -95,7 +97,7 @@ void ArangoEngine::createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice // check whether the physical deletion of the database is possible. // the WAL entry for database deletion will be written *after* the call // to "dropDatabase" returns -void ArangoEngine::dropDatabase(TRI_voc_tick_t id, std::function const& canRemovePhysically) { +void OtherEngine::dropDatabase(TRI_voc_tick_t id, std::function const& canRemovePhysically) { } // asks the storage engine to create a collection as specified in the VPack @@ -106,8 +108,8 @@ void ArangoEngine::dropDatabase(TRI_voc_tick_t id, std::function const& // and throw only then, so that subsequent collection creation requests will not fail. // the WAL entry for the collection creation will be written *after* the call // to "createCollection" returns -void ArangoEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, - arangodb::velocypack::Slice const& data) { +void OtherEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) { } // asks the storage engine to drop the specified collection and persist the @@ -118,8 +120,8 @@ void ArangoEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, // the actual deletion. // the WAL entry for collection deletion will be written *after* the call // to "dropCollection" returns -void ArangoEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, - std::function const& canRemovePhysically) { +void OtherEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + std::function const& canRemovePhysically) { } // asks the storage engine to rename the collection as specified in the VPack @@ -130,8 +132,8 @@ void ArangoEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, // and throw only then, so that subsequent collection creation/rename requests will // not fail. the WAL entry for the rename will be written *after* the call // to "renameCollection" returns -void ArangoEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, - arangodb::velocypack::Slice const& data) { +void OtherEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) { } // asks the storage engine to change properties of the collection as specified in @@ -140,8 +142,8 @@ void ArangoEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, // property changes and throw only then, so that subsequent operations will not fail. // the WAL entry for the propery change will be written *after* the call // to "changeCollection" returns -void ArangoEngine::changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, - arangodb::velocypack::Slice const& data) { +void OtherEngine::changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) { } // asks the storage engine to create an index as specified in the VPack @@ -153,8 +155,8 @@ void ArangoEngine::changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, // creation requests will not fail. // the WAL entry for the index creation will be written *after* the call // to "createIndex" returns -void ArangoEngine::createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, - TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) { +void OtherEngine::createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) { } // asks the storage engine to drop the specified index and persist the deletion @@ -164,28 +166,28 @@ void ArangoEngine::createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collecti // the actual deletion. // the WAL entry for index deletion will be written *after* the call // to "dropIndex" returns -void ArangoEngine::dropIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, - TRI_idx_iid_t id) { +void OtherEngine::dropIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + TRI_idx_iid_t id) { } // iterate all documents of the underlying collection // this is called when a collection is openend, and all its documents need to be added to // indexes etc. -void ArangoEngine::iterateDocuments(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, - std::function const& cb) { +void OtherEngine::iterateDocuments(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + std::function const& cb) { } // adds a document to the storage engine // this will be called by the WAL collector when surviving documents are being moved // into the storage engine's realm -void ArangoEngine::addDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, - arangodb::velocypack::Slice const& document) { +void OtherEngine::addDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + arangodb::velocypack::Slice const& document) { } // removes a document from the storage engine // this will be called by the WAL collector when non-surviving documents are being removed // from the storage engine's realm -void ArangoEngine::removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, - arangodb::velocypack::Slice const& document) { +void OtherEngine::removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + arangodb::velocypack::Slice const& document) { } diff --git a/arangod/StorageEngine/OtherEngine.h b/arangod/StorageEngine/OtherEngine.h new file mode 100644 index 0000000000..ced8797f59 --- /dev/null +++ b/arangod/StorageEngine/OtherEngine.h @@ -0,0 +1,201 @@ +//////////////////////////////////////////////////////////////////////////////// +/// 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_STORAGE_ENGINE_OTHER_ENGINE_H +#define ARANGOD_STORAGE_ENGINE_OTHER_ENGINE_H 1 + +#include "Basics/Common.h" +#include "StorageEngine/StorageEngine.h" + +namespace arangodb { + +class OtherEngine final : public StorageEngine { + public: + + // create the storage engine + explicit OtherEngine(application_features::ApplicationServer*); + + ~OtherEngine(); + + // inherited from ApplicationFeature + // --------------------------------- + + // add the storage engine's specifc options to the global list of options + void collectOptions(std::shared_ptr) override; + + // validate the storage engine's specific options + void validateOptions(std::shared_ptr) override; + + // preparation phase for storage engine. can be used for internal setup. + // the storage engine must not start any threads here or write any files + void prepare() override; + + // start the engine. now it's allowed to start engine-specific threads, + // write files etc. + void start() override; + + // stop the storage engine. this can be used to flush all data to disk, + // shutdown threads etc. it is guaranteed that there will be no read and + // write requests to the storage engine after this call + void stop() override; + + // status functionality + // -------------------- + + // return the name of the storage engine + char const* typeName() const override { return EngineName.c_str(); } + + // inventory functionality + // ----------------------- + + // fill the Builder object with an array of databases that were detected + // by the storage engine. this method must sort out databases that were not + // fully created (see "createDatabase" below). called at server start only + void getDatabases(arangodb::velocypack::Builder& result) override; + + // fill the Builder object with an array of collections (and their corresponding + // indexes) that were detected by the storage engine. called at server start only + void getCollectionsAndIndexes(arangodb::velocypack::Builder& result) override; + + // determine the maximum revision id previously handed out by the storage + // engine. this value is used as a lower bound for further HLC values handed out by + // the server. called at server start only, after getDatabases() and getCollectionsAndIndexes() + uint64_t getMaxRevision() override; + + // database, collection and index management + // ----------------------------------------- + + // asks the storage engine to create a database as specified in the VPack + // Slice object and persist the creation info. It is guaranteed by the server that + // no other active database with the same name and id exists when this function + // is called. If this operation fails somewhere in the middle, the storage + // engine is required to fully clean up the creation and throw only then, + // so that subsequent database creation requests will not fail. + // the WAL entry for the database creation will be written *after* the call + // to "createDatabase" returns + void createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& data) override; + + // asks the storage engine to drop the specified database and persist the + // deletion info. Note that physical deletion of the database data must not + // be carried out by this call, as there may + // still be readers of the database's data. It is recommended that this operation + // only sets a deletion flag for the database but let's an async task perform + // the actual deletion. The async task can later call the callback function to + // check whether the physical deletion of the database is possible. + // the WAL entry for database deletion will be written *after* the call + // to "dropDatabase" returns + void dropDatabase(TRI_voc_tick_t id, std::function const& canRemovePhysically) override; + + // asks the storage engine to create a collection as specified in the VPack + // Slice object and persist the creation info. It is guaranteed by the server + // that no other active collection with the same name and id exists in the same + // database when this function is called. If this operation fails somewhere in + // the middle, the storage engine is required to fully clean up the creation + // and throw only then, so that subsequent collection creation requests will not fail. + // the WAL entry for the collection creation will be written *after* the call + // to "createCollection" returns + void createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) override; + + // asks the storage engine to drop the specified collection and persist the + // deletion info. Note that physical deletion of the collection data must not + // be carried out by this call, as there may + // still be readers of the collection's data. It is recommended that this operation + // only sets a deletion flag for the collection but let's an async task perform + // the actual deletion. + // the WAL entry for collection deletion will be written *after* the call + // to "dropCollection" returns + void dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + std::function const& canRemovePhysically) override; + + // asks the storage engine to rename the collection as specified in the VPack + // Slice object and persist the renaming info. It is guaranteed by the server + // that no other active collection with the same name and id exists in the same + // database when this function is called. If this operation fails somewhere in + // the middle, the storage engine is required to fully revert the rename operation + // and throw only then, so that subsequent collection creation/rename requests will + // not fail. the WAL entry for the rename will be written *after* the call + // to "renameCollection" returns + void renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) override; + + // asks the storage engine to change properties of the collection as specified in + // the VPack Slice object and persist them. If this operation fails + // somewhere in the middle, the storage engine is required to fully revert the + // property changes and throw only then, so that subsequent operations will not fail. + // the WAL entry for the propery change will be written *after* the call + // to "changeCollection" returns + void changeCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, + arangodb::velocypack::Slice const& data) override; + + // asks the storage engine to create an index as specified in the VPack + // Slice object and persist the creation info. The database id, collection id + // and index data are passed in the Slice object. Note that this function + // is not responsible for inserting the individual documents into the index. + // If this operation fails somewhere in the middle, the storage engine is required + // to fully clean up the creation and throw only then, so that subsequent index + // creation requests will not fail. + // the WAL entry for the index creation will be written *after* the call + // to "createIndex" returns + void createIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) override; + + // asks the storage engine to drop the specified index and persist the deletion + // info. Note that physical deletion of the index must not be carried out by this call, + // as there may still be users of the index. It is recommended that this operation + // only sets a deletion flag for the index but let's an async task perform + // the actual deletion. + // the WAL entry for index deletion will be written *after* the call + // to "dropIndex" returns + void dropIndex(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + TRI_idx_iid_t id) override; + + // document operations + // ------------------- + + // iterate all documents of the underlying collection + // this is called when a collection is openend, and all its documents need to be added to + // indexes etc. + void iterateDocuments(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + std::function const& cb) override; + + + // adds a document to the storage engine + // this will be called by the WAL collector when surviving documents are being moved + // into the storage engine's realm + void addDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + arangodb::velocypack::Slice const& document) override; + + // removes a document from the storage engine + // this will be called by the WAL collector when non-surviving documents are being removed + // from the storage engine's realm + void removeDocumentRevision(TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId, + arangodb::velocypack::Slice const& document) override; + + public: + static std::string const EngineName; +}; + +} + +#endif diff --git a/arangod/StorageEngine/StorageEngine.h b/arangod/StorageEngine/StorageEngine.h index 814d04c971..0a599410a1 100644 --- a/arangod/StorageEngine/StorageEngine.h +++ b/arangod/StorageEngine/StorageEngine.h @@ -45,8 +45,8 @@ class StorageEngine : public application_features::ApplicationFeature { setOptional(true); // storage engines must not use elevated privileges for files etc requiresElevatedPrivileges(false); - // TODO: determine sensible startup order for storage engine - startsAfter("Logger"); + // TODO: determine more sensible startup order for storage engine + startsAfter("EngineSelector"); } // status functionality @@ -55,9 +55,6 @@ class StorageEngine : public application_features::ApplicationFeature { // return the name of the storage engine virtual char const* typeName() const = 0; - // return the version string of the storage engine - virtual char const* versionString() const = 0; - // inventory functionality // -----------------------