From 2d860fb80e0c81a51a18e5a438460e9759df6bf1 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Thu, 14 Apr 2016 11:30:54 +0200 Subject: [PATCH] Added a cpp file for AqlTransaction. Now only parts of AQL have to be rebuild on cluster changes, not complete AQL --- arangod/Aql/ClusterBlocks.h | 1 + arangod/CMakeLists.txt | 1 + arangod/Utils/AqlTransaction.cpp | 96 +++++++++++++++++++++++++ arangod/Utils/AqlTransaction.h | 56 ++------------- arangod/VocBase/document-collection.cpp | 1 + 5 files changed, 103 insertions(+), 52 deletions(-) create mode 100644 arangod/Utils/AqlTransaction.cpp diff --git a/arangod/Aql/ClusterBlocks.h b/arangod/Aql/ClusterBlocks.h index 43675fdacf..905cacf779 100644 --- a/arangod/Aql/ClusterBlocks.h +++ b/arangod/Aql/ClusterBlocks.h @@ -29,6 +29,7 @@ #include "Aql/ExecutionBlock.h" #include "Aql/ExecutionNode.h" #include "Aql/ExecutionStats.h" +#include "Rest/GeneralRequest.h" struct TRI_json_t; diff --git a/arangod/CMakeLists.txt b/arangod/CMakeLists.txt index c2e9da6c58..b632e233eb 100644 --- a/arangod/CMakeLists.txt +++ b/arangod/CMakeLists.txt @@ -228,6 +228,7 @@ add_executable(${BIN_ARANGOD} Scheduler/TaskManager.cpp Scheduler/TimerTask.cpp Statistics/statistics.cpp + Utils/AqlTransaction.cpp Utils/CollectionExport.cpp Utils/CollectionKeys.cpp Utils/CollectionKeysRepository.cpp diff --git a/arangod/Utils/AqlTransaction.cpp b/arangod/Utils/AqlTransaction.cpp new file mode 100644 index 0000000000..df6dccd67e --- /dev/null +++ b/arangod/Utils/AqlTransaction.cpp @@ -0,0 +1,96 @@ +//////////////////////////////////////////////////////////////////////////////// +/// 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 "AqlTransaction.h" +#include "CollectionNameResolver.h" + +using namespace arangodb; + +/// @brief add a collection to the transaction + +int AqlTransaction::processCollection(aql::Collection* collection) { + int state = setupState(); + + if (state != TRI_ERROR_NO_ERROR) { + return state; + } + + if (ServerState::instance()->isCoordinator()) { + return processCollectionCoordinator(collection); + } + return processCollectionNormal(collection); +} + +/// @brief add a coordinator collection to the transaction + +int AqlTransaction::processCollectionCoordinator(aql::Collection* collection) { + TRI_voc_cid_t cid = + this->resolver()->getCollectionId(collection->getName()); + + return this->addCollection(cid, collection->getName().c_str(), + collection->accessType); +} + +/// @brief add a regular collection to the transaction + +int AqlTransaction::processCollectionNormal(aql::Collection* collection) { + TRI_vocbase_col_t const* col = + this->resolver()->getCollectionStruct(collection->getName()); + TRI_voc_cid_t cid = 0; + + if (col != nullptr) { + cid = col->_cid; + } + + int res = + this->addCollection(cid, collection->getName(), collection->accessType); + + if (res == TRI_ERROR_NO_ERROR && col != nullptr) { + collection->setCollection(const_cast(col)); + } + + return res; +} + +/// @brief lockCollections, this is needed in a corner case in AQL: we need +/// to lock all shards in a controlled way when we set up a distributed +/// execution engine. To this end, we prevent the standard mechanism to +/// lock collections on the DBservers when we instantiate the query. Then, +/// in a second round, we need to lock the shards in exactly the right +/// order via an HTTP call. This method is used to implement that HTTP action. + +int AqlTransaction::lockCollections() { + auto trx = getInternals(); + + for (size_t i = 0; i < trx->_collections._length; i++) { + auto trxCollection = static_cast( + TRI_AtVectorPointer(&trx->_collections, i)); + int res = TRI_LockCollectionTransaction(trxCollection, + trxCollection->_accessType, 0); + if (res != TRI_ERROR_NO_ERROR) { + return res; + } + } + return TRI_ERROR_NO_ERROR; +} + diff --git a/arangod/Utils/AqlTransaction.h b/arangod/Utils/AqlTransaction.h index f4de937a9a..40c1d0e955 100644 --- a/arangod/Utils/AqlTransaction.h +++ b/arangod/Utils/AqlTransaction.h @@ -27,7 +27,6 @@ #include "Basics/Common.h" #include "Aql/Collection.h" #include "Cluster/ServerState.h" -#include "Utils/CollectionNameResolver.h" #include "Utils/StandaloneTransactionContext.h" #include "Utils/Transaction.h" #include "VocBase/transaction.h" @@ -87,53 +86,19 @@ class AqlTransaction : public Transaction { /// @brief add a collection to the transaction ////////////////////////////////////////////////////////////////////////////// - int processCollection(arangodb::aql::Collection* collection) { - int state = setupState(); - - if (state != TRI_ERROR_NO_ERROR) { - return state; - } - - if (ServerState::instance()->isCoordinator()) { - return processCollectionCoordinator(collection); - } - return processCollectionNormal(collection); - } + int processCollection(arangodb::aql::Collection*); ////////////////////////////////////////////////////////////////////////////// /// @brief add a coordinator collection to the transaction ////////////////////////////////////////////////////////////////////////////// - int processCollectionCoordinator(arangodb::aql::Collection* collection) { - TRI_voc_cid_t cid = - this->resolver()->getCollectionId(collection->getName()); - - return this->addCollection(cid, collection->getName().c_str(), - collection->accessType); - } + int processCollectionCoordinator(arangodb::aql::Collection*); ////////////////////////////////////////////////////////////////////////////// /// @brief add a regular collection to the transaction ////////////////////////////////////////////////////////////////////////////// - int processCollectionNormal(arangodb::aql::Collection* collection) { - TRI_vocbase_col_t const* col = - this->resolver()->getCollectionStruct(collection->getName()); - TRI_voc_cid_t cid = 0; - - if (col != nullptr) { - cid = col->_cid; - } - - int res = - this->addCollection(cid, collection->getName(), collection->accessType); - - if (res == TRI_ERROR_NO_ERROR && col != nullptr) { - collection->setCollection(const_cast(col)); - } - - return res; - } + int processCollectionNormal(arangodb::aql::Collection* collection); ////////////////////////////////////////////////////////////////////////////// /// @brief ditch @@ -174,20 +139,7 @@ class AqlTransaction : public Transaction { /// order via an HTTP call. This method is used to implement that HTTP action. ////////////////////////////////////////////////////////////////////////////// - int lockCollections() { - auto trx = getInternals(); - - for (size_t i = 0; i < trx->_collections._length; i++) { - auto trxCollection = static_cast( - TRI_AtVectorPointer(&trx->_collections, i)); - int res = TRI_LockCollectionTransaction(trxCollection, - trxCollection->_accessType, 0); - if (res != TRI_ERROR_NO_ERROR) { - return res; - } - } - return TRI_ERROR_NO_ERROR; - } + int lockCollections(); ////////////////////////////////////////////////////////////////////////////// /// @brief keep a copy of the collections, this is needed for the clone diff --git a/arangod/VocBase/document-collection.cpp b/arangod/VocBase/document-collection.cpp index c60748329e..185d2bdb87 100644 --- a/arangod/VocBase/document-collection.cpp +++ b/arangod/VocBase/document-collection.cpp @@ -43,6 +43,7 @@ #include "Indexes/PrimaryIndex.h" #include "Indexes/SkiplistIndex.h" #include "RestServer/ArangoServer.h" +#include "Utils/CollectionNameResolver.h" #include "Utils/CollectionReadLocker.h" #include "Utils/CollectionWriteLocker.h" #include "Utils/SingleCollectionTransaction.h"