mirror of https://gitee.com/bigwinds/arangodb
Use shared_ptr for LogicalCollection (#7220)
This commit is contained in:
parent
311fb717f2
commit
0eb5142df8
|
@ -168,9 +168,8 @@ int ClusterTransactionCollection::use(int nestingLevel) {
|
|||
}
|
||||
|
||||
try {
|
||||
_sharedCollection = ci->getCollection(_transaction->vocbase().name(), std::to_string(_cid));
|
||||
if (_sharedCollection) {
|
||||
_collection = _sharedCollection.get();
|
||||
_collection = ci->getCollection(_transaction->vocbase().name(), std::to_string(_cid));
|
||||
if (_collection) {
|
||||
if (!_transaction->hasHint(transaction::Hints::Hint::LOCK_NEVER) &&
|
||||
!_transaction->hasHint(transaction::Hints::Hint::NO_USAGE_LOCK)) {
|
||||
// use and usage-lock
|
||||
|
@ -224,7 +223,7 @@ void ClusterTransactionCollection::release() {
|
|||
LOG_TRX(_transaction, 0) << "unusing collection " << _cid;
|
||||
|
||||
if (_usageLocked) {
|
||||
_transaction->vocbase().releaseCollection(_collection);
|
||||
_transaction->vocbase().releaseCollection(_collection.get());
|
||||
_usageLocked = false;
|
||||
}
|
||||
_collection = nullptr;
|
||||
|
@ -257,9 +256,7 @@ int ClusterTransactionCollection::doLock(AccessMode::Type type,
|
|||
|
||||
TRI_ASSERT(!isLocked());
|
||||
|
||||
LogicalCollection* collection = _collection;
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
|
||||
TRI_ASSERT(_collection);
|
||||
LOG_TRX(_transaction, nestingLevel) << "write-locking collection " << _cid;
|
||||
|
||||
_lockType = type;
|
||||
|
@ -310,8 +307,7 @@ int ClusterTransactionCollection::doUnlock(AccessMode::Type type,
|
|||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
LogicalCollection* collection = _collection;
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
TRI_ASSERT(_collection);
|
||||
|
||||
_lockType = AccessMode::Type::NONE;
|
||||
|
||||
|
|
|
@ -89,8 +89,6 @@ class ClusterTransactionCollection final : public TransactionCollection {
|
|||
AccessMode::Type _lockType; // collection lock type, used for exclusive locks
|
||||
int _nestingLevel; // the transaction level that added this collection
|
||||
bool _usageLocked; // is this already locked
|
||||
/// @brief shared ptr to the collection so we can safely use _collection
|
||||
std::shared_ptr<LogicalCollection> _sharedCollection;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ int MMFilesTransactionCollection::use(int nestingLevel) {
|
|||
}
|
||||
} else {
|
||||
// use without usage-lock (lock already set externally)
|
||||
_collection = _transaction->vocbase().lookupCollection(_cid).get();
|
||||
_collection = _transaction->vocbase().lookupCollection(_cid);
|
||||
|
||||
if (_collection == nullptr) {
|
||||
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
|
||||
|
@ -300,7 +300,7 @@ void MMFilesTransactionCollection::release() {
|
|||
// unuse collection, remove usage-lock
|
||||
LOG_TRX(_transaction, 0) << "unusing collection " << _cid;
|
||||
|
||||
_transaction->vocbase().releaseCollection(_collection);
|
||||
_transaction->vocbase().releaseCollection(_collection.get());
|
||||
_collection = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -323,11 +323,9 @@ int MMFilesTransactionCollection::doLock(AccessMode::Type type, int nestingLevel
|
|||
}
|
||||
|
||||
TRI_ASSERT(!isLocked());
|
||||
|
||||
LogicalCollection* collection = _collection;
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
|
||||
auto physical = static_cast<MMFilesCollection*>(collection->getPhysical());
|
||||
TRI_ASSERT(_collection);
|
||||
|
||||
auto physical = static_cast<MMFilesCollection*>(_collection->getPhysical());
|
||||
TRI_ASSERT(physical != nullptr);
|
||||
|
||||
double timeout = _transaction->timeout();
|
||||
|
@ -400,10 +398,8 @@ int MMFilesTransactionCollection::doUnlock(AccessMode::Type type, int nestingLev
|
|||
bool const useDeadlockDetector = (!_transaction->hasHint(transaction::Hints::Hint::SINGLE_OPERATION) &&
|
||||
!_transaction->hasHint(transaction::Hints::Hint::NO_DLD));
|
||||
|
||||
LogicalCollection* collection = _collection;
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
|
||||
auto physical = static_cast<MMFilesCollection*>(collection->getPhysical());
|
||||
TRI_ASSERT(_collection);
|
||||
auto physical = static_cast<MMFilesCollection*>(_collection->getPhysical());
|
||||
TRI_ASSERT(physical != nullptr);
|
||||
|
||||
if (!AccessMode::isWriteOrExclusive(_lockType)) {
|
||||
|
|
|
@ -109,8 +109,8 @@ void MMFilesWalRecoverState::releaseResources() {
|
|||
// release all collections
|
||||
for (auto it = openedCollections.begin(); it != openedCollections.end();
|
||||
++it) {
|
||||
arangodb::LogicalCollection* collection = it->second;
|
||||
collection->vocbase().releaseCollection(collection);
|
||||
std::shared_ptr<arangodb::LogicalCollection>& collection = it->second;
|
||||
collection->vocbase().releaseCollection(collection.get());
|
||||
}
|
||||
|
||||
openedCollections.clear();
|
||||
|
@ -158,14 +158,14 @@ TRI_vocbase_t* MMFilesWalRecoverState::releaseDatabase(
|
|||
auto it2 = openedCollections.begin();
|
||||
|
||||
while (it2 != openedCollections.end()) {
|
||||
arangodb::LogicalCollection* collection = it2->second;
|
||||
std::shared_ptr<arangodb::LogicalCollection>& collection = it2->second;
|
||||
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
|
||||
if (collection->vocbase().id() == databaseId) {
|
||||
// correct database, now release the collection
|
||||
TRI_ASSERT(vocbase == &(collection->vocbase()));
|
||||
vocbase->releaseCollection(collection);
|
||||
vocbase->releaseCollection(collection.get());
|
||||
// get new iterator position
|
||||
it2 = openedCollections.erase(it2);
|
||||
} else {
|
||||
|
@ -181,7 +181,7 @@ TRI_vocbase_t* MMFilesWalRecoverState::releaseDatabase(
|
|||
}
|
||||
|
||||
/// @brief release a collection (so it can be dropped)
|
||||
arangodb::LogicalCollection* MMFilesWalRecoverState::releaseCollection(
|
||||
std::shared_ptr<arangodb::LogicalCollection> MMFilesWalRecoverState::releaseCollection(
|
||||
TRI_voc_cid_t collectionId) {
|
||||
auto it = openedCollections.find(collectionId);
|
||||
|
||||
|
@ -189,10 +189,9 @@ arangodb::LogicalCollection* MMFilesWalRecoverState::releaseCollection(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
arangodb::LogicalCollection* collection = it->second;
|
||||
|
||||
std::shared_ptr<arangodb::LogicalCollection>& collection = it->second;
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
collection->vocbase().releaseCollection(collection);
|
||||
collection->vocbase().releaseCollection(collection.get());
|
||||
openedCollections.erase(collectionId);
|
||||
|
||||
return collection;
|
||||
|
@ -205,12 +204,12 @@ arangodb::LogicalCollection* MMFilesWalRecoverState::useCollection(
|
|||
|
||||
if (it != openedCollections.end()) {
|
||||
res = TRI_ERROR_NO_ERROR;
|
||||
return (*it).second;
|
||||
return (*it).second.get();
|
||||
}
|
||||
|
||||
TRI_set_errno(TRI_ERROR_NO_ERROR);
|
||||
TRI_vocbase_col_status_e status; // ignored here
|
||||
arangodb::LogicalCollection* collection =
|
||||
std::shared_ptr<arangodb::LogicalCollection> collection =
|
||||
vocbase->useCollection(collectionId, status);
|
||||
|
||||
if (collection == nullptr) {
|
||||
|
@ -232,7 +231,7 @@ arangodb::LogicalCollection* MMFilesWalRecoverState::useCollection(
|
|||
|
||||
openedCollections.emplace(collectionId, collection);
|
||||
res = TRI_ERROR_NO_ERROR;
|
||||
return collection;
|
||||
return collection.get();
|
||||
}
|
||||
|
||||
/// @brief looks up a collection
|
||||
|
@ -672,11 +671,9 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
|
|||
return true;
|
||||
}
|
||||
|
||||
arangodb::LogicalCollection* collection =
|
||||
state->releaseCollection(collectionId);
|
||||
|
||||
if (collection == nullptr) {
|
||||
collection = vocbase->lookupCollection(collectionId).get();
|
||||
auto collection = state->releaseCollection(collectionId);
|
||||
if (!collection) {
|
||||
collection = vocbase->lookupCollection(collectionId);
|
||||
}
|
||||
|
||||
if (collection == nullptr) {
|
||||
|
@ -995,11 +992,9 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
|
|||
return true;
|
||||
}
|
||||
|
||||
arangodb::LogicalCollection* collection =
|
||||
state->releaseCollection(collectionId);
|
||||
|
||||
if (collection == nullptr) {
|
||||
collection = vocbase->lookupCollection(collectionId).get();
|
||||
auto collection = state->releaseCollection(collectionId);
|
||||
if (!collection) {
|
||||
collection = vocbase->lookupCollection(collectionId);
|
||||
}
|
||||
|
||||
if (collection != nullptr) {
|
||||
|
@ -1017,7 +1012,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
|
|||
|
||||
if (nameSlice.isString()) {
|
||||
name = nameSlice.copyString();
|
||||
collection = vocbase->lookupCollection(name).get();
|
||||
collection = vocbase->lookupCollection(name);
|
||||
|
||||
if (collection != nullptr) {
|
||||
auto otherCid = collection->id();
|
||||
|
@ -1058,10 +1053,10 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
|
|||
// restore the old behavior afterwards
|
||||
TRI_DEFER(state->databaseFeature->forceSyncProperties(oldSync));
|
||||
|
||||
collection = vocbase->createCollection(b2.slice()).get();
|
||||
collection = vocbase->createCollection(b2.slice());
|
||||
} else {
|
||||
// collection will be kept
|
||||
collection = vocbase->createCollection(b2.slice()).get();
|
||||
collection = vocbase->createCollection(b2.slice());
|
||||
}
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
} catch (basics::Exception const& ex) {
|
||||
|
@ -1335,11 +1330,10 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
|
|||
}
|
||||
|
||||
// ignore any potential error returned by this call
|
||||
arangodb::LogicalCollection* collection =
|
||||
state->releaseCollection(collectionId);
|
||||
auto collection = state->releaseCollection(collectionId);
|
||||
|
||||
if (collection == nullptr) {
|
||||
collection = vocbase->lookupCollection(collectionId).get();
|
||||
collection = vocbase->lookupCollection(collectionId);
|
||||
}
|
||||
|
||||
if (collection != nullptr) {
|
||||
|
@ -1547,7 +1541,7 @@ int MMFilesWalRecoverState::fillIndexes() {
|
|||
// release all collections
|
||||
for (auto it = openedCollections.begin(); it != openedCollections.end();
|
||||
++it) {
|
||||
arangodb::LogicalCollection* collection = (*it).second;
|
||||
std::shared_ptr<arangodb::LogicalCollection>& collection = (*it).second;
|
||||
auto physical = static_cast<MMFilesCollection*>(collection->getPhysical());
|
||||
|
||||
TRI_ASSERT(physical != nullptr);
|
||||
|
|
|
@ -125,7 +125,7 @@ struct MMFilesWalRecoverState {
|
|||
TRI_vocbase_t* releaseDatabase(TRI_voc_tick_t);
|
||||
|
||||
/// @brief release a collection (so it can be dropped)
|
||||
arangodb::LogicalCollection* releaseCollection(TRI_voc_cid_t);
|
||||
std::shared_ptr<arangodb::LogicalCollection> releaseCollection(TRI_voc_cid_t);
|
||||
|
||||
/// @brief gets a collection (and inserts it into the cache if not in it)
|
||||
arangodb::LogicalCollection* useCollection(TRI_vocbase_t*, TRI_voc_cid_t, int&);
|
||||
|
@ -178,7 +178,8 @@ struct MMFilesWalRecoverState {
|
|||
|
||||
TRI_voc_tick_t lastTick;
|
||||
std::vector<MMFilesWalLogfile*> logfilesToProcess;
|
||||
std::unordered_map<TRI_voc_cid_t, arangodb::LogicalCollection*> openedCollections;
|
||||
std::unordered_map<TRI_voc_cid_t,
|
||||
std::shared_ptr<arangodb::LogicalCollection>> openedCollections;
|
||||
std::unordered_map<TRI_voc_tick_t, TRI_vocbase_t*> openedDatabases;
|
||||
std::vector<std::string> emptyLogfiles;
|
||||
|
||||
|
|
|
@ -766,9 +766,9 @@ Result Syncer::dropIndex(arangodb::velocypack::Slice const& slice) {
|
|||
return Result(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
auto* col = resolveCollection(*vocbase, slice).get();
|
||||
auto col = resolveCollection(*vocbase, slice);
|
||||
|
||||
if (col == nullptr) {
|
||||
if (!col) {
|
||||
return Result(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
|
@ -678,9 +678,9 @@ Result TailingSyncer::changeCollection(VPackSlice const& slice) {
|
|||
return Result(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
auto* col = resolveCollection(*vocbase, slice).get();
|
||||
auto col = resolveCollection(*vocbase, slice);
|
||||
|
||||
if (col == nullptr) {
|
||||
if (!col) {
|
||||
if (isDeleted) {
|
||||
// not a problem if a collection that is going to be deleted anyway
|
||||
// does not exist on slave
|
||||
|
|
|
@ -105,7 +105,7 @@ void RocksDBReplicationContext::removeVocbase(TRI_vocbase_t& vocbase) {
|
|||
|
||||
auto it = _iterators.begin();
|
||||
while (it != _iterators.end()) {
|
||||
if (it->second->dbGuard.database().id() == vocbase.id()) {
|
||||
if (it->second->vocbase.id() == vocbase.id()) {
|
||||
if (it->second->isUsed()) {
|
||||
LOG_TOPIC(ERR, Logger::REPLICATION) << "trying to delete used context";
|
||||
} else {
|
||||
|
@ -736,7 +736,7 @@ void RocksDBReplicationContext::use(double ttl) {
|
|||
// make sure the WAL files are not deleted
|
||||
std::set<TRI_vocbase_t*> dbs;
|
||||
for (auto& pair : _iterators) {
|
||||
dbs.emplace(&pair.second->dbGuard.database());
|
||||
dbs.emplace(&pair.second->vocbase);
|
||||
}
|
||||
for (TRI_vocbase_t* vocbase : dbs) {
|
||||
vocbase->updateReplicationClient(replicationClientId(), _snapshotTick, ttl);
|
||||
|
@ -754,7 +754,7 @@ void RocksDBReplicationContext::release() {
|
|||
// make sure the WAL files are not deleted immediately
|
||||
std::set<TRI_vocbase_t*> dbs;
|
||||
for (auto& pair : _iterators) {
|
||||
dbs.emplace(&pair.second->dbGuard.database());
|
||||
dbs.emplace(&pair.second->vocbase);
|
||||
}
|
||||
for (TRI_vocbase_t* vocbase : dbs) {
|
||||
vocbase->updateReplicationClient(replicationClientId(), _snapshotTick, ttl);
|
||||
|
@ -782,7 +782,7 @@ RocksDBReplicationContext::CollectionIterator::CollectionIterator(
|
|||
TRI_vocbase_t& vocbase,
|
||||
std::shared_ptr<LogicalCollection> const& coll,
|
||||
bool sorted, rocksdb::Snapshot const* snapshot)
|
||||
: dbGuard(vocbase),
|
||||
: vocbase(vocbase),
|
||||
logical{coll},
|
||||
iter{nullptr},
|
||||
bounds{RocksDBKeyBounds::Empty()},
|
||||
|
@ -797,17 +797,33 @@ RocksDBReplicationContext::CollectionIterator::CollectionIterator(
|
|||
_isUsed{false},
|
||||
_sortedIterator{!sorted} // this makes sure that setSorted works
|
||||
{
|
||||
TRI_ASSERT(snapshot != nullptr);
|
||||
TRI_ASSERT(snapshot != nullptr && coll);
|
||||
_readOptions.snapshot = snapshot;
|
||||
_readOptions.verify_checksums = false;
|
||||
_readOptions.fill_cache = false;
|
||||
_readOptions.prefix_same_as_start = true;
|
||||
|
||||
if (!vocbase.use()) { // false if vobase was deleted
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||
}
|
||||
TRI_vocbase_col_status_e ignore;
|
||||
int res = vocbase.useCollection(logical.get(), ignore);
|
||||
if (res != TRI_ERROR_NO_ERROR) { // collection was deleted
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
|
||||
}
|
||||
|
||||
_cTypeHandler.reset(transaction::Context::createCustomTypeHandler(vocbase, _resolver));
|
||||
vpackOptions.customTypeHandler = _cTypeHandler.get();
|
||||
setSorted(sorted);
|
||||
}
|
||||
|
||||
RocksDBReplicationContext::CollectionIterator::~CollectionIterator() {
|
||||
TRI_ASSERT(!vocbase.isDangling());
|
||||
vocbase.releaseCollection(logical.get());
|
||||
logical.reset();
|
||||
vocbase.release();
|
||||
}
|
||||
|
||||
void RocksDBReplicationContext::CollectionIterator::setSorted(bool sorted) {
|
||||
if (_sortedIterator != sorted) {
|
||||
iter.reset();
|
||||
|
@ -904,7 +920,7 @@ RocksDBReplicationContext::getCollectionIterator(TRI_vocbase_t& vocbase,
|
|||
}
|
||||
|
||||
if (cIter) {
|
||||
TRI_ASSERT(cIter->dbGuard.database().id() == vocbase.id());
|
||||
TRI_ASSERT(cIter->vocbase.id() == vocbase.id());
|
||||
cIter->use();
|
||||
|
||||
if (allowCreate && cIter->sorted() != sorted) {
|
||||
|
@ -915,7 +931,7 @@ RocksDBReplicationContext::getCollectionIterator(TRI_vocbase_t& vocbase,
|
|||
// for initial synchronization. the inventory request and collection
|
||||
// dump requests will all happen after the batch creation, so the
|
||||
// current tick value here is good
|
||||
cIter->dbGuard.database().updateReplicationClient(replicationClientId(), _snapshotTick, _ttl);
|
||||
cIter->vocbase.updateReplicationClient(replicationClientId(), _snapshotTick, _ttl);
|
||||
}
|
||||
|
||||
return cIter;
|
||||
|
@ -925,7 +941,7 @@ void RocksDBReplicationContext::releaseDumpIterator(CollectionIterator* it) {
|
|||
if (it) {
|
||||
TRI_ASSERT(it->isUsed());
|
||||
if (!it->hasMore()) {
|
||||
it->dbGuard.database().updateReplicationClient(replicationClientId(), _snapshotTick, _ttl);
|
||||
it->vocbase.updateReplicationClient(replicationClientId(), _snapshotTick, _ttl);
|
||||
MUTEX_LOCKER(locker, _contextLock);
|
||||
_iterators.erase(it->logical->id());
|
||||
} else { // Context::release() will update the replication client
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "RocksDBEngine/RocksDBReplicationCommon.h"
|
||||
#include "Transaction/Methods.h"
|
||||
#include "Utils/CollectionNameResolver.h"
|
||||
#include "Utils/DatabaseGuard.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
#include <rocksdb/options.h>
|
||||
|
@ -49,7 +48,6 @@ namespace rocksdb {
|
|||
}
|
||||
|
||||
namespace arangodb {
|
||||
class DatabaseGuard;
|
||||
|
||||
class RocksDBReplicationContext {
|
||||
private:
|
||||
|
@ -62,8 +60,9 @@ class RocksDBReplicationContext {
|
|||
CollectionIterator(TRI_vocbase_t&,
|
||||
std::shared_ptr<LogicalCollection> const&,
|
||||
bool sorted, rocksdb::Snapshot const*);
|
||||
~CollectionIterator();
|
||||
|
||||
DatabaseGuard dbGuard;
|
||||
TRI_vocbase_t& vocbase;
|
||||
std::shared_ptr<LogicalCollection> logical;
|
||||
|
||||
/// Iterator over primary index or documents
|
||||
|
|
|
@ -594,11 +594,10 @@ class WALParser final : public rocksdb::WriteBatch::Handler {
|
|||
return it->second.collection();
|
||||
}
|
||||
|
||||
auto* collection = _vocbase->lookupCollection(cid).get();
|
||||
|
||||
if (collection != nullptr) {
|
||||
auto collection = _vocbase->lookupCollection(cid);
|
||||
if (collection) {
|
||||
_collectionCache.emplace(cid, CollectionGuard(_vocbase, collection));
|
||||
return collection;
|
||||
return collection.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ int RocksDBTransactionCollection::use(int nestingLevel) {
|
|||
_usageLocked = true;
|
||||
} else {
|
||||
// use without usage-lock (lock already set externally)
|
||||
_collection = _transaction->vocbase().lookupCollection(_cid).get();
|
||||
_collection = _transaction->vocbase().lookupCollection(_cid);
|
||||
|
||||
if (_collection == nullptr) {
|
||||
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
|
||||
|
@ -246,7 +246,7 @@ void RocksDBTransactionCollection::release() {
|
|||
LOG_TRX(_transaction, 0) << "unusing collection " << _cid;
|
||||
|
||||
if (_usageLocked) {
|
||||
_transaction->vocbase().releaseCollection(_collection);
|
||||
_transaction->vocbase().releaseCollection(_collection.get());
|
||||
_usageLocked = false;
|
||||
}
|
||||
|
||||
|
@ -390,10 +390,7 @@ int RocksDBTransactionCollection::doLock(AccessMode::Type type,
|
|||
|
||||
TRI_ASSERT(!isLocked());
|
||||
|
||||
LogicalCollection* collection = _collection;
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
|
||||
auto physical = static_cast<RocksDBCollection*>(collection->getPhysical());
|
||||
auto physical = static_cast<RocksDBCollection*>(_collection->getPhysical());
|
||||
TRI_ASSERT(physical != nullptr);
|
||||
|
||||
double timeout = _transaction->timeout();
|
||||
|
@ -473,10 +470,9 @@ int RocksDBTransactionCollection::doUnlock(AccessMode::Type type,
|
|||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
LogicalCollection* collection = _collection;
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
TRI_ASSERT(_collection);
|
||||
|
||||
auto physical = static_cast<RocksDBCollection*>(collection->getPhysical());
|
||||
auto physical = static_cast<RocksDBCollection*>(_collection->getPhysical());
|
||||
TRI_ASSERT(physical != nullptr);
|
||||
|
||||
LOG_TRX(_transaction, nestingLevel) << "write-unlocking collection " << _cid;
|
||||
|
|
|
@ -50,7 +50,7 @@ class TransactionCollection {
|
|||
inline TRI_voc_cid_t id() const { return _cid; }
|
||||
|
||||
LogicalCollection* collection() const {
|
||||
return _collection; // vocbase collection pointer
|
||||
return _collection.get(); // vocbase collection pointer
|
||||
}
|
||||
|
||||
std::string collectionName() const;
|
||||
|
@ -91,10 +91,10 @@ class TransactionCollection {
|
|||
virtual void release() = 0;
|
||||
|
||||
protected:
|
||||
TransactionState* _transaction; // the transaction state
|
||||
TRI_voc_cid_t const _cid; // collection id
|
||||
LogicalCollection* _collection; // vocbase collection pointer
|
||||
AccessMode::Type _accessType; // access type (read|write)
|
||||
TransactionState* _transaction; // the transaction state
|
||||
TRI_voc_cid_t const _cid; // collection id
|
||||
std::shared_ptr<LogicalCollection> _collection; // vocbase collection pointer
|
||||
AccessMode::Type _accessType; // access type (read|write)
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -47,13 +47,13 @@ class CollectionGuard {
|
|||
}
|
||||
|
||||
/// @brief create the guard, using a collection id
|
||||
CollectionGuard(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
CollectionGuard(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid,
|
||||
bool restoreOriginalStatus = false)
|
||||
: _vocbase(vocbase),
|
||||
_collection(nullptr),
|
||||
_originalStatus(TRI_VOC_COL_STATUS_CORRUPTED),
|
||||
_restoreOriginalStatus(restoreOriginalStatus) {
|
||||
_collection = _vocbase->useCollection(id, _originalStatus);
|
||||
_collection = _vocbase->useCollection(cid, _originalStatus);
|
||||
|
||||
if (_collection == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
|
||||
|
@ -67,11 +67,9 @@ class CollectionGuard {
|
|||
_originalStatus(TRI_VOC_COL_STATUS_CORRUPTED),
|
||||
_restoreOriginalStatus(false) {
|
||||
_collection = _vocbase->useCollection(id, _originalStatus);
|
||||
|
||||
if (_collection == nullptr && !name.empty()) {
|
||||
if (!_collection && !name.empty()) {
|
||||
_collection = _vocbase->useCollection(name, _originalStatus);
|
||||
}
|
||||
|
||||
if (_collection == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
|
||||
}
|
||||
|
@ -96,12 +94,13 @@ class CollectionGuard {
|
|||
}
|
||||
}
|
||||
|
||||
CollectionGuard(TRI_vocbase_t* vocbase, LogicalCollection* collection)
|
||||
CollectionGuard(TRI_vocbase_t* vocbase,
|
||||
std::shared_ptr<LogicalCollection> const& collection)
|
||||
: _vocbase(vocbase),
|
||||
_collection(collection),
|
||||
_originalStatus(TRI_VOC_COL_STATUS_CORRUPTED),
|
||||
_restoreOriginalStatus(false) {
|
||||
int res = _vocbase->useCollection(collection, _originalStatus);
|
||||
int res = _vocbase->useCollection(collection.get(), _originalStatus);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
|
||||
}
|
||||
|
@ -110,13 +109,13 @@ class CollectionGuard {
|
|||
/// @brief destroy the guard
|
||||
~CollectionGuard() {
|
||||
if (_collection != nullptr) {
|
||||
_vocbase->releaseCollection(_collection);
|
||||
_vocbase->releaseCollection(_collection.get());
|
||||
|
||||
if (_restoreOriginalStatus &&
|
||||
(_originalStatus == TRI_VOC_COL_STATUS_UNLOADING ||
|
||||
_originalStatus == TRI_VOC_COL_STATUS_UNLOADED)) {
|
||||
// re-unload the collection
|
||||
_vocbase->unloadCollection(_collection, false);
|
||||
_vocbase->unloadCollection(_collection.get(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,13 +124,13 @@ class CollectionGuard {
|
|||
/// @brief prematurely release the usage lock
|
||||
void release() {
|
||||
if (_collection != nullptr) {
|
||||
_vocbase->releaseCollection(_collection);
|
||||
_vocbase->releaseCollection(_collection.get());
|
||||
_collection = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief return the collection pointer
|
||||
inline arangodb::LogicalCollection* collection() const { return _collection; }
|
||||
inline arangodb::LogicalCollection* collection() const { return _collection.get(); }
|
||||
|
||||
/// @brief return the status of the collection at the time of using the guard
|
||||
inline TRI_vocbase_col_status_e originalStatus() const {
|
||||
|
@ -143,7 +142,7 @@ class CollectionGuard {
|
|||
TRI_vocbase_t* _vocbase;
|
||||
|
||||
/// @brief pointer to collection
|
||||
arangodb::LogicalCollection* _collection;
|
||||
std::shared_ptr<arangodb::LogicalCollection> _collection;
|
||||
|
||||
/// @brief status of collection when invoking the guard
|
||||
TRI_vocbase_col_status_e _originalStatus;
|
||||
|
|
|
@ -1552,56 +1552,48 @@ int TRI_vocbase_t::useCollection(arangodb::LogicalCollection* collection,
|
|||
}
|
||||
|
||||
/// @brief locks a (document) collection for usage by id
|
||||
arangodb::LogicalCollection* TRI_vocbase_t::useCollection(
|
||||
std::shared_ptr<arangodb::LogicalCollection> TRI_vocbase_t::useCollection(
|
||||
TRI_voc_cid_t cid, TRI_vocbase_col_status_e& status) {
|
||||
auto collection = lookupCollection(cid);
|
||||
|
||||
return useCollectionInternal(collection.get(), status);
|
||||
return useCollectionInternal(lookupCollection(cid), status);
|
||||
}
|
||||
|
||||
/// @brief locks a collection for usage by name
|
||||
arangodb::LogicalCollection* TRI_vocbase_t::useCollection(
|
||||
std::shared_ptr<arangodb::LogicalCollection> TRI_vocbase_t::useCollection(
|
||||
std::string const& name, TRI_vocbase_col_status_e& status) {
|
||||
// check that we have an existing name
|
||||
arangodb::LogicalCollection* collection = nullptr;
|
||||
|
||||
std::shared_ptr<arangodb::LogicalCollection> collection;
|
||||
{
|
||||
RECURSIVE_READ_LOCKER(_dataSourceLock, _dataSourceLockWriteOwner);
|
||||
|
||||
auto it = _dataSourceByName.find(name);
|
||||
|
||||
if (it != _dataSourceByName.end()
|
||||
&& it->second->category() == LogicalCollection::category()) {
|
||||
TRI_ASSERT(std::dynamic_pointer_cast<LogicalCollection>(it->second));
|
||||
collection = static_cast<LogicalCollection*>(it->second.get());
|
||||
collection = std::static_pointer_cast<LogicalCollection>(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
return useCollectionInternal(collection, status);
|
||||
return useCollectionInternal(std::move(collection), status);
|
||||
}
|
||||
|
||||
/// @brief locks a collection for usage by name
|
||||
arangodb::LogicalCollection* TRI_vocbase_t::useCollectionByUuid(
|
||||
std::shared_ptr<arangodb::LogicalCollection> TRI_vocbase_t::useCollectionByUuid(
|
||||
std::string const& uuid, TRI_vocbase_col_status_e& status) {
|
||||
auto collection = lookupCollectionByUuid(uuid);
|
||||
|
||||
return useCollectionInternal(collection.get(), status);
|
||||
return useCollectionInternal(lookupCollectionByUuid(uuid), status);
|
||||
}
|
||||
|
||||
arangodb::LogicalCollection* TRI_vocbase_t::useCollectionInternal(
|
||||
arangodb::LogicalCollection* collection, TRI_vocbase_col_status_e& status) {
|
||||
if (collection == nullptr) {
|
||||
std::shared_ptr<arangodb::LogicalCollection> TRI_vocbase_t::useCollectionInternal(
|
||||
std::shared_ptr<arangodb::LogicalCollection> coll, TRI_vocbase_col_status_e& status) {
|
||||
if (!coll) {
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// try to load the collection
|
||||
int res = loadCollection(collection, status);
|
||||
|
||||
int res = loadCollection(coll.get(), status);
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
return collection;
|
||||
return coll;
|
||||
}
|
||||
|
||||
TRI_set_errno(res);
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -370,22 +370,22 @@ struct TRI_vocbase_t {
|
|||
/// Note that this will READ lock the collection you have to release the
|
||||
/// collection lock by yourself and call @ref TRI_ReleaseCollectionVocBase
|
||||
/// when you are done with the collection.
|
||||
arangodb::LogicalCollection* useCollection(TRI_voc_cid_t cid,
|
||||
TRI_vocbase_col_status_e&);
|
||||
std::shared_ptr<arangodb::LogicalCollection> useCollection(TRI_voc_cid_t cid,
|
||||
TRI_vocbase_col_status_e&);
|
||||
|
||||
/// @brief locks a collection for usage by name
|
||||
/// Note that this will READ lock the collection you have to release the
|
||||
/// collection lock by yourself and call @ref TRI_ReleaseCollectionVocBase
|
||||
/// when you are done with the collection.
|
||||
arangodb::LogicalCollection* useCollection(std::string const& name,
|
||||
TRI_vocbase_col_status_e&);
|
||||
std::shared_ptr<arangodb::LogicalCollection> useCollection(std::string const& name,
|
||||
TRI_vocbase_col_status_e&);
|
||||
|
||||
/// @brief locks a collection for usage by uuid
|
||||
/// Note that this will READ lock the collection you have to release the
|
||||
/// collection lock by yourself and call @ref TRI_ReleaseCollectionVocBase
|
||||
/// when you are done with the collection.
|
||||
arangodb::LogicalCollection* useCollectionByUuid(std::string const& uuid,
|
||||
TRI_vocbase_col_status_e&);
|
||||
std::shared_ptr<arangodb::LogicalCollection> useCollectionByUuid(std::string const& uuid,
|
||||
TRI_vocbase_col_status_e&);
|
||||
|
||||
/// @brief releases a collection from usage
|
||||
void releaseCollection(arangodb::LogicalCollection* collection);
|
||||
|
@ -405,8 +405,8 @@ struct TRI_vocbase_t {
|
|||
/// @brief check some invariants on the various lists of collections
|
||||
void checkCollectionInvariants() const;
|
||||
|
||||
arangodb::LogicalCollection* useCollectionInternal(
|
||||
arangodb::LogicalCollection* collection, TRI_vocbase_col_status_e& status);
|
||||
std::shared_ptr<arangodb::LogicalCollection> useCollectionInternal(
|
||||
std::shared_ptr<arangodb::LogicalCollection>, TRI_vocbase_col_status_e& status);
|
||||
|
||||
int loadCollection(arangodb::LogicalCollection* collection,
|
||||
TRI_vocbase_col_status_e& status, bool setStatus = true);
|
||||
|
@ -455,4 +455,4 @@ void TRI_SanitizeObject(arangodb::velocypack::Slice const slice,
|
|||
void TRI_SanitizeObjectWithEdges(arangodb::velocypack::Slice const slice,
|
||||
arangodb::velocypack::Builder& builder);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1447,7 +1447,7 @@ int TransactionCollectionMock::lockRecursive(arangodb::AccessMode::Type type, in
|
|||
|
||||
void TransactionCollectionMock::release() {
|
||||
if (_collection) {
|
||||
_transaction->vocbase().releaseCollection(_collection);
|
||||
_transaction->vocbase().releaseCollection(_collection.get());
|
||||
_collection = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue