1
0
Fork 0

create engine-specific transaction context data

This commit is contained in:
jsteemann 2017-02-27 17:05:30 +01:00
parent e37e94adbe
commit ae751e7360
10 changed files with 228 additions and 47 deletions

View File

@ -250,6 +250,7 @@ SET(ARANGOD_SOURCES
MMFiles/MMFilesSkiplistIndex.cpp MMFiles/MMFilesSkiplistIndex.cpp
MMFiles/MMFilesSynchronizerThread.cpp MMFiles/MMFilesSynchronizerThread.cpp
MMFiles/MMFilesTransactionCollection.cpp MMFiles/MMFilesTransactionCollection.cpp
MMFiles/MMFilesTransactionContextData.cpp
MMFiles/MMFilesTransactionState.cpp MMFiles/MMFilesTransactionState.cpp
MMFiles/MMFilesWalLogfile.cpp MMFiles/MMFilesWalLogfile.cpp
MMFiles/MMFilesWalRecoverState.cpp MMFiles/MMFilesWalRecoverState.cpp

View File

@ -31,10 +31,6 @@
#include "Basics/WriteLocker.h" #include "Basics/WriteLocker.h"
#include "Basics/encoding.h" #include "Basics/encoding.h"
#include "Basics/files.h" #include "Basics/files.h"
#include "Random/RandomGenerator.h"
#include "RestServer/DatabaseFeature.h"
#include "RestServer/DatabasePathFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "MMFiles/MMFilesAqlFunctions.h" #include "MMFiles/MMFilesAqlFunctions.h"
#include "MMFiles/MMFilesCleanupThread.h" #include "MMFiles/MMFilesCleanupThread.h"
#include "MMFiles/MMFilesCompactorThread.h" #include "MMFiles/MMFilesCompactorThread.h"
@ -45,7 +41,12 @@
#include "MMFiles/MMFilesPersistentIndex.h" #include "MMFiles/MMFilesPersistentIndex.h"
#include "MMFiles/MMFilesPersistentIndexFeature.h" #include "MMFiles/MMFilesPersistentIndexFeature.h"
#include "MMFiles/MMFilesTransactionCollection.h" #include "MMFiles/MMFilesTransactionCollection.h"
#include "MMFiles/MMFilesTransactionContextData.h"
#include "MMFiles/MMFilesTransactionState.h" #include "MMFiles/MMFilesTransactionState.h"
#include "Random/RandomGenerator.h"
#include "RestServer/DatabaseFeature.h"
#include "RestServer/DatabasePathFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "VocBase/LogicalCollection.h" #include "VocBase/LogicalCollection.h"
#include "VocBase/ticks.h" #include "VocBase/ticks.h"
#include "VocBase/vocbase.h" #include "VocBase/vocbase.h"
@ -224,6 +225,10 @@ void MMFilesEngine::stop() {
logfileManager->waitForCollector(); logfileManager->waitForCollector();
} }
transaction::ContextData* MMFilesEngine::createTransactionContextData() {
return new MMFilesTransactionContextData;
}
TransactionState* MMFilesEngine::createTransactionState(TRI_vocbase_t* vocbase) { TransactionState* MMFilesEngine::createTransactionState(TRI_vocbase_t* vocbase) {
return new MMFilesTransactionState(vocbase); return new MMFilesTransactionState(vocbase);
} }

View File

@ -40,6 +40,10 @@ class MMFilesCompactorThread;
class TransactionCollection; class TransactionCollection;
class TransactionState; class TransactionState;
namespace transaction {
class ContextData;
}
/// @brief collection file structure /// @brief collection file structure
struct MMFilesEngineCollectionFiles { struct MMFilesEngineCollectionFiles {
std::vector<std::string> journals; std::vector<std::string> journals;
@ -75,6 +79,7 @@ class MMFilesEngine final : public StorageEngine {
// flush wal wait for collector // flush wal wait for collector
void stop() override; void stop() override;
transaction::ContextData* createTransactionContextData() override;
TransactionState* createTransactionState(TRI_vocbase_t*) override; TransactionState* createTransactionState(TRI_vocbase_t*) override;
TransactionCollection* createTransactionCollection(TransactionState* state, TRI_voc_cid_t cid, AccessMode::Type accessType, int nestingLevel) override; TransactionCollection* createTransactionCollection(TransactionState* state, TRI_voc_cid_t cid, AccessMode::Type accessType, int nestingLevel) override;

View File

@ -0,0 +1,75 @@
////////////////////////////////////////////////////////////////////////////////
/// 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 "MMFilesTransactionContextData.h"
#include "MMFiles/MMFilesCollection.h"
#include "MMFiles/MMFilesDitch.h"
#include "VocBase/LogicalCollection.h"
using namespace arangodb;
MMFilesTransactionContextData::MMFilesTransactionContextData() {}
MMFilesTransactionContextData::~MMFilesTransactionContextData() {
for (auto& it : _ditches) {
// we're done with this ditch
auto& ditch = it.second;
ditch->ditches()->freeMMFilesDocumentDitch(ditch, true /* fromTransaction */);
// If some external entity is still using the ditch, it is kept!
}
}
/// @brief pin data for the collection
void MMFilesTransactionContextData::pinData(LogicalCollection* collection) {
TRI_voc_cid_t cid = collection->cid();
auto it = _ditches.find(cid);
if (it != _ditches.end()) {
// tell everyone else this ditch is still in use,
// at least until the transaction is over
TRI_ASSERT((*it).second->usedByTransaction());
// ditch already exists
return;
}
// this method will not throw, but may return a nullptr
auto ditch = arangodb::MMFilesCollection::toMMFilesCollection(collection)->ditches()->createMMFilesDocumentDitch(true, __FILE__, __LINE__);
if (ditch == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
try {
_ditches.emplace(cid, ditch);
}
catch (...) {
ditch->ditches()->freeMMFilesDocumentDitch(ditch, true);
throw;
}
}
/// @brief whether or not the data for the collection is pinned
bool MMFilesTransactionContextData::isPinned(TRI_voc_cid_t cid) const {
return (_ditches.find(cid) != _ditches.end());
}

View File

@ -0,0 +1,53 @@
////////////////////////////////////////////////////////////////////////////////
/// 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_MMFILES_TRANSACTION_CONTEXT_DATA_H
#define ARANGOD_MMFILES_TRANSACTION_CONTEXT_DATA_H 1
#include "Basics/Common.h"
#include "Transaction/ContextData.h"
#include "VocBase/voc-types.h"
namespace arangodb {
class LogicalCollection;
class MMFilesDocumentDitch;
/// @brief transaction type
class MMFilesTransactionContextData final : public transaction::ContextData {
public:
MMFilesTransactionContextData();
~MMFilesTransactionContextData();
/// @brief pin data for the collection
void pinData(arangodb::LogicalCollection*) override;
/// @brief whether or not the data for the collection is pinned
bool isPinned(TRI_voc_cid_t) const override;
private:
std::unordered_map<TRI_voc_cid_t, MMFilesDocumentDitch*> _ditches;
};
}
#endif

View File

@ -45,7 +45,6 @@ class MMFilesWalMarker;
namespace transaction { namespace transaction {
class Methods; class Methods;
} }
;
class TransactionCollection; class TransactionCollection;
/// @brief transaction type /// @brief transaction type

View File

@ -45,6 +45,10 @@ class PhysicalCollection;
class TransactionCollection; class TransactionCollection;
class TransactionState; class TransactionState;
namespace transaction {
class ContextData;
}
class StorageEngine : public application_features::ApplicationFeature { class StorageEngine : public application_features::ApplicationFeature {
public: public:
@ -71,6 +75,7 @@ class StorageEngine : public application_features::ApplicationFeature {
virtual void start() {} virtual void start() {}
virtual void stop() {} virtual void stop() {}
virtual transaction::ContextData* createTransactionContextData() = 0;
virtual TransactionState* createTransactionState(TRI_vocbase_t*) = 0; virtual TransactionState* createTransactionState(TRI_vocbase_t*) = 0;
virtual TransactionCollection* createTransactionCollection(TransactionState*, TRI_voc_cid_t, AccessMode::Type, int nestingLevel) = 0; virtual TransactionCollection* createTransactionCollection(TransactionState*, TRI_voc_cid_t, AccessMode::Type, int nestingLevel) = 0;

View File

@ -27,6 +27,9 @@
#include "MMFiles/MMFilesCollection.h" #include "MMFiles/MMFilesCollection.h"
#include "MMFiles/MMFilesDitch.h" #include "MMFiles/MMFilesDitch.h"
#include "RestServer/TransactionManagerFeature.h" #include "RestServer/TransactionManagerFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
#include "Transaction/ContextData.h"
#include "Transaction/Helpers.h" #include "Transaction/Helpers.h"
#include "Transaction/Methods.h" #include "Transaction/Methods.h"
#include "Utils/CollectionNameResolver.h" #include "Utils/CollectionNameResolver.h"
@ -68,7 +71,6 @@ transaction::Context::Context(TRI_vocbase_t* vocbase)
: _vocbase(vocbase), : _vocbase(vocbase),
_resolver(nullptr), _resolver(nullptr),
_customTypeHandler(), _customTypeHandler(),
_ditches(),
_builders{_arena}, _builders{_arena},
_stringBuffer(), _stringBuffer(),
_options(arangodb::velocypack::Options::Defaults), _options(arangodb::velocypack::Options::Defaults),
@ -85,13 +87,6 @@ transaction::Context::~Context() {
TransactionManagerFeature::MANAGER->unregisterTransaction(_transaction.id, _transaction.hasFailedOperations); TransactionManagerFeature::MANAGER->unregisterTransaction(_transaction.id, _transaction.hasFailedOperations);
} }
for (auto& it : _ditches) {
// we're done with this ditch
auto& ditch = it.second;
ditch->ditches()->freeMMFilesDocumentDitch(ditch, true /* fromTransaction */);
// If some external entity is still using the ditch, it is kept!
}
// free all VPackBuilders we handed out // free all VPackBuilders we handed out
for (auto& it : _builders) { for (auto& it : _builders) {
delete it; delete it;
@ -111,37 +106,12 @@ VPackCustomTypeHandler* transaction::Context::createCustomTypeHandler(TRI_vocbas
/// @brief pin data for the collection /// @brief pin data for the collection
void transaction::Context::pinData(LogicalCollection* collection) { void transaction::Context::pinData(LogicalCollection* collection) {
TRI_voc_cid_t cid = collection->cid(); contextData()->pinData(collection);
auto it = _ditches.find(cid);
if (it != _ditches.end()) {
// tell everyone else this ditch is still in use,
// at least until the transaction is over
TRI_ASSERT((*it).second->usedByTransaction());
// ditch already exists
return;
}
// this method will not throw, but may return a nullptr
auto ditch = arangodb::MMFilesCollection::toMMFilesCollection(collection)->ditches()->createMMFilesDocumentDitch(true, __FILE__, __LINE__);
if (ditch == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
try {
_ditches.emplace(cid, ditch);
}
catch (...) {
ditch->ditches()->freeMMFilesDocumentDitch(ditch, true);
throw;
}
} }
/// @brief whether or not the data for the collection is pinned /// @brief whether or not the data for the collection is pinned
bool transaction::Context::isPinned(TRI_voc_cid_t cid) const { bool transaction::Context::isPinned(TRI_voc_cid_t cid) {
return (_ditches.find(cid) != _ditches.end()); return contextData()->isPinned(cid);
} }
/// @brief temporarily lease a StringBuffer object /// @brief temporarily lease a StringBuffer object
@ -221,3 +191,10 @@ void transaction::Context::storeTransactionResult(TRI_voc_tid_t id, bool hasFail
_transaction.hasFailedOperations = hasFailedOperations; _transaction.hasFailedOperations = hasFailedOperations;
} }
transaction::ContextData* transaction::Context::contextData() {
if (_contextData == nullptr) {
StorageEngine* engine = EngineSelectorFeature::ENGINE;
_contextData.reset(engine->createTransactionContextData());
}
return _contextData.get();
}

View File

@ -43,11 +43,11 @@ struct CustomTypeHandler;
} }
class CollectionNameResolver; class CollectionNameResolver;
class MMFilesDocumentDitch;
class LogicalCollection; class LogicalCollection;
class TransactionState; class TransactionState;
namespace transaction { namespace transaction {
class ContextData;
class Methods; class Methods;
class Context { class Context {
@ -77,7 +77,7 @@ class Context {
void pinData(arangodb::LogicalCollection*); void pinData(arangodb::LogicalCollection*);
/// @brief whether or not the data for the collection is pinned /// @brief whether or not the data for the collection is pinned
bool isPinned(TRI_voc_cid_t) const; bool isPinned(TRI_voc_cid_t);
/// @brief temporarily lease a StringBuffer object /// @brief temporarily lease a StringBuffer object
basics::StringBuffer* leaseStringBuffer(size_t initialSize); basics::StringBuffer* leaseStringBuffer(size_t initialSize);
@ -125,6 +125,8 @@ class Context {
/// @brief create a resolver /// @brief create a resolver
CollectionNameResolver const* createResolver(); CollectionNameResolver const* createResolver();
transaction::ContextData* contextData();
protected: protected:
TRI_vocbase_t* _vocbase; TRI_vocbase_t* _vocbase;
@ -133,8 +135,6 @@ class Context {
std::shared_ptr<velocypack::CustomTypeHandler> _customTypeHandler; std::shared_ptr<velocypack::CustomTypeHandler> _customTypeHandler;
std::unordered_map<TRI_voc_cid_t, MMFilesDocumentDitch*> _ditches;
SmallVector<arangodb::velocypack::Builder*, 32>::allocator_type::arena_type _arena; SmallVector<arangodb::velocypack::Builder*, 32>::allocator_type::arena_type _arena;
SmallVector<arangodb::velocypack::Builder*, 32> _builders; SmallVector<arangodb::velocypack::Builder*, 32> _builders;
@ -143,6 +143,8 @@ class Context {
arangodb::velocypack::Options _options; arangodb::velocypack::Options _options;
arangodb::velocypack::Options _dumpOptions; arangodb::velocypack::Options _dumpOptions;
std::unique_ptr<transaction::ContextData> _contextData;
struct { struct {
TRI_voc_tid_t id; TRI_voc_tid_t id;
bool hasFailedOperations; bool hasFailedOperations;

View File

@ -0,0 +1,59 @@
////////////////////////////////////////////////////////////////////////////////
/// 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_TRANSACTION_CONTEXT_DATA_H
#define ARANGOD_TRANSACTION_CONTEXT_DATA_H 1
#include "Basics/Common.h"
#include "VocBase/voc-types.h"
namespace arangodb {
class LogicalCollection;
namespace transaction {
class ContextData {
public:
ContextData(ContextData const&) = delete;
ContextData& operator=(ContextData const&) = delete;
protected:
/// @brief create the context data
ContextData() = default;
public:
/// @brief destroy the context data
virtual ~ContextData() = default;
/// @brief pin data for the collection
virtual void pinData(arangodb::LogicalCollection*) = 0;
/// @brief whether or not the data for the collection is pinned
virtual bool isPinned(TRI_voc_cid_t) const = 0;
};
}
}
#endif