mirror of https://gitee.com/bigwinds/arangodb
some vocbase refactoring
This commit is contained in:
parent
cc5eaea09c
commit
b71e12f6a0
|
@ -82,13 +82,11 @@ static_assert(sizeof(StateNames) / sizeof(std::string) ==
|
|||
/// @brief create a profile
|
||||
Profile::Profile(Query* query)
|
||||
: query(query), results(), stamp(query->startTime()), tracked(false) {
|
||||
auto queryList = static_cast<QueryList*>(query->vocbase()->_queries);
|
||||
auto queryList = query->vocbase()->queryList();
|
||||
|
||||
if (queryList != nullptr) {
|
||||
try {
|
||||
tracked = queryList->insert(query, stamp);
|
||||
} catch (...) {
|
||||
}
|
||||
try {
|
||||
tracked = queryList->insert(query, stamp);
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,13 +94,11 @@ Profile::Profile(Query* query)
|
|||
Profile::~Profile() {
|
||||
// only remove from list when the query was inserted into it...
|
||||
if (tracked) {
|
||||
auto queryList = static_cast<QueryList*>(query->vocbase()->_queries);
|
||||
auto queryList = query->vocbase()->queryList();
|
||||
|
||||
if (queryList != nullptr) {
|
||||
try {
|
||||
queryList->remove(query, stamp);
|
||||
} catch (...) {
|
||||
}
|
||||
try {
|
||||
queryList->remove(query, stamp);
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,8 +106,7 @@ DBServerAgencySyncResult DBServerAgencySync::execute() {
|
|||
auto plan = clusterInfo->getPlan();
|
||||
auto current = clusterInfo->getCurrent();
|
||||
|
||||
TRI_UseVocBase(vocbase);
|
||||
TRI_DEFER(TRI_ReleaseVocBase(vocbase));
|
||||
VocbaseGuard guard(vocbase);
|
||||
|
||||
V8Context* context = V8DealerFeature::DEALER->enterContext(vocbase, true);
|
||||
|
||||
|
|
|
@ -534,7 +534,7 @@ bool HeartbeatThread::handlePlanChangeCoordinator(uint64_t currentPlanVersion) {
|
|||
HasRunOnce = true;
|
||||
}
|
||||
} else {
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
vocbase->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
}
|
||||
|
||||
// result is bigger than batchSize, and a cursor will be created
|
||||
auto cursors = _vocbase->_cursorRepository;
|
||||
auto cursors = _vocbase->cursorRepository();
|
||||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
double ttl = arangodb::basics::VelocyPackHelper::getNumericValue<double>(
|
||||
|
@ -456,8 +456,7 @@ void RestCursorHandler::modifyCursor() {
|
|||
|
||||
std::string const& id = suffix[0];
|
||||
|
||||
auto cursors =
|
||||
static_cast<arangodb::CursorRepository*>(_vocbase->_cursorRepository);
|
||||
auto cursors = _vocbase->cursorRepository();
|
||||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
auto cursorId = static_cast<arangodb::CursorId>(
|
||||
|
@ -526,8 +525,7 @@ void RestCursorHandler::deleteCursor() {
|
|||
|
||||
std::string const& id = suffix[0];
|
||||
|
||||
auto cursors =
|
||||
static_cast<arangodb::CursorRepository*>(_vocbase->_cursorRepository);
|
||||
auto cursors = _vocbase->cursorRepository();
|
||||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
auto cursorId = static_cast<arangodb::CursorId>(
|
||||
|
|
|
@ -274,8 +274,7 @@ void RestExportHandler::createCursor() {
|
|||
// TODO: generalize to calling handler setPayload
|
||||
response->setContentType(HttpResponse::ContentType::JSON);
|
||||
|
||||
auto cursors =
|
||||
static_cast<arangodb::CursorRepository*>(_vocbase->_cursorRepository);
|
||||
auto cursors = _vocbase->cursorRepository();
|
||||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
// create a cursor from the result
|
||||
|
@ -318,8 +317,7 @@ void RestExportHandler::modifyCursor() {
|
|||
|
||||
std::string const& id = suffix[0];
|
||||
|
||||
auto cursors =
|
||||
static_cast<arangodb::CursorRepository*>(_vocbase->_cursorRepository);
|
||||
auto cursors = _vocbase->cursorRepository();
|
||||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
auto cursorId = static_cast<arangodb::CursorId>(
|
||||
|
@ -383,8 +381,7 @@ void RestExportHandler::deleteCursor() {
|
|||
|
||||
std::string const& id = suffix[0];
|
||||
|
||||
auto cursors =
|
||||
static_cast<arangodb::CursorRepository*>(_vocbase->_cursorRepository);
|
||||
auto cursors = _vocbase->cursorRepository();
|
||||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
auto cursorId = static_cast<arangodb::CursorId>(
|
||||
|
|
|
@ -92,7 +92,7 @@ RestHandler::status RestQueryHandler::execute() {
|
|||
|
||||
bool RestQueryHandler::readQueryProperties() {
|
||||
try {
|
||||
auto queryList = static_cast<QueryList*>(_vocbase->_queries);
|
||||
auto queryList = _vocbase->queryList();
|
||||
|
||||
VPackBuilder result;
|
||||
result.add(VPackValue(VPackValueType::Object));
|
||||
|
@ -124,7 +124,7 @@ bool RestQueryHandler::readQueryProperties() {
|
|||
|
||||
bool RestQueryHandler::readQuery(bool slow) {
|
||||
try {
|
||||
auto queryList = static_cast<QueryList*>(_vocbase->_queries);
|
||||
auto queryList = _vocbase->queryList();
|
||||
auto queries = slow ? queryList->listSlow() : queryList->listCurrent();
|
||||
|
||||
VPackBuilder result;
|
||||
|
@ -192,7 +192,7 @@ bool RestQueryHandler::readQuery() {
|
|||
}
|
||||
|
||||
bool RestQueryHandler::deleteQuerySlow() {
|
||||
auto queryList = static_cast<arangodb::aql::QueryList*>(_vocbase->_queries);
|
||||
auto queryList = _vocbase->queryList();
|
||||
queryList->clearSlow();
|
||||
|
||||
VPackBuilder result;
|
||||
|
@ -208,7 +208,7 @@ bool RestQueryHandler::deleteQuerySlow() {
|
|||
|
||||
bool RestQueryHandler::deleteQuery(std::string const& name) {
|
||||
auto id = StringUtils::uint64(name);
|
||||
auto queryList = static_cast<arangodb::aql::QueryList*>(_vocbase->_queries);
|
||||
auto queryList = _vocbase->queryList();
|
||||
TRI_ASSERT(queryList != nullptr);
|
||||
|
||||
auto res = queryList->kill(id);
|
||||
|
@ -276,7 +276,7 @@ bool RestQueryHandler::replaceProperties() {
|
|||
"expecting a JSON object as body");
|
||||
};
|
||||
|
||||
auto queryList = static_cast<arangodb::aql::QueryList*>(_vocbase->_queries);
|
||||
auto queryList = _vocbase->queryList();
|
||||
|
||||
try {
|
||||
bool enabled = queryList->enabled();
|
||||
|
|
|
@ -2798,7 +2798,7 @@ void RestReplicationHandler::handleCommandCreateKeys() {
|
|||
keys->create(tickEnd);
|
||||
size_t const count = keys->count();
|
||||
|
||||
auto keysRepository = _vocbase->_collectionKeys;
|
||||
auto keysRepository = _vocbase->collectionKeys();
|
||||
|
||||
try {
|
||||
keysRepository->store(keys.get());
|
||||
|
@ -2859,7 +2859,7 @@ void RestReplicationHandler::handleCommandGetKeys() {
|
|||
int res = TRI_ERROR_NO_ERROR;
|
||||
|
||||
try {
|
||||
auto keysRepository = _vocbase->_collectionKeys;
|
||||
auto keysRepository = _vocbase->collectionKeys();
|
||||
TRI_ASSERT(keysRepository != nullptr);
|
||||
|
||||
auto collectionKeysId = static_cast<arangodb::CollectionKeysId>(
|
||||
|
@ -2973,7 +2973,7 @@ void RestReplicationHandler::handleCommandFetchKeys() {
|
|||
int res = TRI_ERROR_NO_ERROR;
|
||||
|
||||
try {
|
||||
auto keysRepository = _vocbase->_collectionKeys;
|
||||
auto keysRepository = _vocbase->collectionKeys();
|
||||
TRI_ASSERT(keysRepository != nullptr);
|
||||
|
||||
auto collectionKeysId = static_cast<arangodb::CollectionKeysId>(
|
||||
|
@ -3046,7 +3046,7 @@ void RestReplicationHandler::handleCommandRemoveKeys() {
|
|||
|
||||
std::string const& id = suffix[1];
|
||||
|
||||
auto keys = _vocbase->_collectionKeys;
|
||||
auto keys = _vocbase->collectionKeys();
|
||||
TRI_ASSERT(keys != nullptr);
|
||||
|
||||
auto collectionKeysId = static_cast<arangodb::CollectionKeysId>(
|
||||
|
|
|
@ -174,8 +174,8 @@ void BootstrapFeature::unprepare() {
|
|||
TRI_vocbase_t* vocbase = databaseFeature->useDatabase(id);
|
||||
|
||||
if (vocbase != nullptr) {
|
||||
vocbase->_queries->killAll(true);
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
vocbase->queryList()->killAll(true);
|
||||
vocbase->release();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -183,8 +183,8 @@ void BootstrapFeature::unprepare() {
|
|||
TRI_vocbase_t* vocbase = databaseFeature->useDatabase(name);
|
||||
|
||||
if (vocbase != nullptr) {
|
||||
vocbase->_queries->killAll(true);
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
vocbase->queryList()->killAll(true);
|
||||
vocbase->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ void DatabaseManagerThread::run() {
|
|||
auto theLists = databaseFeature->_databasesLists.load();
|
||||
|
||||
for (TRI_vocbase_t* vocbase : theLists->_droppedDatabases) {
|
||||
if (!TRI_CanRemoveVocBase(vocbase)) {
|
||||
if (!vocbase->canBeDropped()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ void DatabaseManagerThread::run() {
|
|||
for (auto& p : theLists->_coordinatorDatabases) {
|
||||
TRI_vocbase_t* vocbase = p.second;
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
auto cursorRepository = vocbase->_cursorRepository;
|
||||
auto cursorRepository = vocbase->cursorRepository();
|
||||
|
||||
try {
|
||||
cursorRepository->garbageCollect(false);
|
||||
|
@ -460,7 +460,7 @@ int DatabaseFeature::createDatabaseCoordinator(TRI_voc_tick_t id, std::string co
|
|||
}
|
||||
|
||||
// increase reference counter
|
||||
TRI_UseVocBase(vocbase.get());
|
||||
vocbase->use();
|
||||
vocbase->_state = (sig_atomic_t)TRI_VOCBASE_STATE_NORMAL;
|
||||
|
||||
{
|
||||
|
@ -569,7 +569,7 @@ int DatabaseFeature::createDatabase(TRI_voc_tick_t id, std::string const& name,
|
|||
}
|
||||
|
||||
// increase reference counter
|
||||
TRI_UseVocBase(vocbase.get());
|
||||
vocbase->use();
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -634,7 +634,7 @@ int DatabaseFeature::dropDatabaseCoordinator(TRI_voc_tick_t id, bool force) {
|
|||
_databasesProtector.scan();
|
||||
delete oldLists;
|
||||
|
||||
if (TRI_DropVocBase(vocbase)) {
|
||||
if (vocbase->markAsDropped()) {
|
||||
LOG(INFO) << "dropping coordinator database '" << vocbase->name() << "'";
|
||||
res = TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -691,7 +691,7 @@ int DatabaseFeature::dropDatabase(std::string const& name, bool writeMarker, boo
|
|||
// invalidate all entries for the database
|
||||
arangodb::aql::QueryCache::instance()->invalidate(vocbase);
|
||||
|
||||
if (!TRI_DropVocBase(vocbase)) {
|
||||
if (!vocbase->markAsDropped()) {
|
||||
// deleted by someone else?
|
||||
return TRI_ERROR_ARANGO_DATABASE_NOT_FOUND;
|
||||
}
|
||||
|
@ -837,7 +837,7 @@ TRI_vocbase_t* DatabaseFeature::useDatabaseCoordinator(TRI_voc_tick_t id) {
|
|||
TRI_vocbase_t* vocbase = p.second;
|
||||
|
||||
if (vocbase->_id == id) {
|
||||
bool result TRI_UNUSED = TRI_UseVocBase(vocbase);
|
||||
bool result TRI_UNUSED = vocbase->use();
|
||||
|
||||
// if we got here, no one else can have deleted the database
|
||||
TRI_ASSERT(result == true);
|
||||
|
@ -851,30 +851,30 @@ TRI_vocbase_t* DatabaseFeature::useDatabaseCoordinator(std::string const& name)
|
|||
auto unuser(_databasesProtector.use());
|
||||
auto theLists = _databasesLists.load();
|
||||
|
||||
TRI_vocbase_t* vocbase = nullptr;
|
||||
auto it = theLists->_coordinatorDatabases.find(name);
|
||||
|
||||
if (it != theLists->_coordinatorDatabases.end()) {
|
||||
vocbase = it->second;
|
||||
TRI_UseVocBase(vocbase);
|
||||
TRI_vocbase_t* vocbase = it->second;
|
||||
vocbase->use();
|
||||
return vocbase;
|
||||
}
|
||||
|
||||
return vocbase;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TRI_vocbase_t* DatabaseFeature::useDatabase(std::string const& name) {
|
||||
auto unuser(_databasesProtector.use());
|
||||
auto theLists = _databasesLists.load();
|
||||
|
||||
TRI_vocbase_t* vocbase = nullptr;
|
||||
auto it = theLists->_databases.find(name);
|
||||
|
||||
if (it != theLists->_databases.end()) {
|
||||
vocbase = it->second;
|
||||
TRI_UseVocBase(vocbase);
|
||||
TRI_vocbase_t* vocbase = it->second;
|
||||
vocbase->use();
|
||||
return vocbase;
|
||||
}
|
||||
|
||||
return vocbase;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TRI_vocbase_t* DatabaseFeature::useDatabase(TRI_voc_tick_t id) {
|
||||
|
@ -885,7 +885,7 @@ TRI_vocbase_t* DatabaseFeature::useDatabase(TRI_voc_tick_t id) {
|
|||
TRI_vocbase_t* vocbase = p.second;
|
||||
|
||||
if (vocbase->_id == id) {
|
||||
TRI_UseVocBase(vocbase);
|
||||
vocbase->use();
|
||||
return vocbase;
|
||||
}
|
||||
}
|
||||
|
@ -893,12 +893,6 @@ TRI_vocbase_t* DatabaseFeature::useDatabase(TRI_voc_tick_t id) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/// @brief release a previously used database
|
||||
/// this will decrease the reference-counter for the database
|
||||
void DatabaseFeature::releaseDatabase(TRI_vocbase_t* vocbase) {
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
}
|
||||
|
||||
/// @brief lookup a database by its name, not increasing its reference count
|
||||
TRI_vocbase_t* DatabaseFeature::lookupDatabase(std::string const& name) {
|
||||
auto unuser(_databasesProtector.use());
|
||||
|
|
|
@ -94,7 +94,6 @@ class DatabaseFeature final : public application_features::ApplicationFeature {
|
|||
TRI_vocbase_t* useDatabaseCoordinator(TRI_voc_tick_t id);
|
||||
TRI_vocbase_t* useDatabase(std::string const& name);
|
||||
TRI_vocbase_t* useDatabase(TRI_voc_tick_t id);
|
||||
void releaseDatabase(TRI_vocbase_t* vocbase);
|
||||
|
||||
TRI_vocbase_t* lookupDatabase(std::string const& name);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ VocbaseContext::VocbaseContext(GeneralRequest* request, TRI_vocbase_t* vocbase,
|
|||
TRI_ASSERT(_vocbase != nullptr);
|
||||
}
|
||||
|
||||
VocbaseContext::~VocbaseContext() { TRI_ReleaseVocBase(_vocbase); }
|
||||
VocbaseContext::~VocbaseContext() { _vocbase->release(); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not to use special cluster authentication
|
||||
|
|
|
@ -79,7 +79,7 @@ class MMFilesEngine final : public StorageEngine {
|
|||
uint64_t getMaxRevision() override;
|
||||
|
||||
// return the path for a database
|
||||
std::string databasePath(TRI_vocbase_t* vocbase) const override { return databaseDirectory(vocbase->_id); }
|
||||
std::string databasePath(TRI_vocbase_t const* vocbase) const override { return databaseDirectory(vocbase->_id); }
|
||||
|
||||
TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& parameters, bool isUpgrade) override;
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class OtherEngine final : public StorageEngine {
|
|||
uint64_t getMaxRevision() override;
|
||||
|
||||
// return the path for a database
|
||||
std::string databasePath(TRI_vocbase_t*) const override { return "none"; }
|
||||
std::string databasePath(TRI_vocbase_t const*) const override { return "none"; }
|
||||
|
||||
TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& parameters, bool isUpgrade) override {
|
||||
return nullptr;
|
||||
|
|
|
@ -85,7 +85,7 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
virtual uint64_t getMaxRevision() = 0;
|
||||
|
||||
// return the path for a database
|
||||
virtual std::string databasePath(TRI_vocbase_t* vocbase) const = 0;
|
||||
virtual std::string databasePath(TRI_vocbase_t const* vocbase) const = 0;
|
||||
|
||||
virtual TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& parameters, bool isUpgrade) = 0;
|
||||
|
||||
|
|
|
@ -68,16 +68,11 @@ VelocyPackCursor::VelocyPackCursor(TRI_vocbase_t* vocbase, CursorId id,
|
|||
std::shared_ptr<VPackBuilder> extra,
|
||||
double ttl, bool hasCount)
|
||||
: Cursor(id, batchSize, extra, ttl, hasCount),
|
||||
_vocbase(vocbase),
|
||||
_vocbaseGuard(vocbase),
|
||||
_result(std::move(result)),
|
||||
_iterator(_result.result->slice()),
|
||||
_cached(_result.cached) {
|
||||
TRI_ASSERT(_result.result->slice().isArray());
|
||||
TRI_UseVocBase(vocbase);
|
||||
}
|
||||
|
||||
VelocyPackCursor::~VelocyPackCursor() {
|
||||
TRI_ReleaseVocBase(_vocbase);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -200,15 +195,13 @@ ExportCursor::ExportCursor(TRI_vocbase_t* vocbase, CursorId id,
|
|||
arangodb::CollectionExport* ex, size_t batchSize,
|
||||
double ttl, bool hasCount)
|
||||
: Cursor(id, batchSize, nullptr, ttl, hasCount),
|
||||
_vocbase(vocbase),
|
||||
_vocbaseGuard(vocbase),
|
||||
_ex(ex),
|
||||
_size(ex->_documents->size()) {
|
||||
TRI_UseVocBase(vocbase);
|
||||
}
|
||||
|
||||
ExportCursor::~ExportCursor() {
|
||||
delete _ex;
|
||||
TRI_ReleaseVocBase(_vocbase);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -272,7 +265,7 @@ static bool IncludeAttribute(
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExportCursor::dump(arangodb::basics::StringBuffer& buffer) {
|
||||
auto transactionContext = std::make_shared<StandaloneTransactionContext>(_vocbase);
|
||||
auto transactionContext = std::make_shared<StandaloneTransactionContext>(_vocbaseGuard.vocbase());
|
||||
VPackOptions* options = transactionContext->getVPackOptions();
|
||||
|
||||
TRI_ASSERT(_ex != nullptr);
|
||||
|
|
|
@ -28,11 +28,10 @@
|
|||
#include "Basics/StringBuffer.h"
|
||||
#include "Aql/QueryResult.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
#include <velocypack/Iterator.h>
|
||||
|
||||
struct TRI_vocbase_t;
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
class Builder;
|
||||
|
@ -116,7 +115,7 @@ class VelocyPackCursor : public Cursor {
|
|||
std::shared_ptr<arangodb::velocypack::Builder>, double,
|
||||
bool);
|
||||
|
||||
~VelocyPackCursor();
|
||||
~VelocyPackCursor() = default;
|
||||
|
||||
public:
|
||||
bool hasNext() override final;
|
||||
|
@ -128,7 +127,7 @@ class VelocyPackCursor : public Cursor {
|
|||
void dump(arangodb::basics::StringBuffer&) override final;
|
||||
|
||||
private:
|
||||
TRI_vocbase_t* _vocbase;
|
||||
VocbaseGuard _vocbaseGuard;
|
||||
aql::QueryResult _result;
|
||||
arangodb::velocypack::ArrayIterator _iterator;
|
||||
bool _cached;
|
||||
|
@ -151,7 +150,7 @@ class ExportCursor : public Cursor {
|
|||
void dump(arangodb::basics::StringBuffer&) override final;
|
||||
|
||||
private:
|
||||
TRI_vocbase_t* _vocbase;
|
||||
VocbaseGuard _vocbaseGuard;
|
||||
arangodb::CollectionExport* _ex;
|
||||
size_t const _size;
|
||||
};
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_UTILS_DATABASE_GUARD_H
|
||||
#define ARANGOD_UTILS_DATABASE_GUARD_H 1
|
||||
#ifndef ARANGOD_UTILS_vocbase_GUARD_H
|
||||
#define ARANGOD_UTILS_vocbase_GUARD_H 1
|
||||
|
||||
#include "ApplicationFeatures/ApplicationServer.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
|
@ -42,12 +42,12 @@ class DatabaseGuard {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
explicit DatabaseGuard(TRI_voc_tick_t id)
|
||||
: _database(nullptr) {
|
||||
: _vocbase(nullptr) {
|
||||
|
||||
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
_database = databaseFeature->useDatabase(id);
|
||||
_vocbase = databaseFeature->useDatabase(id);
|
||||
|
||||
if (_database == nullptr) {
|
||||
if (_vocbase == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
@ -56,13 +56,13 @@ class DatabaseGuard {
|
|||
/// @brief create the guard, using a database name
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
explicit DatabaseGuard(char const* name)
|
||||
: _database(nullptr) {
|
||||
explicit DatabaseGuard(std::string const& name)
|
||||
: _vocbase(nullptr) {
|
||||
|
||||
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
_database = databaseFeature->useDatabase(name);
|
||||
_vocbase = databaseFeature->useDatabase(name);
|
||||
|
||||
if (_database == nullptr) {
|
||||
if (_vocbase == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
@ -72,10 +72,8 @@ class DatabaseGuard {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~DatabaseGuard() {
|
||||
if (_database != nullptr) {
|
||||
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
databaseFeature->releaseDatabase(_database);
|
||||
}
|
||||
TRI_ASSERT(_vocbase != nullptr);
|
||||
_vocbase->release();
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -83,7 +81,7 @@ class DatabaseGuard {
|
|||
/// @brief return the database pointer
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline TRI_vocbase_t* database() const { return _database; }
|
||||
inline TRI_vocbase_t* database() const { return _vocbase; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -91,7 +89,7 @@ class DatabaseGuard {
|
|||
/// @brief pointer to database
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_t* _database;
|
||||
TRI_vocbase_t* _vocbase;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#ifndef ARANGOD_UTILS_REPLICATION_TRANSACTION_H
|
||||
#define ARANGOD_UTILS_REPLICATION_TRANSACTION_H 1
|
||||
|
||||
#include "ApplicationFeatures/ApplicationServer.h"
|
||||
#include "RestServer/DatabaseFeature.h"
|
||||
#include "Utils/StandaloneTransactionContext.h"
|
||||
#include "Utils/Transaction.h"
|
||||
#include "VocBase/ticks.h"
|
||||
|
@ -37,25 +35,15 @@ namespace arangodb {
|
|||
|
||||
class ReplicationTransaction : public Transaction {
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the transaction
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ReplicationTransaction(TRI_vocbase_t* vocbase)
|
||||
: Transaction(StandaloneTransactionContext::Create(vocbase)) {
|
||||
|
||||
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
databaseFeature->useDatabase(vocbase->name());
|
||||
_vocbase->use();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief end the transaction
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~ReplicationTransaction() {
|
||||
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
databaseFeature->releaseDatabase(vocbase());
|
||||
}
|
||||
~ReplicationTransaction() { _vocbase->release(); }
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ bool WorkMonitor::cancelAql(WorkDescription* desc) {
|
|||
|
||||
LOG(WARN) << "cancel query " << id << " in " << vocbase;
|
||||
|
||||
auto queryList = static_cast<arangodb::aql::QueryList*>(vocbase->_queries);
|
||||
auto queryList = vocbase->queryList();
|
||||
auto res = queryList->kill(id);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
|
|
@ -87,7 +87,7 @@ void V8Context::handleGlobalContextMethods() {
|
|||
}
|
||||
|
||||
for (auto& type : copy) {
|
||||
std::string func = GlobalContextMethods::code(type);
|
||||
std::string const& func = GlobalContextMethods::code(type);
|
||||
|
||||
LOG(DEBUG) << "executing global context method '" << func
|
||||
<< "' for context " << _id;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <v8.h>
|
||||
|
||||
#include "Basics/Mutex.h"
|
||||
#include "Basics/StaticStrings.h"
|
||||
|
||||
namespace arangodb {
|
||||
class GlobalContextMethods {
|
||||
|
@ -81,7 +82,7 @@ class GlobalContextMethods {
|
|||
}
|
||||
}
|
||||
|
||||
static std::string const code(MethodType type) {
|
||||
static std::string const& code(MethodType type) {
|
||||
switch (type) {
|
||||
case MethodType::RELOAD_ROUTING:
|
||||
return CodeReloadRouting;
|
||||
|
@ -95,7 +96,7 @@ class GlobalContextMethods {
|
|||
return CodeWarmupExports;
|
||||
case MethodType::UNKNOWN:
|
||||
default:
|
||||
return "";
|
||||
return StaticStrings::Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -545,10 +545,14 @@ V8Context* V8DealerFeature::enterContext(TRI_vocbase_t* vocbase,
|
|||
v8g->_vocbase = vocbase;
|
||||
v8g->_allowUseDatabase = allowUseDatabase;
|
||||
|
||||
TRI_UseVocBase(vocbase);
|
||||
vocbase->use();
|
||||
|
||||
LOG(TRACE) << "entering V8 context " << context->_id;
|
||||
context->handleGlobalContextMethods();
|
||||
try {
|
||||
LOG(TRACE) << "entering V8 context " << context->_id;
|
||||
context->handleGlobalContextMethods();
|
||||
} catch (...) {
|
||||
// ignore errors here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -578,7 +582,7 @@ void V8DealerFeature::exitContext(V8Context* context) {
|
|||
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
// release last recently used vocbase
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
vocbase->release();
|
||||
|
||||
// check for cancelation requests
|
||||
canceled = v8g->_canceled;
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "V8Server/V8Context.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "V8Server/V8PeriodicTask.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
|
@ -48,13 +47,12 @@ V8Job::V8Job(TRI_vocbase_t* vocbase, std::string const& command,
|
|||
std::shared_ptr<VPackBuilder> parameters, bool allowUseDatabase,
|
||||
Task* task)
|
||||
: Job("V8 Job"),
|
||||
_vocbase(vocbase),
|
||||
_vocbaseGuard(vocbase),
|
||||
_command(command),
|
||||
_parameters(parameters),
|
||||
_canceled(false),
|
||||
_allowUseDatabase(allowUseDatabase),
|
||||
_task(task) {
|
||||
TRI_UseVocBase(vocbase);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -62,8 +60,6 @@ V8Job::V8Job(TRI_vocbase_t* vocbase, std::string const& command,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
V8Job::~V8Job() {
|
||||
TRI_ReleaseVocBase(_vocbase);
|
||||
|
||||
if (_task != nullptr) {
|
||||
V8PeriodicTask::jobDone(_task);
|
||||
}
|
||||
|
@ -75,7 +71,7 @@ void V8Job::work() {
|
|||
}
|
||||
|
||||
auto context =
|
||||
V8DealerFeature::DEALER->enterContext(_vocbase, _allowUseDatabase);
|
||||
V8DealerFeature::DEALER->enterContext(_vocbaseGuard.vocbase(), _allowUseDatabase);
|
||||
|
||||
// note: the context might be 0 in case of shut-down
|
||||
if (context == nullptr) {
|
||||
|
|
|
@ -26,8 +26,7 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
#include "Dispatcher/Job.h"
|
||||
|
||||
struct TRI_vocbase_t;
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace rest {
|
||||
|
@ -53,7 +52,8 @@ class V8Job : public rest::Job {
|
|||
virtual std::string const& getName() const override { return _command; }
|
||||
|
||||
private:
|
||||
TRI_vocbase_t* _vocbase;
|
||||
/// @brief guard to make sure the database is not dropped while used by us
|
||||
VocbaseGuard _vocbaseGuard;
|
||||
std::string const _command;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> _parameters;
|
||||
std::atomic<bool> _canceled;
|
||||
|
|
|
@ -54,20 +54,11 @@ V8PeriodicTask::V8PeriodicTask(std::string const& id, std::string const& name,
|
|||
bool allowUseDatabase)
|
||||
: Task(id, name),
|
||||
PeriodicTask(id, offset, period),
|
||||
_vocbase(vocbase),
|
||||
_vocbaseGuard(vocbase),
|
||||
_command(command),
|
||||
_parameters(parameters),
|
||||
_created(TRI_microtime()),
|
||||
_allowUseDatabase(allowUseDatabase) {
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
|
||||
// increase reference counter for the database used
|
||||
TRI_UseVocBase(_vocbase);
|
||||
}
|
||||
|
||||
V8PeriodicTask::~V8PeriodicTask() {
|
||||
// decrease reference counter for the database used
|
||||
TRI_ReleaseVocBase(_vocbase);
|
||||
}
|
||||
|
||||
// get a task specific description in JSON format
|
||||
|
@ -77,7 +68,7 @@ void V8PeriodicTask::getDescription(VPackBuilder& builder) const {
|
|||
|
||||
builder.add("created", VPackValue(_created));
|
||||
builder.add("command", VPackValue(_command));
|
||||
builder.add("database", VPackValue(_vocbase->name()));
|
||||
builder.add("database", VPackValue(_vocbaseGuard.vocbase()->name()));
|
||||
}
|
||||
|
||||
// handles the next tick
|
||||
|
@ -99,7 +90,7 @@ bool V8PeriodicTask::handlePeriod() {
|
|||
}
|
||||
|
||||
std::unique_ptr<Job> job(new V8Job(
|
||||
_vocbase, "(function (params) { " + _command + " } )(params);",
|
||||
_vocbaseGuard.vocbase(), "(function (params) { " + _command + " } )(params);",
|
||||
_parameters, _allowUseDatabase, this));
|
||||
|
||||
DispatcherFeature::DISPATCHER->addJob(job, false);
|
||||
|
|
|
@ -39,7 +39,7 @@ class V8PeriodicTask : public rest::PeriodicTask {
|
|||
double, std::string const&,
|
||||
std::shared_ptr<arangodb::velocypack::Builder>, bool);
|
||||
|
||||
~V8PeriodicTask();
|
||||
~V8PeriodicTask() = default;
|
||||
|
||||
public:
|
||||
static void jobDone(Task*);
|
||||
|
@ -56,7 +56,8 @@ class V8PeriodicTask : public rest::PeriodicTask {
|
|||
static std::unordered_set<Task*> RUNNING;
|
||||
|
||||
private:
|
||||
TRI_vocbase_t* _vocbase;
|
||||
/// @brief guard to make sure the database is not dropped while used by us
|
||||
VocbaseGuard _vocbaseGuard;
|
||||
std::string const _command;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> _parameters;
|
||||
double _created;
|
||||
|
|
|
@ -46,20 +46,11 @@ V8TimerTask::V8TimerTask(std::string const& id, std::string const& name,
|
|||
// greater than zero,
|
||||
// otherwise
|
||||
// the timertask will not execute the task at all
|
||||
_vocbase(vocbase),
|
||||
_vocbaseGuard(vocbase),
|
||||
_command(command),
|
||||
_parameters(parameters),
|
||||
_created(TRI_microtime()),
|
||||
_allowUseDatabase(allowUseDatabase) {
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
|
||||
// increase reference counter for the database used
|
||||
TRI_UseVocBase(_vocbase);
|
||||
}
|
||||
|
||||
V8TimerTask::~V8TimerTask() {
|
||||
// decrease reference counter for the database used
|
||||
TRI_ReleaseVocBase(_vocbase);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -70,7 +61,7 @@ void V8TimerTask::getDescription(VPackBuilder& builder) const {
|
|||
TimerTask::getDescription(builder);
|
||||
builder.add("created", VPackValue(_created));
|
||||
builder.add("command", VPackValue(_command));
|
||||
builder.add("database", VPackValue(_vocbase->name()));
|
||||
builder.add("database", VPackValue(_vocbaseGuard.vocbase()->name()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -81,7 +72,7 @@ bool V8TimerTask::handleTimeout() {
|
|||
TRI_ASSERT(DispatcherFeature::DISPATCHER != nullptr);
|
||||
|
||||
std::unique_ptr<Job> job(
|
||||
new V8Job(_vocbase, "(function (params) { " + _command + " } )(params);",
|
||||
new V8Job(_vocbaseGuard.vocbase(), "(function (params) { " + _command + " } )(params);",
|
||||
_parameters, _allowUseDatabase, nullptr));
|
||||
|
||||
if (DispatcherFeature::DISPATCHER == nullptr) {
|
||||
|
|
|
@ -44,7 +44,7 @@ class V8TimerTask : public rest::TimerTask {
|
|||
std::string const&,
|
||||
std::shared_ptr<arangodb::velocypack::Builder>, bool);
|
||||
|
||||
~V8TimerTask();
|
||||
~V8TimerTask() = default;
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,11 +67,8 @@ class V8TimerTask : public rest::TimerTask {
|
|||
bool handleTimeout() override;
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief system vocbase
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_vocbase_t* _vocbase;
|
||||
/// @brief guard to make sure the database is not dropped while used by us
|
||||
VocbaseGuard _vocbaseGuard;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief command to execute
|
||||
|
|
|
@ -115,7 +115,7 @@ static void WeakCollectionCallback(const v8::WeakCallbackData<
|
|||
v8g->decreaseActiveExternals();
|
||||
|
||||
// decrease the reference-counter for the database
|
||||
TRI_ReleaseVocBase(collection->_vocbase);
|
||||
collection->_vocbase->release();
|
||||
|
||||
// find the persistent handle
|
||||
#if ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
|
@ -157,15 +157,20 @@ v8::Handle<v8::Object> WrapCollection(v8::Isolate* isolate,
|
|||
|
||||
if (it == v8g->JSCollections.end()) {
|
||||
// increase the reference-counter for the database
|
||||
TRI_UseVocBase(collection->_vocbase);
|
||||
auto externalCollection = v8::External::New(isolate, nonconstCollection);
|
||||
collection->_vocbase->use();
|
||||
try {
|
||||
auto externalCollection = v8::External::New(isolate, nonconstCollection);
|
||||
|
||||
result->SetInternalField(SLOT_COLLECTION, externalCollection);
|
||||
result->SetInternalField(SLOT_COLLECTION, externalCollection);
|
||||
|
||||
v8g->JSCollections[nonconstCollection].Reset(isolate, externalCollection);
|
||||
v8g->JSCollections[nonconstCollection].SetWeak(
|
||||
&v8g->JSCollections[nonconstCollection], WeakCollectionCallback);
|
||||
v8g->increaseActiveExternals();
|
||||
v8g->JSCollections[nonconstCollection].Reset(isolate, externalCollection);
|
||||
v8g->JSCollections[nonconstCollection].SetWeak(
|
||||
&v8g->JSCollections[nonconstCollection], WeakCollectionCallback);
|
||||
v8g->increaseActiveExternals();
|
||||
} catch (...) {
|
||||
collection->_vocbase->release();
|
||||
throw;
|
||||
}
|
||||
} else {
|
||||
auto myCollection = v8::Local<v8::External>::New(isolate, it->second);
|
||||
|
||||
|
|
|
@ -2097,7 +2097,7 @@ static void JS_SaveVocbase(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (TRI_IsDeletedVocBase(vocbase)) {
|
||||
if (vocbase->isDropped()) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
@ -2688,7 +2688,7 @@ static void JS_CollectionVocbase(
|
|||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (TRI_IsDeletedVocBase(vocbase)) {
|
||||
if (vocbase->isDropped()) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
|
@ -1366,7 +1366,7 @@ static void JS_QueriesPropertiesAql(
|
|||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
auto queryList = static_cast<arangodb::aql::QueryList*>(vocbase->_queries);
|
||||
auto queryList = vocbase->queryList();
|
||||
TRI_ASSERT(queryList != nullptr);
|
||||
|
||||
if (args.Length() > 1) {
|
||||
|
@ -1442,7 +1442,7 @@ static void JS_QueriesCurrentAql(
|
|||
TRI_V8_THROW_EXCEPTION_USAGE("AQL_QUERIES_CURRENT()");
|
||||
}
|
||||
|
||||
auto queryList = static_cast<arangodb::aql::QueryList*>(vocbase->_queries);
|
||||
auto queryList = vocbase->queryList();
|
||||
TRI_ASSERT(queryList != nullptr);
|
||||
|
||||
try {
|
||||
|
@ -1486,7 +1486,7 @@ static void JS_QueriesSlowAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
auto queryList = static_cast<arangodb::aql::QueryList*>(vocbase->_queries);
|
||||
auto queryList = vocbase->queryList();
|
||||
TRI_ASSERT(queryList != nullptr);
|
||||
|
||||
if (args.Length() == 1) {
|
||||
|
@ -1545,7 +1545,7 @@ static void JS_QueriesKillAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
|
||||
auto id = TRI_ObjectToUInt64(args[0], true);
|
||||
|
||||
auto queryList = static_cast<arangodb::aql::QueryList*>(vocbase->_queries);
|
||||
auto queryList = vocbase->queryList();
|
||||
TRI_ASSERT(queryList != nullptr);
|
||||
|
||||
auto res = queryList->kill(id);
|
||||
|
@ -2042,7 +2042,7 @@ static void JS_UseDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
if (TRI_IsDeletedVocBase(vocbase)) {
|
||||
if (vocbase->isDropped()) {
|
||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
@ -2068,7 +2068,7 @@ static void JS_UseDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
|
||||
v8g->_vocbase = vocbase;
|
||||
TRI_ASSERT(orig != vocbase);
|
||||
databaseFeature->releaseDatabase(static_cast<TRI_vocbase_t*>(orig));
|
||||
static_cast<TRI_vocbase_t*>(orig)->release();
|
||||
|
||||
TRI_V8_RETURN(WrapVocBase(isolate, vocbase));
|
||||
}
|
||||
|
@ -2305,7 +2305,7 @@ static void CreateDatabaseCoordinator(
|
|||
// and switch back
|
||||
v8g->_vocbase = orig;
|
||||
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
vocbase->release();
|
||||
|
||||
TRI_V8_RETURN_TRUE();
|
||||
}
|
||||
|
@ -2394,7 +2394,7 @@ static void JS_CreateDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
v8g->_vocbase = orig;
|
||||
|
||||
// finally decrease the reference-counter
|
||||
TRI_ReleaseVocBase(database);
|
||||
database->release();
|
||||
|
||||
TRI_V8_RETURN_TRUE();
|
||||
}
|
||||
|
@ -2419,7 +2419,7 @@ static void DropDatabaseCoordinator(
|
|||
}
|
||||
|
||||
TRI_voc_tick_t const id = vocbase->_id;
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
vocbase->release();
|
||||
|
||||
ClusterInfo* ci = ClusterInfo::instance();
|
||||
std::string errorMsg;
|
||||
|
@ -2441,7 +2441,7 @@ static void DropDatabaseCoordinator(
|
|||
break;
|
||||
}
|
||||
|
||||
TRI_ReleaseVocBase(vocbase);
|
||||
vocbase->release();
|
||||
// sleep
|
||||
usleep(10000);
|
||||
}
|
||||
|
|
|
@ -86,8 +86,7 @@ static void JS_CreateCursor(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
}
|
||||
|
||||
// create a cursor
|
||||
auto cursors =
|
||||
static_cast<arangodb::CursorRepository*>(vocbase->_cursorRepository);
|
||||
auto cursors = vocbase->cursorRepository();
|
||||
|
||||
arangodb::aql::QueryResult result(TRI_ERROR_NO_ERROR);
|
||||
result.result = builder;
|
||||
|
@ -134,8 +133,7 @@ static void JS_JsonCursor(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
|||
arangodb::basics::StringUtils::uint64(id));
|
||||
|
||||
// find the cursor
|
||||
auto cursors =
|
||||
static_cast<arangodb::CursorRepository*>(vocbase->_cursorRepository);
|
||||
auto cursors = vocbase->cursorRepository();
|
||||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
bool busy;
|
||||
|
|
|
@ -140,8 +140,7 @@ void CleanupThread::run() {
|
|||
/// @brief clean up cursors
|
||||
void CleanupThread::cleanupCursors(bool force) {
|
||||
// clean unused cursors
|
||||
auto cursors =
|
||||
static_cast<arangodb::CursorRepository*>(_vocbase->_cursorRepository);
|
||||
auto cursors = _vocbase->cursorRepository();
|
||||
TRI_ASSERT(cursors != nullptr);
|
||||
|
||||
try {
|
||||
|
@ -242,7 +241,7 @@ void CleanupThread::cleanupCollection(TRI_vocbase_col_t* collection,
|
|||
}
|
||||
}
|
||||
|
||||
if (!isDeleted && TRI_IsDeletedVocBase(document->_vocbase)) {
|
||||
if (!isDeleted && document->_vocbase->isDropped()) {
|
||||
// the collection was not marked as deleted, but the database was
|
||||
isDeleted = true;
|
||||
}
|
||||
|
|
|
@ -1087,15 +1087,11 @@ void TRI_vocbase_t::shutdown() {
|
|||
}
|
||||
|
||||
// mark all cursors as deleted so underlying collections can be freed soon
|
||||
if (_cursorRepository != nullptr) {
|
||||
_cursorRepository->garbageCollect(true);
|
||||
}
|
||||
_cursorRepository->garbageCollect(true);
|
||||
|
||||
// mark all collection keys as deleted so underlying collections can be freed
|
||||
// soon
|
||||
if (_collectionKeys != nullptr) {
|
||||
_collectionKeys->garbageCollect(true);
|
||||
}
|
||||
_collectionKeys->garbageCollect(true);
|
||||
|
||||
std::vector<TRI_vocbase_col_t*> collections;
|
||||
|
||||
|
@ -1678,68 +1674,6 @@ void TRI_ReleaseCollectionVocBase(TRI_vocbase_t* vocbase,
|
|||
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the vocbase has been marked as deleted
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_IsDeletedVocBase(TRI_vocbase_t* vocbase) {
|
||||
auto refCount = vocbase->_refCount.load();
|
||||
// if the stored value is odd, it means the database has been marked as
|
||||
// deleted
|
||||
return (refCount % 2 == 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief increase the reference counter for a database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_UseVocBase(TRI_vocbase_t* vocbase) {
|
||||
// increase the reference counter by 2.
|
||||
// this is because we use odd values to indicate that the database has been
|
||||
// marked as deleted
|
||||
auto oldValue = vocbase->_refCount.fetch_add(2, std::memory_order_release);
|
||||
// check if the deleted bit is set
|
||||
return (oldValue % 2 != 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief decrease the reference counter for a database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_ReleaseVocBase(TRI_vocbase_t* vocbase) {
|
||||
// decrease the reference counter by 2.
|
||||
// this is because we use odd values to indicate that the database has been
|
||||
// marked as deleted
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto oldValue = vocbase->_refCount.fetch_sub(2, std::memory_order_release);
|
||||
TRI_ASSERT(oldValue >= 2);
|
||||
#else
|
||||
vocbase->_refCount.fetch_sub(2, std::memory_order_release);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief marks a database as deleted
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_DropVocBase(TRI_vocbase_t* vocbase) {
|
||||
auto oldValue = vocbase->_refCount.fetch_or(1, std::memory_order_release);
|
||||
// if the previously stored value is odd, it means the database has already
|
||||
// been marked as deleted
|
||||
return (oldValue % 2 == 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns whether the database can be removed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_CanRemoveVocBase(TRI_vocbase_t* vocbase) {
|
||||
auto refCount = vocbase->_refCount.load();
|
||||
// we are intentionally comparing with exactly 1 here, because a 1 means
|
||||
// that noone else references the database but it has been marked as deleted
|
||||
return (refCount == 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief gets the "throw collection not loaded error"
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1768,14 +1702,11 @@ TRI_vocbase_t::TRI_vocbase_t(TRI_vocbase_type_e type, TRI_voc_tick_t id,
|
|||
_refCount(0),
|
||||
_deadlockDetector(false),
|
||||
_userStructures(nullptr),
|
||||
_queries(nullptr),
|
||||
_cursorRepository(nullptr),
|
||||
_collectionKeys(nullptr),
|
||||
_hasCompactor(false),
|
||||
_isOwnAppsDirectory(true) {
|
||||
_queries = new arangodb::aql::QueryList(this);
|
||||
_cursorRepository = new arangodb::CursorRepository(this);
|
||||
_collectionKeys = new arangodb::CollectionKeysRepository();
|
||||
_queries.reset(new arangodb::aql::QueryList(this));
|
||||
_cursorRepository.reset(new arangodb::CursorRepository(this));
|
||||
_collectionKeys.reset(new arangodb::CollectionKeysRepository());
|
||||
|
||||
// init collections
|
||||
_collections.reserve(32);
|
||||
|
@ -1801,13 +1732,9 @@ TRI_vocbase_t::~TRI_vocbase_t() {
|
|||
_cleanupThread.reset();
|
||||
|
||||
TRI_DestroyCondition(&_compactorCondition);
|
||||
|
||||
delete _cursorRepository;
|
||||
delete _collectionKeys;
|
||||
delete _queries;
|
||||
}
|
||||
|
||||
std::string const TRI_vocbase_t::path() {
|
||||
std::string TRI_vocbase_t::path() const {
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
return engine->databasePath(this);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Basics/Common.h"
|
||||
#include "Basics/ConditionVariable.h"
|
||||
#include "Basics/DeadlockDetector.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Basics/ReadWriteLock.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Basics/threads.h"
|
||||
|
@ -267,10 +268,11 @@ struct TRI_vocbase_t {
|
|||
|
||||
// structures for user-defined volatile data
|
||||
void* _userStructures;
|
||||
arangodb::aql::QueryList* _queries;
|
||||
arangodb::CursorRepository* _cursorRepository;
|
||||
arangodb::CollectionKeysRepository* _collectionKeys;
|
||||
|
||||
private:
|
||||
std::unique_ptr<arangodb::aql::QueryList> _queries;
|
||||
std::unique_ptr<arangodb::CursorRepository> _cursorRepository;
|
||||
std::unique_ptr<arangodb::CollectionKeysRepository> _collectionKeys;
|
||||
public:
|
||||
bool _hasCompactor;
|
||||
bool _isOwnAppsDirectory;
|
||||
|
||||
|
@ -303,14 +305,68 @@ struct TRI_vocbase_t {
|
|||
/// @brief checks if a database name is allowed
|
||||
/// returns true if the name is allowed and false otherwise
|
||||
static bool IsAllowedName(bool allowSystem, std::string const& name);
|
||||
std::string const name() { return _name; }
|
||||
std::string const path();
|
||||
std::string const& name() const { return _name; }
|
||||
std::string path() const;
|
||||
void updateReplicationClient(TRI_server_id_t, TRI_voc_tick_t);
|
||||
std::vector<std::tuple<TRI_server_id_t, double, TRI_voc_tick_t>>
|
||||
getReplicationClients();
|
||||
|
||||
arangodb::aql::QueryList* queryList() const { return _queries.get(); }
|
||||
arangodb::CursorRepository* cursorRepository() const { return _cursorRepository.get(); }
|
||||
arangodb::CollectionKeysRepository* collectionKeys() const { return _collectionKeys.get(); }
|
||||
|
||||
/// @brief whether or not the vocbase has been marked as deleted
|
||||
inline bool isDropped() const {
|
||||
auto refCount = _refCount.load();
|
||||
// if the stored value is odd, it means the database has been marked as
|
||||
// deleted
|
||||
return (refCount % 2 == 1);
|
||||
}
|
||||
|
||||
/// @brief increase the reference counter for a database
|
||||
bool use() {
|
||||
// increase the reference counter by 2.
|
||||
// this is because we use odd values to indicate that the database has been
|
||||
// marked as deleted
|
||||
auto oldValue = _refCount.fetch_add(2, std::memory_order_release);
|
||||
// check if the deleted bit is set
|
||||
return (oldValue % 2 != 1);
|
||||
}
|
||||
|
||||
/// @brief decrease the reference counter for a database
|
||||
void release() {
|
||||
// decrease the reference counter by 2.
|
||||
// this is because we use odd values to indicate that the database has been
|
||||
// marked as deleted
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto oldValue = _refCount.fetch_sub(2, std::memory_order_release);
|
||||
TRI_ASSERT(oldValue >= 2);
|
||||
#else
|
||||
_refCount.fetch_sub(2, std::memory_order_release);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @brief returns whether the database can be dropped
|
||||
bool canBeDropped() const {
|
||||
if (isSystem()) {
|
||||
return false;
|
||||
}
|
||||
auto refCount = _refCount.load();
|
||||
// we are intentionally comparing with exactly 1 here, because a 1 means
|
||||
// that noone else references the database but it has been marked as deleted
|
||||
return (refCount == 1);
|
||||
}
|
||||
|
||||
/// @brief marks a database as deleted
|
||||
bool markAsDropped() {
|
||||
auto oldValue = _refCount.fetch_or(1, std::memory_order_release);
|
||||
// if the previously stored value is odd, it means the database has already
|
||||
// been marked as deleted
|
||||
return (oldValue % 2 == 0);
|
||||
}
|
||||
|
||||
/// @brief returns whether the database is the system database
|
||||
bool isSystem() { return name() == TRI_VOC_SYSTEM_DATABASE; }
|
||||
bool isSystem() const { return name() == TRI_VOC_SYSTEM_DATABASE; }
|
||||
|
||||
/// @brief closes a database and all collections
|
||||
void shutdown();
|
||||
|
@ -343,6 +399,27 @@ struct TRI_vocbase_t {
|
|||
bool doOverride, bool writeMarker);
|
||||
};
|
||||
|
||||
// scope guard for a database
|
||||
// ensures that a database
|
||||
class VocbaseGuard {
|
||||
public:
|
||||
VocbaseGuard() = delete;
|
||||
VocbaseGuard(VocbaseGuard const&) = delete;
|
||||
VocbaseGuard& operator=(VocbaseGuard const&) = delete;
|
||||
|
||||
explicit VocbaseGuard(TRI_vocbase_t* vocbase) : _vocbase(vocbase) {
|
||||
if (!_vocbase->use()) {
|
||||
// database already dropped
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
~VocbaseGuard() { _vocbase->release(); }
|
||||
TRI_vocbase_t* vocbase() const { return _vocbase; }
|
||||
|
||||
private:
|
||||
TRI_vocbase_t* _vocbase;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief status of a collection
|
||||
///
|
||||
|
@ -518,36 +595,6 @@ TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase(TRI_vocbase_t*, char const*,
|
|||
|
||||
void TRI_ReleaseCollectionVocBase(TRI_vocbase_t*, TRI_vocbase_col_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the vocbase has been marked as deleted
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_IsDeletedVocBase(TRI_vocbase_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief increase the reference counter for a database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_UseVocBase(TRI_vocbase_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief decrease the reference counter for a database
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_ReleaseVocBase(TRI_vocbase_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief marks a database as deleted
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_DropVocBase(TRI_vocbase_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns whether the database can be removed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_CanRemoveVocBase(TRI_vocbase_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief gets the "throw collection not loaded error"
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -102,7 +102,7 @@ void RecoverState::releaseResources() {
|
|||
|
||||
// release all databases
|
||||
for (auto it = openedDatabases.begin(); it != openedDatabases.end(); ++it) {
|
||||
databaseFeature->releaseDatabase((*it).second);
|
||||
(*it).second->release();
|
||||
}
|
||||
|
||||
openedDatabases.clear();
|
||||
|
@ -159,7 +159,7 @@ TRI_vocbase_t* RecoverState::releaseDatabase(TRI_voc_tick_t databaseId) {
|
|||
}
|
||||
}
|
||||
|
||||
databaseFeature->releaseDatabase(vocbase);
|
||||
vocbase->release();
|
||||
openedDatabases.erase(databaseId);
|
||||
|
||||
return vocbase;
|
||||
|
|
Loading…
Reference in New Issue