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/MMFilesSynchronizerThread.cpp
MMFiles/MMFilesTransactionCollection.cpp
MMFiles/MMFilesTransactionContextData.cpp
MMFiles/MMFilesTransactionState.cpp
MMFiles/MMFilesWalLogfile.cpp
MMFiles/MMFilesWalRecoverState.cpp

View File

@ -31,10 +31,6 @@
#include "Basics/WriteLocker.h"
#include "Basics/encoding.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/MMFilesCleanupThread.h"
#include "MMFiles/MMFilesCompactorThread.h"
@ -45,7 +41,12 @@
#include "MMFiles/MMFilesPersistentIndex.h"
#include "MMFiles/MMFilesPersistentIndexFeature.h"
#include "MMFiles/MMFilesTransactionCollection.h"
#include "MMFiles/MMFilesTransactionContextData.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/ticks.h"
#include "VocBase/vocbase.h"
@ -223,7 +224,11 @@ void MMFilesEngine::stop() {
logfileManager->flush(true, true, false);
logfileManager->waitForCollector();
}
transaction::ContextData* MMFilesEngine::createTransactionContextData() {
return new MMFilesTransactionContextData;
}
TransactionState* MMFilesEngine::createTransactionState(TRI_vocbase_t* vocbase) {
return new MMFilesTransactionState(vocbase);
}

View File

@ -40,6 +40,10 @@ class MMFilesCompactorThread;
class TransactionCollection;
class TransactionState;
namespace transaction {
class ContextData;
}
/// @brief collection file structure
struct MMFilesEngineCollectionFiles {
std::vector<std::string> journals;
@ -75,6 +79,7 @@ class MMFilesEngine final : public StorageEngine {
// flush wal wait for collector
void stop() override;
transaction::ContextData* createTransactionContextData() override;
TransactionState* createTransactionState(TRI_vocbase_t*) 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 {
class Methods;
}
;
class TransactionCollection;
/// @brief transaction type

View File

@ -45,6 +45,10 @@ class PhysicalCollection;
class TransactionCollection;
class TransactionState;
namespace transaction {
class ContextData;
}
class StorageEngine : public application_features::ApplicationFeature {
public:
@ -71,6 +75,7 @@ class StorageEngine : public application_features::ApplicationFeature {
virtual void start() {}
virtual void stop() {}
virtual transaction::ContextData* createTransactionContextData() = 0;
virtual TransactionState* createTransactionState(TRI_vocbase_t*) = 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/MMFilesDitch.h"
#include "RestServer/TransactionManagerFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
#include "Transaction/ContextData.h"
#include "Transaction/Helpers.h"
#include "Transaction/Methods.h"
#include "Utils/CollectionNameResolver.h"
@ -68,7 +71,6 @@ transaction::Context::Context(TRI_vocbase_t* vocbase)
: _vocbase(vocbase),
_resolver(nullptr),
_customTypeHandler(),
_ditches(),
_builders{_arena},
_stringBuffer(),
_options(arangodb::velocypack::Options::Defaults),
@ -85,13 +87,6 @@ transaction::Context::~Context() {
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
for (auto& it : _builders) {
delete it;
@ -111,37 +106,12 @@ VPackCustomTypeHandler* transaction::Context::createCustomTypeHandler(TRI_vocbas
/// @brief pin data for the collection
void transaction::Context::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;
}
contextData()->pinData(collection);
}
/// @brief whether or not the data for the collection is pinned
bool transaction::Context::isPinned(TRI_voc_cid_t cid) const {
return (_ditches.find(cid) != _ditches.end());
bool transaction::Context::isPinned(TRI_voc_cid_t cid) {
return contextData()->isPinned(cid);
}
/// @brief temporarily lease a StringBuffer object
@ -220,4 +190,11 @@ void transaction::Context::storeTransactionResult(TRI_voc_tid_t id, bool hasFail
_transaction.id = id;
_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 MMFilesDocumentDitch;
class LogicalCollection;
class TransactionState;
namespace transaction {
class ContextData;
class Methods;
class Context {
@ -77,7 +77,7 @@ class Context {
void pinData(arangodb::LogicalCollection*);
/// @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
basics::StringBuffer* leaseStringBuffer(size_t initialSize);
@ -124,6 +124,8 @@ class Context {
/// @brief create a resolver
CollectionNameResolver const* createResolver();
transaction::ContextData* contextData();
protected:
@ -133,8 +135,6 @@ class Context {
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> _builders;
@ -142,6 +142,8 @@ class Context {
arangodb::velocypack::Options _options;
arangodb::velocypack::Options _dumpOptions;
std::unique_ptr<transaction::ContextData> _contextData;
struct {
TRI_voc_tid_t id;

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