1
0
Fork 0

simplified internal APIs a bit

This commit is contained in:
jsteemann 2017-02-15 12:42:07 +01:00
parent 112d07f6c2
commit d49c5c3fc0
30 changed files with 133 additions and 219 deletions

View File

@ -35,11 +35,8 @@ namespace aql {
class AqlTransaction final : public transaction::Methods {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief create the transaction and add all collections from the query
/// context
//////////////////////////////////////////////////////////////////////////////
AqlTransaction(
std::shared_ptr<TransactionContext> transactionContext,
std::map<std::string, aql::Collection*> const* collections,
@ -47,9 +44,9 @@ class AqlTransaction final : public transaction::Methods {
: transaction::Methods(transactionContext),
_collections(*collections) {
if (!isMainTransaction) {
addHint(transaction::Hints::Hint::LOCK_NEVER, true);
addHint(transaction::Hints::Hint::LOCK_NEVER);
} else {
addHint(transaction::Hints::Hint::LOCK_ENTIRELY, false);
addHint(transaction::Hints::Hint::LOCK_ENTIRELY);
}
for (auto it : *collections) {
@ -59,20 +56,14 @@ class AqlTransaction final : public transaction::Methods {
}
}
//////////////////////////////////////////////////////////////////////////////
/// @brief end the transaction
//////////////////////////////////////////////////////////////////////////////
~AqlTransaction() {}
//////////////////////////////////////////////////////////////////////////////
/// @brief add a list of collections to the transaction
//////////////////////////////////////////////////////////////////////////////
int addCollectionList(
std::map<std::string, aql::Collection*>* collections) {
int addCollections(
std::map<std::string, aql::Collection*> const& collections) {
int ret = TRI_ERROR_NO_ERROR;
for (auto it : *collections) {
for (auto const& it : collections) {
ret = processCollection(it.second);
if (ret != TRI_ERROR_NO_ERROR) {
break;
@ -81,65 +72,36 @@ class AqlTransaction final : public transaction::Methods {
return ret;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief add a collection to the transaction
//////////////////////////////////////////////////////////////////////////////
int processCollection(aql::Collection*);
//////////////////////////////////////////////////////////////////////////////
/// @brief add a coordinator collection to the transaction
//////////////////////////////////////////////////////////////////////////////
int processCollectionCoordinator(aql::Collection*);
//////////////////////////////////////////////////////////////////////////////
/// @brief add a regular collection to the transaction
//////////////////////////////////////////////////////////////////////////////
int processCollectionNormal(aql::Collection* collection);
//////////////////////////////////////////////////////////////////////////////
/// @brief ditch
//////////////////////////////////////////////////////////////////////////////
DocumentDitch* ditch(TRI_voc_cid_t cid) {
return _transactionContext->ditch(cid);
}
//////////////////////////////////////////////////////////////////////////////
/// @brief documentCollection
//////////////////////////////////////////////////////////////////////////////
LogicalCollection* documentCollection(TRI_voc_cid_t cid);
//////////////////////////////////////////////////////////////////////////////
/// @brief clone, used to make daughter transactions for parts of a
/// distributed
/// AQL query running on the coordinator
//////////////////////////////////////////////////////////////////////////////
transaction::Methods* clone() const override {
return new AqlTransaction(StandaloneTransactionContext::Create(vocbase()),
&_collections, false);
}
//////////////////////////////////////////////////////////////////////////////
/// @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 lockCollections() override;
//////////////////////////////////////////////////////////////////////////////
/// @brief keep a copy of the collections, this is needed for the clone
/// operation
//////////////////////////////////////////////////////////////////////////////
private:
std::map<std::string, aql::Collection*> _collections;
};

View File

@ -22,12 +22,14 @@
////////////////////////////////////////////////////////////////////////////////
#include "CalculationBlock.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/Functions.h"
#include "Basics/Exceptions.h"
#include "Basics/ScopeGuard.h"
#include "Basics/VelocyPackHelper.h"
#include "StorageEngine/TransactionState.h"
#include "Transaction/Methods.h"
#include "V8/v8-globals.h"
#include "VocBase/vocbase.h"

View File

@ -26,6 +26,7 @@
#include "Aql/AqlItemBlock.h"
#include "Aql/AqlValue.h"
#include "Aql/BlockCollector.h"
#include "Aql/Collection.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/ExecutionStats.h"
#include "Basics/Exceptions.h"

View File

@ -22,6 +22,8 @@
////////////////////////////////////////////////////////////////////////////////
#include "EnumerateListBlock.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/AqlValue.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/Exceptions.h"
#include "VocBase/vocbase.h"

View File

@ -46,6 +46,7 @@
#include "Cluster/ClusterInfo.h"
#include "Cluster/TraverserEngineRegistry.h"
#include "Logger/Logger.h"
#include "Transaction/Methods.h"
#include "VocBase/ticks.h"
using namespace arangodb;
@ -1131,6 +1132,29 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
engines[currentEngineId].nodes.emplace_back(en);
}
};
/// @brief shutdown, will be called exactly once for the whole query
int ExecutionEngine::shutdown(int errorCode) {
if (_root != nullptr && !_wasShutdown) {
// Take care of locking prevention measures in the cluster:
if (_lockedShards != nullptr) {
if (transaction::Methods::_makeNolockHeaders == _lockedShards) {
transaction::Methods::_makeNolockHeaders = _previouslyLockedShards;
}
delete _lockedShards;
_lockedShards = nullptr;
_previouslyLockedShards = nullptr;
}
// prevent a duplicate shutdown
int res = _root->shutdown(errorCode);
_wasShutdown = true;
return res;
}
return TRI_ERROR_NO_ERROR;
}
/// @brief create an execution engine from a plan
ExecutionEngine* ExecutionEngine::instantiateFromPlan(

View File

@ -25,9 +25,7 @@
#define ARANGOD_AQL_EXECUTION_ENGINE_H 1
#include "Basics/Common.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/AqlItemBlockManager.h"
#include "Aql/AqlTransaction.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionPlan.h"
#include "Aql/ExecutionStats.h"
@ -35,6 +33,7 @@
namespace arangodb {
namespace aql {
class AqlItemBlock;
class ExecutionEngine {
public:
@ -75,27 +74,7 @@ class ExecutionEngine {
}
/// @brief shutdown, will be called exactly once for the whole query
int shutdown(int errorCode) {
if (_root != nullptr && !_wasShutdown) {
// Take care of locking prevention measures in the cluster:
if (_lockedShards != nullptr) {
if (transaction::Methods::_makeNolockHeaders == _lockedShards) {
transaction::Methods::_makeNolockHeaders = _previouslyLockedShards;
}
delete _lockedShards;
_lockedShards = nullptr;
_previouslyLockedShards = nullptr;
}
// prevent a duplicate shutdown
int res = _root->shutdown(errorCode);
_wasShutdown = true;
return res;
}
return TRI_ERROR_NO_ERROR;
}
int shutdown(int errorCode);
/// @brief getSome
AqlItemBlock* getSome(size_t atLeast, size_t atMost) {

View File

@ -23,6 +23,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "IndexBlock.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/Collection.h"
#include "Aql/Condition.h"
#include "Aql/ExecutionEngine.h"

View File

@ -22,7 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "ModificationBlocks.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/AqlValue.h"
#include "Aql/Collection.h"
#include "Aql/ExecutionEngine.h"

View File

@ -3943,11 +3943,7 @@ void arangodb::aql::inlineSubqueriesRule(Optimizer* opt,
opt->addPlan(std::move(plan), rule, modified);
}
///////////////////////////////////////////////////////////////////////////////
// GEO RULE ///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
struct MMFilesGeoIndexInfo{
struct MMFilesGeoIndexInfo {
operator bool() const { return distanceNode && valid; }
void invalidate() { valid = false; }
MMFilesGeoIndexInfo()
@ -3984,7 +3980,6 @@ struct MMFilesGeoIndexInfo{
std::pair<AstNode*,AstNode*> constantPair;
};
//////////////////////////////////////////////////////////////////////
//candidate checking
AstNode* isValueOrRefNode(AstNode* node){
@ -4265,7 +4260,6 @@ MMFilesGeoIndexInfo identifyGeoOptimizationCandidate(ExecutionNode::NodeType typ
return rv;
};
//////////////////////////////////////////////////////////////////////
//modify plan
// builds a condition that can be used with the index interface and

View File

@ -23,10 +23,7 @@
#include "Query.h"
#include <velocypack/Builder.h>
#include <velocypack/Iterator.h>
#include <velocypack/velocypack-aliases.h>
#include "Aql/AqlItemBlock.h"
#include "Aql/AqlTransaction.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionEngine.h"
@ -53,6 +50,10 @@
#include "VocBase/Graphs.h"
#include "VocBase/vocbase.h"
#include <velocypack/Builder.h>
#include <velocypack/Iterator.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb;
using namespace arangodb::aql;
@ -541,7 +542,7 @@ QueryResult Query::prepare(QueryRegistry* registry) {
enterState(LOADING_COLLECTIONS);
int res = trx->addCollectionList(_collections.collections());
int res = trx->addCollections(*_collections.collections());
if (res == TRI_ERROR_NO_ERROR) {
res = trx->begin();

View File

@ -22,11 +22,12 @@
////////////////////////////////////////////////////////////////////////////////
#include "QueryRegistry.h"
#include "Logger/Logger.h"
#include "Basics/ReadLocker.h"
#include "Basics/WriteLocker.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/Query.h"
#include "Basics/ReadLocker.h"
#include "Basics/WriteLocker.h"
#include "Logger/Logger.h"
#include "Transaction/Methods.h"
using namespace arangodb::aql;

View File

@ -22,10 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "RestAqlHandler.h"
#include <velocypack/Dumper.h>
#include <velocypack/velocypack-aliases.h>
#include "Aql/AqlItemBlock.h"
#include "Aql/ClusterBlocks.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionEngine.h"
@ -40,8 +37,13 @@
#include "Scheduler/JobGuard.h"
#include "Scheduler/JobQueue.h"
#include "Scheduler/SchedulerFeature.h"
#include "Transaction/Methods.h"
#include "Utils/TransactionContext.h"
#include "VocBase/ticks.h"
#include <velocypack/Dumper.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb;
using namespace arangodb::rest;
using namespace arangodb::aql;

View File

@ -22,6 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "ShortestPathBlock.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/ExecutionPlan.h"
#include "Utils/OperationCursor.h"
@ -33,10 +34,7 @@
#include <velocypack/Iterator.h>
#include <velocypack/velocypack-aliases.h>
////////////////////////////////////////////////////////////////////////////////
/// @brief typedef the template instantiation of the PathFinder
////////////////////////////////////////////////////////////////////////////////
typedef arangodb::basics::DynamicDistanceFinder<
arangodb::velocypack::Slice, arangodb::velocypack::Slice, double,
arangodb::traverser::ShortestPath> ArangoDBPathFinder;
@ -52,11 +50,8 @@ typedef arangodb::basics::ConstDistanceFinder<arangodb::velocypack::Slice,
using namespace arangodb::aql;
////////////////////////////////////////////////////////////////////////////////
/// @brief Local class to expand edges.
/// Will be handed over to the path finder
////////////////////////////////////////////////////////////////////////////////
namespace arangodb {
namespace aql {
struct ConstDistanceExpanderLocal {
@ -110,11 +105,8 @@ struct ConstDistanceExpanderLocal {
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Cluster class to expand edges.
/// Will be handed over to the path finder
////////////////////////////////////////////////////////////////////////////////
struct ConstDistanceExpanderCluster {
private:
@ -165,10 +157,7 @@ struct ConstDistanceExpanderCluster {
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Expander for weighted edges
////////////////////////////////////////////////////////////////////////////////
struct EdgeWeightExpanderLocal {
private:
@ -246,10 +235,7 @@ struct EdgeWeightExpanderLocal {
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Expander for weighted edges
////////////////////////////////////////////////////////////////////////////////
struct EdgeWeightExpanderCluster {
private:

View File

@ -22,6 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "SortBlock.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/Exceptions.h"
#include "VocBase/vocbase.h"

View File

@ -22,6 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "SubqueryBlock.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Basics/Exceptions.h"
#include "VocBase/vocbase.h"

View File

@ -22,6 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "TraversalBlock.h"
#include "Aql/AqlItemBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/ExecutionNode.h"
#include "Aql/ExecutionPlan.h"

View File

@ -237,39 +237,27 @@ int Aqlparse (arangodb::aql::Parser* parser);
using namespace arangodb::aql;
////////////////////////////////////////////////////////////////////////////////
/// @brief shortcut macro for signaling out of memory
////////////////////////////////////////////////////////////////////////////////
#define ABORT_OOM \
parser->registerError(TRI_ERROR_OUT_OF_MEMORY); \
YYABORT;
#define scanner parser->scanner()
////////////////////////////////////////////////////////////////////////////////
/// @brief forward for lexer function defined in Aql/tokens.ll
////////////////////////////////////////////////////////////////////////////////
int Aqllex (YYSTYPE*,
YYLTYPE*,
void*);
////////////////////////////////////////////////////////////////////////////////
/// @brief register parse error
////////////////////////////////////////////////////////////////////////////////
void Aqlerror (YYLTYPE* locp,
arangodb::aql::Parser* parser,
char const* message) {
parser->registerParseError(TRI_ERROR_QUERY_PARSE, message, locp->first_line, locp->first_column);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check if any of the variables used in the INTO expression were
/// introduced by the COLLECT itself, in which case it would fail
////////////////////////////////////////////////////////////////////////////////
static Variable const* CheckIntoVariables(AstNode const* collectVars,
std::unordered_set<Variable const*> const& vars) {
if (collectVars == nullptr || collectVars->type != NODE_TYPE_ARRAY) {
@ -292,10 +280,7 @@ static Variable const* CheckIntoVariables(AstNode const* collectVars,
return nullptr;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief register variables in the scope
////////////////////////////////////////////////////////////////////////////////
static void RegisterAssignVariables(arangodb::aql::Scopes* scopes, AstNode const* vars) {
size_t const n = vars->numMembers();
for (size_t i = 0; i < n; ++i) {
@ -309,10 +294,7 @@ static void RegisterAssignVariables(arangodb::aql::Scopes* scopes, AstNode const
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief validate the aggregate variables expressions
////////////////////////////////////////////////////////////////////////////////
static bool ValidateAggregates(Parser* parser, AstNode const* aggregates) {
size_t const n = aggregates->numMembers();
@ -346,10 +328,7 @@ static bool ValidateAggregates(Parser* parser, AstNode const* aggregates) {
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief start a new scope for the collect
////////////////////////////////////////////////////////////////////////////////
static bool StartCollectScope(arangodb::aql::Scopes* scopes) {
// check if we are in the main scope
if (scopes->type() == arangodb::aql::AQL_SCOPE_MAIN) {
@ -363,10 +342,7 @@ static bool StartCollectScope(arangodb::aql::Scopes* scopes) {
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the INTO variable stored in a node (may not exist)
////////////////////////////////////////////////////////////////////////////////
static AstNode const* GetIntoVariable(Parser* parser, AstNode const* node) {
if (node == nullptr) {
return nullptr;
@ -386,10 +362,7 @@ static AstNode const* GetIntoVariable(Parser* parser, AstNode const* node) {
return parser->ast()->createNodeVariable(v->getStringValue(), v->getStringLength(), true);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the INTO variable = expression stored in a node (may not exist)
////////////////////////////////////////////////////////////////////////////////
static AstNode const* GetIntoExpression(AstNode const* node) {
if (node == nullptr || node->type == NODE_TYPE_VALUE) {
return nullptr;

View File

@ -646,14 +646,12 @@ int MMFilesCollectorThread::processCollectionOperations(MMFilesCollectorCache* c
arangodb::SingleCollectionTransaction trx(
arangodb::StandaloneTransactionContext::Create(collection->vocbase()),
collection->cid(), AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::NO_USAGE_LOCK,
true); // already locked by guard above
trx.addHint(transaction::Hints::Hint::NO_COMPACTION_LOCK,
true); // already locked above
trx.addHint(transaction::Hints::Hint::NO_THROTTLING, true);
trx.addHint(transaction::Hints::Hint::NO_BEGIN_MARKER, true);
trx.addHint(transaction::Hints::Hint::NO_ABORT_MARKER, true);
trx.addHint(transaction::Hints::Hint::TRY_LOCK, true);
trx.addHint(transaction::Hints::Hint::NO_USAGE_LOCK); // already locked by guard above
trx.addHint(transaction::Hints::Hint::NO_COMPACTION_LOCK); // already locked above
trx.addHint(transaction::Hints::Hint::NO_THROTTLING);
trx.addHint(transaction::Hints::Hint::NO_BEGIN_MARKER);
trx.addHint(transaction::Hints::Hint::NO_ABORT_MARKER);
trx.addHint(transaction::Hints::Hint::TRY_LOCK);
int res = trx.begin();

View File

@ -429,10 +429,10 @@ void MMFilesCompactorThread::compactDatafiles(LogicalCollection* collection,
arangodb::SingleCollectionTransaction trx(arangodb::StandaloneTransactionContext::Create(collection->vocbase()),
collection->cid(), AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::NO_BEGIN_MARKER, true);
trx.addHint(transaction::Hints::Hint::NO_ABORT_MARKER, true);
trx.addHint(transaction::Hints::Hint::NO_COMPACTION_LOCK, true);
trx.addHint(transaction::Hints::Hint::NO_THROTTLING, true);
trx.addHint(transaction::Hints::Hint::NO_BEGIN_MARKER);
trx.addHint(transaction::Hints::Hint::NO_ABORT_MARKER);
trx.addHint(transaction::Hints::Hint::NO_COMPACTION_LOCK);
trx.addHint(transaction::Hints::Hint::NO_THROTTLING);
CompactionInitialContext initial = getCompactionContext(&trx, collection, toCompact);
@ -959,8 +959,8 @@ uint64_t MMFilesCompactorThread::getNumberOfDocuments(LogicalCollection* collect
AccessMode::Type::READ);
// only try to acquire the lock here
// if lock acquisition fails, we go on and report an (arbitrary) positive number
trx.addHint(transaction::Hints::Hint::TRY_LOCK, false);
trx.addHint(transaction::Hints::Hint::NO_THROTTLING, true);
trx.addHint(transaction::Hints::Hint::TRY_LOCK);
trx.addHint(transaction::Hints::Hint::NO_THROTTLING);
int res = trx.begin();

View File

@ -283,12 +283,12 @@ int MMFilesWalRecoverState::executeSingleOperation(
try {
SingleCollectionTransaction trx(arangodb::StandaloneTransactionContext::Create(vocbase), collectionId, AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::NO_BEGIN_MARKER, false);
trx.addHint(transaction::Hints::Hint::NO_ABORT_MARKER, false);
trx.addHint(transaction::Hints::Hint::NO_THROTTLING, false);
trx.addHint(transaction::Hints::Hint::LOCK_NEVER, false);
trx.addHint(transaction::Hints::Hint::RECOVERY, false); // to turn off waitForSync!
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
trx.addHint(transaction::Hints::Hint::NO_BEGIN_MARKER);
trx.addHint(transaction::Hints::Hint::NO_ABORT_MARKER);
trx.addHint(transaction::Hints::Hint::NO_THROTTLING);
trx.addHint(transaction::Hints::Hint::LOCK_NEVER);
trx.addHint(transaction::Hints::Hint::RECOVERY); // to turn off waitForSync!
res = trx.begin();

View File

@ -573,7 +573,7 @@ int ContinuousSyncer::processDocument(TRI_replication_operation_e type,
// update the apply tick for all standalone operations
SingleCollectionTransaction trx(StandaloneTransactionContext::Create(_vocbase),
cid, AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
int res = trx.begin();

View File

@ -128,7 +128,7 @@ bool RestDocumentHandler::createDocument() {
AccessMode::Type::WRITE);
bool const isMultiple = body.isArray();
if (!isMultiple) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
}
int res = trx.begin();
@ -233,7 +233,7 @@ bool RestDocumentHandler::readSingleDocument(bool generateBody) {
auto transactionContext(StandaloneTransactionContext::Create(_vocbase));
SingleCollectionTransaction trx(transactionContext, collection,
AccessMode::Type::READ);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
// ...........................................................................
// inside read transaction
@ -421,7 +421,7 @@ bool RestDocumentHandler::modifyDocument(bool isPatch) {
SingleCollectionTransaction trx(transactionContext, collectionName,
AccessMode::Type::WRITE);
if (!isArrayCase) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
}
// ...........................................................................
@ -546,7 +546,7 @@ bool RestDocumentHandler::deleteDocument() {
SingleCollectionTransaction trx(transactionContext, collectionName,
AccessMode::Type::WRITE);
if (suffixes.size() == 2 || !search.isArray()) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
}
int res = trx.begin();

View File

@ -1503,8 +1503,7 @@ int RestReplicationHandler::processRestoreCollection(
SingleCollectionTransaction trx(
StandaloneTransactionContext::Create(_vocbase), col->cid(),
AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::RECOVERY,
false); // to turn off waitForSync!
trx.addHint(transaction::Hints::Hint::RECOVERY); // to turn off waitForSync!
res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
@ -2259,8 +2258,7 @@ int RestReplicationHandler::processRestoreData(
SingleCollectionTransaction trx(
StandaloneTransactionContext::Create(_vocbase), colName,
AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::RECOVERY,
false); // to turn off waitForSync!
trx.addHint(transaction::Hints::Hint::RECOVERY); // to turn off waitForSync!
int res = trx.begin();
@ -3448,7 +3446,7 @@ void RestReplicationHandler::handleCommandHoldReadLockCollection() {
auto trxContext = StandaloneTransactionContext::Create(_vocbase);
SingleCollectionTransaction trx(trxContext, col->cid(), AccessMode::Type::READ);
trx.addHint(transaction::Hints::Hint::LOCK_ENTIRELY, false);
trx.addHint(transaction::Hints::Hint::LOCK_ENTIRELY);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
generateError(rest::ResponseCode::SERVER_ERROR,

View File

@ -74,6 +74,9 @@ class TransactionState {
TRI_ASSERT(_nestingLevel > 0);
return --_nestingLevel;
}
int nestingLevel() const { return _nestingLevel; }
bool isTopLevelTransaction() const { return _nestingLevel == 0; }
bool isEmbeddedTransaction() const { return !isTopLevelTransaction(); }
double timeout() const { return _timeout; }
void timeout(double value) {

View File

@ -162,22 +162,13 @@ void transaction::Methods::IndexHandle::toVelocyPack(
TRI_vocbase_t* transaction::Methods::vocbase() const { return _state->vocbase(); }
/// @brief add a transaction hint
void transaction::Methods::addHint(transaction::Hints::Hint hint, bool passthrough) {
_hints.set(hint);
if (passthrough) {
_state->setHint(hint);
}
}
/// @brief whether or not the transaction consists of a single operation only
bool transaction::Methods::isSingleOperationTransaction() const {
return _state->isSingleOperation();
}
/// @brief get the status of the transaction
transaction::Status transaction::Methods::getStatus() const {
transaction::Status transaction::Methods::status() const {
return _state->status();
}
@ -551,7 +542,7 @@ thread_local std::unordered_set<std::string>* transaction::Methods::_makeNolockH
transaction::Methods::Methods(std::shared_ptr<TransactionContext> transactionContext)
: _nestingLevel(0),
_hints(0),
_hints(),
_state(nullptr),
_resolver(nullptr),
_transactionContext(transactionContext),
@ -579,21 +570,21 @@ transaction::Methods::Methods(std::shared_ptr<TransactionContext> transactionCon
/// @brief destroy the transaction
transaction::Methods::~Methods() {
if (isEmbeddedTransaction()) {
if (_state->isEmbeddedTransaction()) {
_state->decreaseNesting();
} else {
if (getStatus() == transaction::Status::RUNNING) {
if (_state->status() == transaction::Status::RUNNING) {
// auto abort a running transaction
try {
this->abort();
TRI_ASSERT(getStatus() != transaction::Status::RUNNING);
TRI_ASSERT(_state->status() != transaction::Status::RUNNING);
} catch (...) {
// must never throw because we are in a dtor
}
}
// free the state associated with the transaction
TRI_ASSERT(getStatus() != transaction::Status::RUNNING);
TRI_ASSERT(_state->status() != transaction::Status::RUNNING);
// store result
_transactionContextPtr->storeTransactionResult(_state->id(), _state->hasFailedOperations());
_transactionContextPtr->unregisterTransaction();
@ -615,7 +606,7 @@ CollectionNameResolver const* transaction::Methods::resolver() {
/// @brief return the transaction collection for a document collection
TransactionCollection* transaction::Methods::trxCollection(TRI_voc_cid_t cid) const {
TRI_ASSERT(_state != nullptr);
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
return _state->collection(cid, AccessMode::Type::READ);
}
@ -623,8 +614,8 @@ TransactionCollection* transaction::Methods::trxCollection(TRI_voc_cid_t cid) co
/// @brief order a ditch for a collection
DocumentDitch* transaction::Methods::orderDitch(TRI_voc_cid_t cid) {
TRI_ASSERT(_state != nullptr);
TRI_ASSERT(getStatus() == transaction::Status::RUNNING ||
getStatus() == transaction::Status::CREATED);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING ||
_state->status() == transaction::Status::CREATED);
if (_ditchCache.cid == cid) {
return _ditchCache.ditch;
@ -764,7 +755,7 @@ int transaction::Methods::begin() {
/// @brief commit / finish the transaction
int transaction::Methods::commit() {
if (_state == nullptr || getStatus() != transaction::Status::RUNNING) {
if (_state == nullptr || _state->status() != transaction::Status::RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INTERNAL;
}
@ -781,7 +772,7 @@ int transaction::Methods::commit() {
/// @brief abort the transaction
int transaction::Methods::abort() {
if (_state == nullptr || getStatus() != transaction::Status::RUNNING) {
if (_state == nullptr || _state->status() != transaction::Status::RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INTERNAL;
}
@ -966,7 +957,7 @@ std::string transaction::Methods::collectionName(TRI_voc_cid_t cid) {
/// @brief Iterate over all elements of the collection.
void transaction::Methods::invokeOnAllElements(std::string const& collectionName,
std::function<bool(DocumentIdentifierToken const&)> callback) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
if (_state->isCoordinator()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
}
@ -1004,7 +995,7 @@ int transaction::Methods::documentFastPath(std::string const& collectionName,
VPackSlice const value,
VPackBuilder& result,
bool shouldLock) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
if (!value.isObject() && !value.isString()) {
// must provide a document object or string
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
@ -1064,7 +1055,7 @@ int transaction::Methods::documentFastPath(std::string const& collectionName,
int transaction::Methods::documentFastPathLocal(std::string const& collectionName,
std::string const& key,
ManagedDocumentResult& result) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
TRI_voc_cid_t cid = addCollectionAtRuntime(collectionName);
LogicalCollection* collection = documentCollection(trxCollection(cid));
@ -1187,7 +1178,7 @@ OperationResult transaction::Methods::clusterResultRemove(
OperationResult transaction::Methods::document(std::string const& collectionName,
VPackSlice const value,
OperationOptions& options) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
if (!value.isObject() && !value.isArray()) {
// must provide a document object or an array of documents
@ -1324,7 +1315,7 @@ OperationResult transaction::Methods::documentLocal(std::string const& collectio
OperationResult transaction::Methods::insert(std::string const& collectionName,
VPackSlice const value,
OperationOptions const& options) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
if (!value.isObject() && !value.isArray()) {
// must provide a document object or an array of documents
@ -1581,7 +1572,7 @@ OperationResult transaction::Methods::insertLocal(std::string const& collectionN
OperationResult transaction::Methods::update(std::string const& collectionName,
VPackSlice const newValue,
OperationOptions const& options) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
if (!newValue.isObject() && !newValue.isArray()) {
// must provide a document object or an array of documents
@ -1632,7 +1623,7 @@ OperationResult transaction::Methods::updateCoordinator(std::string const& colle
OperationResult transaction::Methods::replace(std::string const& collectionName,
VPackSlice const newValue,
OperationOptions const& options) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
if (!newValue.isObject() && !newValue.isArray()) {
// must provide a document object or an array of documents
@ -1891,7 +1882,7 @@ OperationResult transaction::Methods::modifyLocal(
OperationResult transaction::Methods::remove(std::string const& collectionName,
VPackSlice const value,
OperationOptions const& options) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
if (!value.isObject() && !value.isArray() && !value.isString()) {
// must provide a document object or an array of documents
@ -2132,7 +2123,7 @@ OperationResult transaction::Methods::removeLocal(std::string const& collectionN
OperationResult transaction::Methods::all(std::string const& collectionName,
uint64_t skip, uint64_t limit,
OperationOptions const& options) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
OperationOptions optionsCopy = options;
@ -2204,7 +2195,7 @@ OperationResult transaction::Methods::allLocal(std::string const& collectionName
/// @brief remove all documents in a collection
OperationResult transaction::Methods::truncate(std::string const& collectionName,
OperationOptions const& options) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
OperationOptions optionsCopy = options;
OperationResult result;
@ -2311,7 +2302,7 @@ OperationResult transaction::Methods::truncateLocal(std::string const& collectio
/// @brief count the number of documents in a collection
OperationResult transaction::Methods::count(std::string const& collectionName, bool aggregate) {
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
if (_state->isCoordinator()) {
return countCoordinator(collectionName, aggregate);
@ -2642,7 +2633,7 @@ arangodb::LogicalCollection* transaction::Methods::documentCollection(
TransactionCollection const* trxCollection) const {
TRI_ASSERT(_state != nullptr);
TRI_ASSERT(trxCollection != nullptr);
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
TRI_ASSERT(trxCollection->collection() != nullptr);
return trxCollection->collection();
@ -2652,7 +2643,7 @@ arangodb::LogicalCollection* transaction::Methods::documentCollection(
arangodb::LogicalCollection* transaction::Methods::documentCollection(
TRI_voc_cid_t cid) const {
TRI_ASSERT(_state != nullptr);
TRI_ASSERT(getStatus() == transaction::Status::RUNNING);
TRI_ASSERT(_state->status() == transaction::Status::RUNNING);
auto trxCollection = _state->collection(cid, AccessMode::Type::READ);
@ -2673,7 +2664,7 @@ int transaction::Methods::addCollection(TRI_voc_cid_t cid, char const* name,
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "cannot add collection without state");
}
Status const status = getStatus();
Status const status = _state->status();
if (status == transaction::Status::COMMITTED ||
status == transaction::Status::ABORTED) {
@ -2686,7 +2677,7 @@ int transaction::Methods::addCollection(TRI_voc_cid_t cid, char const* name,
throwCollectionNotFound(name);
}
if (isEmbeddedTransaction()) {
if (_state->isEmbeddedTransaction()) {
return addCollectionEmbedded(cid, name, type);
}
@ -2712,7 +2703,7 @@ int transaction::Methods::addCollection(std::string const& name, AccessMode::Typ
/// @brief test if a collection is already locked
bool transaction::Methods::isLocked(LogicalCollection* document,
AccessMode::Type type) {
if (_state == nullptr || getStatus() != transaction::Status::RUNNING) {
if (_state == nullptr || _state->status() != transaction::Status::RUNNING) {
return false;
}
@ -2725,7 +2716,7 @@ bool transaction::Methods::isLocked(LogicalCollection* document,
/// @brief read- or write-lock a collection
int transaction::Methods::lock(TransactionCollection* trxCollection,
AccessMode::Type type) {
if (_state == nullptr || getStatus() != transaction::Status::RUNNING) {
if (_state == nullptr || _state->status() != transaction::Status::RUNNING) {
return TRI_ERROR_TRANSACTION_INTERNAL;
}
@ -2735,7 +2726,7 @@ int transaction::Methods::lock(TransactionCollection* trxCollection,
/// @brief read- or write-unlock a collection
int transaction::Methods::unlock(TransactionCollection* trxCollection,
AccessMode::Type type) {
if (_state == nullptr || getStatus() != transaction::Status::RUNNING) {
if (_state == nullptr || _state->status() != transaction::Status::RUNNING) {
return TRI_ERROR_TRANSACTION_INTERNAL;
}
@ -2872,7 +2863,7 @@ int transaction::Methods::addCollectionToplevel(TRI_voc_cid_t cid, char const* n
int res;
if (getStatus() != transaction::Status::CREATED) {
if (_state->status() != transaction::Status::CREATED) {
// transaction already started?
res = TRI_ERROR_TRANSACTION_INTERNAL;
} else {
@ -2899,8 +2890,6 @@ void transaction::Methods::setupEmbedded(TRI_vocbase_t*) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_TRANSACTION_NESTED);
}
TRI_ASSERT(_nestingLevel == 0);
_state = _transactionContextPtr->getParentTransaction();
TRI_ASSERT(_state != nullptr);
@ -2909,8 +2898,6 @@ void transaction::Methods::setupEmbedded(TRI_vocbase_t*) {
/// @brief set up a top-level transaction
void transaction::Methods::setupToplevel(TRI_vocbase_t* vocbase) {
TRI_ASSERT(_nestingLevel == 0);
// we are not embedded. now start our own transaction
StorageEngine* engine = EngineSelectorFeature::ENGINE;
_state = engine->createTransactionState(vocbase);

View File

@ -157,19 +157,16 @@ class Methods {
}
/// @brief add a transaction hint
void addHint(transaction::Hints::Hint hint, bool passthrough);
void addHint(transaction::Hints::Hint hint) { _hints.set(hint); }
/// @brief return the collection name resolver
CollectionNameResolver const* resolver();
/// @brief whether or not the transaction is embedded
inline bool isEmbeddedTransaction() const { return (_nestingLevel > 0); }
/// @brief whether or not the transaction consists of a single operation only
bool isSingleOperationTransaction() const;
/// @brief get the status of the transaction
Status getStatus() const;
Status status() const;
int nestingLevel() const { return _nestingLevel; }

View File

@ -92,7 +92,7 @@ void CollectionExport::run(uint64_t maxWaitTime, size_t limit) {
AccessMode::Type::READ);
// already locked by guard above
trx.addHint(transaction::Hints::Hint::NO_USAGE_LOCK, true);
trx.addHint(transaction::Hints::Hint::NO_USAGE_LOCK);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {

View File

@ -42,7 +42,7 @@ class UserTransaction final : public transaction::Methods {
double lockTimeout, bool waitForSync,
bool allowImplicitCollections)
: transaction::Methods(transactionContext) {
addHint(transaction::Hints::Hint::LOCK_ENTIRELY, false);
addHint(transaction::Hints::Hint::LOCK_ENTIRELY);
for (auto const& it : exclusiveCollections) {
addCollection(it, AccessMode::Type::EXCLUSIVE);

View File

@ -331,7 +331,7 @@ static void ExistsVocbaseVPack(
TRI_ASSERT(search.isObject());
SingleCollectionTransaction trx(transactionContext, collectionName, AccessMode::Type::READ);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
res = trx.begin();
@ -431,7 +431,7 @@ static void DocumentVocbaseCol(
SingleCollectionTransaction trx(transactionContext, collectionName,
AccessMode::Type::READ);
if (!args[0]->IsArray()) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
}
TIMER_STOP(JS_DOCUMENT_CREATE_TRX);
@ -517,7 +517,7 @@ static void DocumentVocbase(
SingleCollectionTransaction trx(transactionContext, collectionName,
AccessMode::Type::READ);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
int res = trx.begin();
@ -609,7 +609,7 @@ static void RemoveVocbaseCol(v8::FunctionCallbackInfo<v8::Value> const& args) {
SingleCollectionTransaction trx(transactionContext, collectionName, AccessMode::Type::WRITE);
if (!args[0]->IsArray()) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
}
int res = trx.begin();
@ -752,7 +752,7 @@ static void RemoveVocbase(v8::FunctionCallbackInfo<v8::Value> const& args) {
SingleCollectionTransaction trx(transactionContext, collectionName,
AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
int res = trx.begin();
@ -1390,7 +1390,7 @@ static void JS_PropertiesVocbaseCol(
isModification ? AccessMode::Type::WRITE : AccessMode::Type::READ);
if (!isModification) {
trx.addHint(transaction::Hints::Hint::NO_USAGE_LOCK, false);
trx.addHint(transaction::Hints::Hint::NO_USAGE_LOCK);
}
int res = trx.begin();
@ -1801,7 +1801,7 @@ static void ModifyVocbaseCol(TRI_voc_document_operation_e operation,
SingleCollectionTransaction trx(transactionContext, collectionName,
AccessMode::Type::WRITE);
if (!args[0]->IsArray()) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
}
int res = trx.begin();
@ -1928,7 +1928,7 @@ static void ModifyVocbase(TRI_voc_document_operation_e operation,
SingleCollectionTransaction trx(transactionContext, collectionName,
AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
@ -2173,7 +2173,7 @@ static void JS_SaveVocbase(v8::FunctionCallbackInfo<v8::Value> const& args) {
auto transactionContext(V8TransactionContext::Create(vocbase, true));
SingleCollectionTransaction trx(transactionContext,
collectionName, AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
res = trx.begin();
@ -2336,7 +2336,7 @@ static void JS_InsertVocbaseCol(
SingleCollectionTransaction trx(transactionContext, collection->cid(),
AccessMode::Type::WRITE);
if (!payloadIsArray) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION, false);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
}
TIMER_STOP(JS_INSERT_CREATE_TRX);

View File

@ -551,7 +551,7 @@ static void JS_GetIndexesVocbaseCol(
V8TransactionContext::Create(collection->vocbase(), true),
collection->cid(), AccessMode::Type::READ);
trx.addHint(transaction::Hints::Hint::NO_USAGE_LOCK, false);
trx.addHint(transaction::Hints::Hint::NO_USAGE_LOCK);
int res = trx.begin();