mirror of https://gitee.com/bigwinds/arangodb
Moved primaryIndex knowledge out of Logical Collection. Also moved logic for close into MMFiles
This commit is contained in:
parent
7cf3581812
commit
fbdbfdcb6d
|
@ -411,11 +411,6 @@ MMFilesCollection::MMFilesCollection(LogicalCollection* logical, PhysicalCollect
|
||||||
}
|
}
|
||||||
|
|
||||||
MMFilesCollection::~MMFilesCollection() {
|
MMFilesCollection::~MMFilesCollection() {
|
||||||
try {
|
|
||||||
close();
|
|
||||||
} catch (...) {
|
|
||||||
// dtor must not propagate exceptions
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_voc_rid_t MMFilesCollection::revision() const {
|
TRI_voc_rid_t MMFilesCollection::revision() const {
|
||||||
|
@ -439,6 +434,30 @@ void MMFilesCollection::updateCount(int64_t count) {
|
||||||
|
|
||||||
/// @brief closes an open collection
|
/// @brief closes an open collection
|
||||||
int MMFilesCollection::close() {
|
int MMFilesCollection::close() {
|
||||||
|
if (!_logicalCollection->_isDeleted) {
|
||||||
|
auto primIdx = primaryIndex();
|
||||||
|
auto idxSize = primIdx->size();
|
||||||
|
|
||||||
|
if (initialCount() != static_cast<int64_t>(idxSize)) {
|
||||||
|
updateCount(idxSize);
|
||||||
|
|
||||||
|
// save new "count" value
|
||||||
|
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||||
|
bool const doSync =
|
||||||
|
application_features::ApplicationServer::getFeature<DatabaseFeature>(
|
||||||
|
"Database")
|
||||||
|
->forceSyncProperties();
|
||||||
|
engine->changeCollection(_logicalCollection->vocbase(),
|
||||||
|
_logicalCollection->cid(), _logicalCollection,
|
||||||
|
doSync);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We also have to unload the indexes.
|
||||||
|
for (auto& idx : *(_logicalCollection->indexList())) {
|
||||||
|
idx->unload();
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
WRITE_LOCKER(writeLocker, _filesLock);
|
WRITE_LOCKER(writeLocker, _filesLock);
|
||||||
|
|
||||||
|
@ -1201,6 +1220,15 @@ bool MMFilesCollection::applyForTickRange(TRI_voc_tick_t dataMin, TRI_voc_tick_t
|
||||||
return false; // hasMore = false
|
return false; // hasMore = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @brief Return the number of documents in this collection
|
||||||
|
uint64_t MMFilesCollection::numberDocuments() const {
|
||||||
|
return primaryIndex()->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMFilesCollection::sizeHint(transaction::Methods* trx, int64_t hint) {
|
||||||
|
primaryIndex()->resize(trx, static_cast<size_t>(hint * 1.1));
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief report extra memory used by indexes etc.
|
/// @brief report extra memory used by indexes etc.
|
||||||
size_t MMFilesCollection::memory() const {
|
size_t MMFilesCollection::memory() const {
|
||||||
return 0; // TODO
|
return 0; // TODO
|
||||||
|
@ -1282,6 +1310,30 @@ void MMFilesCollection::fillIndex(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief return the primary index
|
||||||
|
// WARNING: Make sure that this LogicalCollection Instance
|
||||||
|
// is somehow protected. If it goes out of all scopes
|
||||||
|
// or it's indexes are freed the pointer returned will get invalidated.
|
||||||
|
arangodb::MMFilesPrimaryIndex* MMFilesCollection::primaryIndex() const {
|
||||||
|
// The primary index always has iid 0
|
||||||
|
auto primary = _logicalCollection->lookupIndex(0);
|
||||||
|
TRI_ASSERT(primary != nullptr);
|
||||||
|
|
||||||
|
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||||
|
if (primary->type() != Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX) {
|
||||||
|
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
|
||||||
|
<< "got invalid indexes for collection '" << _logicalCollection->name()
|
||||||
|
<< "'";
|
||||||
|
for (auto const& it : *(_logicalCollection->indexList())) {
|
||||||
|
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "- " << it.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
TRI_ASSERT(primary->type() == Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX);
|
||||||
|
// the primary index must be the index at position #0
|
||||||
|
return static_cast<arangodb::MMFilesPrimaryIndex*>(primary.get());
|
||||||
|
}
|
||||||
|
|
||||||
int MMFilesCollection::fillAllIndexes(transaction::Methods* trx) {
|
int MMFilesCollection::fillAllIndexes(transaction::Methods* trx) {
|
||||||
return fillIndexes(trx, *(_logicalCollection->indexList()));
|
return fillIndexes(trx, *(_logicalCollection->indexList()));
|
||||||
}
|
}
|
||||||
|
@ -1326,9 +1378,9 @@ int MMFilesCollection::fillIndexes(
|
||||||
// only log performance infos for indexes with more than this number of
|
// only log performance infos for indexes with more than this number of
|
||||||
// entries
|
// entries
|
||||||
static size_t const NotificationSizeThreshold = 131072;
|
static size_t const NotificationSizeThreshold = 131072;
|
||||||
auto primaryIndex = _logicalCollection->primaryIndex();
|
auto primaryIdx = primaryIndex();
|
||||||
|
|
||||||
if (primaryIndex->size() > NotificationSizeThreshold) {
|
if (primaryIdx->size() > NotificationSizeThreshold) {
|
||||||
LOG_TOPIC(TRACE, Logger::PERFORMANCE)
|
LOG_TOPIC(TRACE, Logger::PERFORMANCE)
|
||||||
<< "fill-indexes-document-collection { collection: "
|
<< "fill-indexes-document-collection { collection: "
|
||||||
<< _logicalCollection->vocbase() << "/" << _logicalCollection->name()
|
<< _logicalCollection->vocbase() << "/" << _logicalCollection->name()
|
||||||
|
@ -1341,7 +1393,7 @@ int MMFilesCollection::fillIndexes(
|
||||||
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
||||||
|
|
||||||
// give the index a size hint
|
// give the index a size hint
|
||||||
auto nrUsed = primaryIndex->size();
|
auto nrUsed = primaryIdx->size();
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
auto idx = indexes[i];
|
auto idx = indexes[i];
|
||||||
if (idx->type() == Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX) {
|
if (idx->type() == Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX) {
|
||||||
|
@ -1388,7 +1440,7 @@ int MMFilesCollection::fillIndexes(
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
MMFilesSimpleIndexElement element =
|
MMFilesSimpleIndexElement element =
|
||||||
primaryIndex->lookupSequential(trx, position, total);
|
primaryIdx->lookupSequential(trx, position, total);
|
||||||
|
|
||||||
if (!element) {
|
if (!element) {
|
||||||
break;
|
break;
|
||||||
|
@ -2131,7 +2183,7 @@ int MMFilesCollection::endWrite(bool useDeadlockDetector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMFilesCollection::truncate(transaction::Methods* trx, OperationOptions& options) {
|
void MMFilesCollection::truncate(transaction::Methods* trx, OperationOptions& options) {
|
||||||
auto primaryIndex = _logicalCollection->primaryIndex();
|
auto primaryIdx = primaryIndex();
|
||||||
|
|
||||||
options.ignoreRevs = true;
|
options.ignoreRevs = true;
|
||||||
|
|
||||||
|
@ -2158,7 +2210,7 @@ void MMFilesCollection::truncate(transaction::Methods* trx, OperationOptions& op
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
primaryIndex->invokeOnAllElementsForRemoval(callback);
|
primaryIdx->invokeOnAllElementsForRemoval(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MMFilesCollection::insert(transaction::Methods* trx,
|
int MMFilesCollection::insert(transaction::Methods* trx,
|
||||||
|
@ -2404,7 +2456,7 @@ int MMFilesCollection::insertPrimaryIndex(transaction::Methods* trx,
|
||||||
TRI_IF_FAILURE("InsertPrimaryIndex") { return TRI_ERROR_DEBUG; }
|
TRI_IF_FAILURE("InsertPrimaryIndex") { return TRI_ERROR_DEBUG; }
|
||||||
|
|
||||||
// insert into primary index
|
// insert into primary index
|
||||||
return _logicalCollection->primaryIndex()->insertKey(trx, revisionId, doc);
|
return primaryIndex()->insertKey(trx, revisionId, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief deletes an entry from the primary index
|
/// @brief deletes an entry from the primary index
|
||||||
|
@ -2413,7 +2465,7 @@ int MMFilesCollection::deletePrimaryIndex(arangodb::transaction::Methods* trx,
|
||||||
VPackSlice const& doc) {
|
VPackSlice const& doc) {
|
||||||
TRI_IF_FAILURE("DeletePrimaryIndex") { return TRI_ERROR_DEBUG; }
|
TRI_IF_FAILURE("DeletePrimaryIndex") { return TRI_ERROR_DEBUG; }
|
||||||
|
|
||||||
return _logicalCollection->primaryIndex()->removeKey(trx, revisionId, doc);
|
return primaryIndex()->removeKey(trx, revisionId, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief creates a new entry in the secondary indexes
|
/// @brief creates a new entry in the secondary indexes
|
||||||
|
@ -3121,7 +3173,7 @@ int MMFilesCollection::lookupDocument(transaction::Methods* trx,
|
||||||
}
|
}
|
||||||
|
|
||||||
MMFilesSimpleIndexElement element =
|
MMFilesSimpleIndexElement element =
|
||||||
_logicalCollection->primaryIndex()->lookupKey(trx, key, result);
|
primaryIndex()->lookupKey(trx, key, result);
|
||||||
if (element) {
|
if (element) {
|
||||||
TRI_voc_rid_t revisionId = element.revisionId();
|
TRI_voc_rid_t revisionId = element.revisionId();
|
||||||
uint8_t const* vpack = lookupRevisionVPack(revisionId);
|
uint8_t const* vpack = lookupRevisionVPack(revisionId);
|
||||||
|
@ -3165,7 +3217,7 @@ int MMFilesCollection::updateDocument(
|
||||||
// adjusted)
|
// adjusted)
|
||||||
VPackSlice keySlice(transaction::helpers::extractKeyFromDocument(newDoc));
|
VPackSlice keySlice(transaction::helpers::extractKeyFromDocument(newDoc));
|
||||||
MMFilesSimpleIndexElement* element =
|
MMFilesSimpleIndexElement* element =
|
||||||
_logicalCollection->primaryIndex()->lookupKeyRef(trx, keySlice);
|
primaryIndex()->lookupKeyRef(trx, keySlice);
|
||||||
if (element != nullptr && element->revisionId() != 0) {
|
if (element != nullptr && element->revisionId() != 0) {
|
||||||
element->updateRevisionId(
|
element->updateRevisionId(
|
||||||
newRevisionId,
|
newRevisionId,
|
||||||
|
|
|
@ -66,9 +66,10 @@ class MMFilesCollection final : public PhysicalCollection {
|
||||||
int64_t _initialCount;
|
int64_t _initialCount;
|
||||||
bool const _trackKeys;
|
bool const _trackKeys;
|
||||||
|
|
||||||
OpenIteratorState(LogicalCollection* collection, transaction::Methods* trx)
|
OpenIteratorState(LogicalCollection* collection, transaction::Methods* trx)
|
||||||
: _collection(collection),
|
: _collection(collection),
|
||||||
_primaryIndex(collection->primaryIndex()),
|
_primaryIndex(static_cast<MMFilesCollection*>(collection->getPhysical())
|
||||||
|
->primaryIndex()),
|
||||||
_tid(0),
|
_tid(0),
|
||||||
_fid(0),
|
_fid(0),
|
||||||
_stats(),
|
_stats(),
|
||||||
|
@ -169,6 +170,10 @@ class MMFilesCollection final : public PhysicalCollection {
|
||||||
_datafileStatistics.update(fid, values);
|
_datafileStatistics.update(fid, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t numberDocuments() const override;
|
||||||
|
|
||||||
|
void sizeHint(transaction::Methods* trx, int64_t hint) override;
|
||||||
|
|
||||||
/// @brief report extra memory used by indexes etc.
|
/// @brief report extra memory used by indexes etc.
|
||||||
size_t memory() const override;
|
size_t memory() const override;
|
||||||
|
|
||||||
|
@ -228,6 +233,11 @@ class MMFilesCollection final : public PhysicalCollection {
|
||||||
// -- SECTION Indexes --
|
// -- SECTION Indexes --
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
|
||||||
|
// WARNING: Make sure that this Collection Instance
|
||||||
|
// is somehow protected. If it goes out of all scopes
|
||||||
|
// or it's indexes are freed the pointer returned will get invalidated.
|
||||||
|
MMFilesPrimaryIndex* primaryIndex() const;
|
||||||
|
|
||||||
inline bool useSecondaryIndexes() const { return _useSecondaryIndexes; }
|
inline bool useSecondaryIndexes() const { return _useSecondaryIndexes; }
|
||||||
|
|
||||||
void useSecondaryIndexes(bool value) { _useSecondaryIndexes = value; }
|
void useSecondaryIndexes(bool value) { _useSecondaryIndexes = value; }
|
||||||
|
|
|
@ -562,6 +562,7 @@ void MMFilesCollectorThread::processCollectionMarker(
|
||||||
LogicalCollection* collection, MMFilesCollectorCache* cache,
|
LogicalCollection* collection, MMFilesCollectorCache* cache,
|
||||||
MMFilesCollectorOperation const& operation) {
|
MMFilesCollectorOperation const& operation) {
|
||||||
auto physical = static_cast<MMFilesCollection*>(collection->getPhysical());
|
auto physical = static_cast<MMFilesCollection*>(collection->getPhysical());
|
||||||
|
TRI_ASSERT(physical != nullptr);
|
||||||
auto const* walMarker = reinterpret_cast<TRI_df_marker_t const*>(operation.walPosition);
|
auto const* walMarker = reinterpret_cast<TRI_df_marker_t const*>(operation.walPosition);
|
||||||
TRI_ASSERT(walMarker != nullptr);
|
TRI_ASSERT(walMarker != nullptr);
|
||||||
TRI_ASSERT(reinterpret_cast<TRI_df_marker_t const*>(operation.datafilePosition));
|
TRI_ASSERT(reinterpret_cast<TRI_df_marker_t const*>(operation.datafilePosition));
|
||||||
|
@ -582,7 +583,7 @@ void MMFilesCollectorThread::processCollectionMarker(
|
||||||
transaction::helpers::extractKeyAndRevFromDocument(slice, keySlice, revisionId);
|
transaction::helpers::extractKeyAndRevFromDocument(slice, keySlice, revisionId);
|
||||||
|
|
||||||
bool wasAdjusted = false;
|
bool wasAdjusted = false;
|
||||||
MMFilesSimpleIndexElement element = collection->primaryIndex()->lookupKey(&trx, keySlice);
|
MMFilesSimpleIndexElement element = physical->primaryIndex()->lookupKey(&trx, keySlice);
|
||||||
|
|
||||||
if (element &&
|
if (element &&
|
||||||
element.revisionId() == revisionId) {
|
element.revisionId() == revisionId) {
|
||||||
|
@ -613,7 +614,7 @@ void MMFilesCollectorThread::processCollectionMarker(
|
||||||
TRI_voc_rid_t revisionId = 0;
|
TRI_voc_rid_t revisionId = 0;
|
||||||
transaction::helpers::extractKeyAndRevFromDocument(slice, keySlice, revisionId);
|
transaction::helpers::extractKeyAndRevFromDocument(slice, keySlice, revisionId);
|
||||||
|
|
||||||
MMFilesSimpleIndexElement found = collection->primaryIndex()->lookupKey(&trx, keySlice);
|
MMFilesSimpleIndexElement found = physical->primaryIndex()->lookupKey(&trx, keySlice);
|
||||||
|
|
||||||
if (found &&
|
if (found &&
|
||||||
found.revisionId() > revisionId) {
|
found.revisionId() > revisionId) {
|
||||||
|
|
|
@ -272,6 +272,9 @@ MMFilesCompactorThread::CompactionInitialContext MMFilesCompactorThread::getComp
|
||||||
/// @brief datafile iterator, calculates necessary total size
|
/// @brief datafile iterator, calculates necessary total size
|
||||||
auto calculateSize = [&context](TRI_df_marker_t const* marker, MMFilesDatafile* datafile) -> bool {
|
auto calculateSize = [&context](TRI_df_marker_t const* marker, MMFilesDatafile* datafile) -> bool {
|
||||||
LogicalCollection* collection = context._collection;
|
LogicalCollection* collection = context._collection;
|
||||||
|
TRI_ASSERT(collection != nullptr);
|
||||||
|
auto physical = static_cast<MMFilesCollection*>(collection->getPhysical());
|
||||||
|
TRI_ASSERT(physical != nullptr);
|
||||||
TRI_df_marker_type_t const type = marker->getType();
|
TRI_df_marker_type_t const type = marker->getType();
|
||||||
|
|
||||||
// new or updated document
|
// new or updated document
|
||||||
|
@ -282,12 +285,15 @@ MMFilesCompactorThread::CompactionInitialContext MMFilesCompactorThread::getComp
|
||||||
VPackSlice keySlice = transaction::helpers::extractKeyFromDocument(slice);
|
VPackSlice keySlice = transaction::helpers::extractKeyFromDocument(slice);
|
||||||
|
|
||||||
// check if the document is still active
|
// check if the document is still active
|
||||||
auto primaryIndex = collection->primaryIndex();
|
auto primaryIndex = physical->primaryIndex();
|
||||||
TRI_df_marker_t const* markerPtr = nullptr;
|
TRI_df_marker_t const* markerPtr = nullptr;
|
||||||
MMFilesSimpleIndexElement element = primaryIndex->lookupKey(context._trx, keySlice);
|
MMFilesSimpleIndexElement element = primaryIndex->lookupKey(context._trx, keySlice);
|
||||||
if (element) {
|
if (element) {
|
||||||
MMFilesDocumentPosition const old = static_cast<MMFilesCollection*>(collection->getPhysical())->lookupRevision(element.revisionId());
|
MMFilesDocumentPosition const old =
|
||||||
markerPtr = reinterpret_cast<TRI_df_marker_t const*>(static_cast<uint8_t const*>(old.dataptr()) - MMFilesDatafileHelper::VPackOffset(TRI_DF_MARKER_VPACK_DOCUMENT));
|
physical->lookupRevision(element.revisionId());
|
||||||
|
markerPtr = reinterpret_cast<TRI_df_marker_t const*>(
|
||||||
|
static_cast<uint8_t const*>(old.dataptr()) -
|
||||||
|
MMFilesDatafileHelper::VPackOffset(TRI_DF_MARKER_VPACK_DOCUMENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deleted = (markerPtr == nullptr || marker != markerPtr);
|
bool deleted = (markerPtr == nullptr || marker != markerPtr);
|
||||||
|
@ -361,7 +367,7 @@ void MMFilesCompactorThread::compactDatafiles(LogicalCollection* collection,
|
||||||
/// file.
|
/// file.
|
||||||
/// IMPORTANT: if the logic inside this function is adjusted, the total size
|
/// IMPORTANT: if the logic inside this function is adjusted, the total size
|
||||||
/// calculated by function CalculateSize might need adjustment, too!!
|
/// calculated by function CalculateSize might need adjustment, too!!
|
||||||
auto compactifier = [&context, &collection, &physical, this](TRI_df_marker_t const* marker, MMFilesDatafile* datafile) -> bool {
|
auto compactifier = [&context, &physical, this](TRI_df_marker_t const* marker, MMFilesDatafile* datafile) -> bool {
|
||||||
TRI_voc_fid_t const targetFid = context->_compactor->fid();
|
TRI_voc_fid_t const targetFid = context->_compactor->fid();
|
||||||
|
|
||||||
TRI_df_marker_type_t const type = marker->getType();
|
TRI_df_marker_type_t const type = marker->getType();
|
||||||
|
@ -374,7 +380,7 @@ void MMFilesCompactorThread::compactDatafiles(LogicalCollection* collection,
|
||||||
VPackSlice keySlice = transaction::helpers::extractKeyFromDocument(slice);
|
VPackSlice keySlice = transaction::helpers::extractKeyFromDocument(slice);
|
||||||
|
|
||||||
// check if the document is still active
|
// check if the document is still active
|
||||||
auto primaryIndex = collection->primaryIndex();
|
auto primaryIndex = physical->primaryIndex();
|
||||||
TRI_df_marker_t const* markerPtr = nullptr;
|
TRI_df_marker_t const* markerPtr = nullptr;
|
||||||
MMFilesSimpleIndexElement element = primaryIndex->lookupKey(context->_trx, keySlice);
|
MMFilesSimpleIndexElement element = primaryIndex->lookupKey(context->_trx, keySlice);
|
||||||
if (element) {
|
if (element) {
|
||||||
|
|
|
@ -157,8 +157,9 @@ void MMFilesDocumentOperation::revert(transaction::Methods* trx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let the primary index entry point to the correct document
|
// let the primary index entry point to the correct document
|
||||||
MMFilesSimpleIndexElement* element = _collection->primaryIndex()->lookupKeyRef(trx, transaction::helpers::extractKeyFromDocument(newDoc));
|
MMFilesSimpleIndexElement* element = physical->primaryIndex()->lookupKeyRef(
|
||||||
|
trx, transaction::helpers::extractKeyFromDocument(newDoc));
|
||||||
if (element != nullptr && element->revisionId() != 0) {
|
if (element != nullptr && element->revisionId() != 0) {
|
||||||
VPackSlice keySlice(transaction::helpers::extractKeyFromDocument(oldDoc));
|
VPackSlice keySlice(transaction::helpers::extractKeyFromDocument(oldDoc));
|
||||||
element->updateRevisionId(oldRevisionId, static_cast<uint32_t>(keySlice.begin() - oldDoc.begin()));
|
element->updateRevisionId(oldRevisionId, static_cast<uint32_t>(keySlice.begin() - oldDoc.begin()));
|
||||||
|
|
|
@ -571,7 +571,8 @@ PersistentIndexIterator* PersistentIndex::lookup(transaction::Methods* trx,
|
||||||
// Secured by trx. The shared_ptr index stays valid in
|
// Secured by trx. The shared_ptr index stays valid in
|
||||||
// _collection at least as long as trx is running.
|
// _collection at least as long as trx is running.
|
||||||
// Same for the iterator
|
// Same for the iterator
|
||||||
auto idx = _collection->primaryIndex();
|
auto physical = static_cast<MMFilesCollection*>(_collection->getPhysical());
|
||||||
|
auto idx = physical->primaryIndex();
|
||||||
return new PersistentIndexIterator(_collection, trx, mmdr, this, idx, _db, reverse, leftBorder, rightBorder);
|
return new PersistentIndexIterator(_collection, trx, mmdr, this, idx, _db, reverse, leftBorder, rightBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "Cluster/ServerState.h"
|
#include "Cluster/ServerState.h"
|
||||||
#include "Indexes/Index.h"
|
#include "Indexes/Index.h"
|
||||||
#include "Logger/Logger.h"
|
#include "Logger/Logger.h"
|
||||||
|
#include "MMFiles/MMFilesCollection.h"
|
||||||
#include "MMFiles/MMFilesLogfileManager.h"
|
#include "MMFiles/MMFilesLogfileManager.h"
|
||||||
#include "MMFiles/MMFilesPrimaryIndex.h"
|
#include "MMFiles/MMFilesPrimaryIndex.h"
|
||||||
#include "MMFiles/MMFilesIndexElement.h"
|
#include "MMFiles/MMFilesIndexElement.h"
|
||||||
|
@ -941,6 +942,10 @@ void transaction::Methods::invokeOnAllElements(std::string const& collectionName
|
||||||
TransactionCollection* trxCol = trxCollection(cid);
|
TransactionCollection* trxCol = trxCollection(cid);
|
||||||
LogicalCollection* document = documentCollection(trxCol);
|
LogicalCollection* document = documentCollection(trxCol);
|
||||||
|
|
||||||
|
// TODO Should not directly use PrimaryIndex
|
||||||
|
auto physical = static_cast<MMFilesCollection*>(document->getPhysical());
|
||||||
|
TRI_ASSERT(physical != nullptr);
|
||||||
|
|
||||||
orderDitch(cid); // will throw when it fails
|
orderDitch(cid); // will throw when it fails
|
||||||
|
|
||||||
int res = lock(trxCol, AccessMode::Type::READ);
|
int res = lock(trxCol, AccessMode::Type::READ);
|
||||||
|
@ -949,7 +954,7 @@ void transaction::Methods::invokeOnAllElements(std::string const& collectionName
|
||||||
THROW_ARANGO_EXCEPTION(res);
|
THROW_ARANGO_EXCEPTION(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto primaryIndex = document->primaryIndex();
|
auto primaryIndex = physical->primaryIndex();
|
||||||
primaryIndex->invokeOnAllElements(callback);
|
primaryIndex->invokeOnAllElements(callback);
|
||||||
|
|
||||||
res = unlock(trxCol, AccessMode::Type::READ);
|
res = unlock(trxCol, AccessMode::Type::READ);
|
||||||
|
@ -2566,7 +2571,11 @@ std::unique_ptr<OperationCursor> transaction::Methods::indexScan(
|
||||||
|
|
||||||
switch (cursorType) {
|
switch (cursorType) {
|
||||||
case CursorType::ANY: {
|
case CursorType::ANY: {
|
||||||
arangodb::MMFilesPrimaryIndex* idx = document->primaryIndex();
|
// TODO Should not directly use PrimaryIndex
|
||||||
|
auto physical = static_cast<MMFilesCollection*>(document->getPhysical());
|
||||||
|
TRI_ASSERT(physical != nullptr);
|
||||||
|
|
||||||
|
arangodb::MMFilesPrimaryIndex* idx = physical->primaryIndex();
|
||||||
|
|
||||||
if (idx == nullptr) {
|
if (idx == nullptr) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||||
|
@ -2578,7 +2587,11 @@ std::unique_ptr<OperationCursor> transaction::Methods::indexScan(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CursorType::ALL: {
|
case CursorType::ALL: {
|
||||||
arangodb::MMFilesPrimaryIndex* idx = document->primaryIndex();
|
// TODO Should not directly use PrimaryIndex
|
||||||
|
auto physical = static_cast<MMFilesCollection*>(document->getPhysical());
|
||||||
|
TRI_ASSERT(physical != nullptr);
|
||||||
|
|
||||||
|
arangodb::MMFilesPrimaryIndex* idx = physical->primaryIndex();
|
||||||
|
|
||||||
if (idx == nullptr) {
|
if (idx == nullptr) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||||
|
|
|
@ -521,9 +521,9 @@ bool LogicalCollection::IsAllowedName(bool allowSystem,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @brief Return the number of documents in this collection
|
||||||
uint64_t LogicalCollection::numberDocuments() const {
|
uint64_t LogicalCollection::numberDocuments() const {
|
||||||
// TODO Ask StorageEngine instead
|
return getPhysical()->numberDocuments();
|
||||||
return primaryIndex()->size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -659,28 +659,6 @@ LogicalCollection::getIndexes() const {
|
||||||
return _indexes;
|
return _indexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief return the primary index
|
|
||||||
// WARNING: Make sure that this LogicalCollection Instance
|
|
||||||
// is somehow protected. If it goes out of all scopes
|
|
||||||
// or it's indexes are freed the pointer returned will get invalidated.
|
|
||||||
arangodb::MMFilesPrimaryIndex* LogicalCollection::primaryIndex() const {
|
|
||||||
TRI_ASSERT(!_indexes.empty());
|
|
||||||
|
|
||||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
|
||||||
if (_indexes[0]->type() != Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX) {
|
|
||||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "got invalid indexes for collection '" << _name << "'";
|
|
||||||
for (auto const& it : _indexes) {
|
|
||||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "- " << it.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TRI_ASSERT(_indexes[0]->type() ==
|
|
||||||
Index::IndexType::TRI_IDX_TYPE_PRIMARY_INDEX);
|
|
||||||
// the primary index must be the index at position #0
|
|
||||||
return static_cast<arangodb::MMFilesPrimaryIndex*>(_indexes[0].get());
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogicalCollection::getIndexesVPack(VPackBuilder& result,
|
void LogicalCollection::getIndexesVPack(VPackBuilder& result,
|
||||||
bool withFigures) const {
|
bool withFigures) const {
|
||||||
result.openArray();
|
result.openArray();
|
||||||
|
@ -845,27 +823,6 @@ int LogicalCollection::rename(std::string const& newName) {
|
||||||
|
|
||||||
int LogicalCollection::close() {
|
int LogicalCollection::close() {
|
||||||
// This was unload() in 3.0
|
// This was unload() in 3.0
|
||||||
auto primIdx = primaryIndex();
|
|
||||||
auto idxSize = primIdx->size();
|
|
||||||
|
|
||||||
if (!_isDeleted &&
|
|
||||||
_physical->initialCount() != static_cast<int64_t>(idxSize)) {
|
|
||||||
_physical->updateCount(idxSize);
|
|
||||||
|
|
||||||
// save new "count" value
|
|
||||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
|
||||||
bool const doSync =
|
|
||||||
application_features::ApplicationServer::getFeature<DatabaseFeature>(
|
|
||||||
"Database")
|
|
||||||
->forceSyncProperties();
|
|
||||||
engine->changeCollection(_vocbase, _cid, this, doSync);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We also have to unload the indexes.
|
|
||||||
for (auto& idx : _indexes) {
|
|
||||||
idx->unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
return getPhysical()->close();
|
return getPhysical()->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1163,6 +1120,7 @@ std::shared_ptr<Index> LogicalCollection::createIndex(transaction::Methods* trx,
|
||||||
created = true;
|
created = true;
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = getPhysical()->saveIndex(trx, idx);
|
int res = getPhysical()->saveIndex(trx, idx);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -1222,7 +1180,6 @@ bool LogicalCollection::removeIndex(TRI_idx_iid_t iid) {
|
||||||
/// @brief drops an index, including index file removal and replication
|
/// @brief drops an index, including index file removal and replication
|
||||||
bool LogicalCollection::dropIndex(TRI_idx_iid_t iid, bool writeMarker) {
|
bool LogicalCollection::dropIndex(TRI_idx_iid_t iid, bool writeMarker) {
|
||||||
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
||||||
// TODO: Validate that writeMarker := (engine->inRevocery() == false)
|
|
||||||
return _physical->dropIndex(iid, writeMarker);
|
return _physical->dropIndex(iid, writeMarker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,12 +1416,7 @@ void LogicalCollection::sizeHint(transaction::Methods* trx, int64_t hint) {
|
||||||
if (hint <= 0) {
|
if (hint <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
getPhysical()->sizeHint(trx, hint);
|
||||||
int res = primaryIndex()->resize(trx, static_cast<size_t>(hint * 1.1));
|
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LogicalCollection::readDocument(transaction::Methods* trx, DocumentIdentifierToken const& token, ManagedDocumentResult& result) {
|
bool LogicalCollection::readDocument(transaction::Methods* trx, DocumentIdentifierToken const& token, ManagedDocumentResult& result) {
|
||||||
|
|
|
@ -187,12 +187,7 @@ class LogicalCollection {
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Index>> const& getIndexes() const;
|
std::vector<std::shared_ptr<Index>> const& getIndexes() const;
|
||||||
|
|
||||||
// WARNING: Make sure that this LogicalCollection Instance
|
// Adds all properties to the builder (has to be an open object)
|
||||||
// is somehow protected. If it goes out of all scopes
|
|
||||||
// or it's indexes are freed the pointer returned will get invalidated.
|
|
||||||
MMFilesPrimaryIndex* primaryIndex() const;
|
|
||||||
|
|
||||||
// Adds all properties to the builder (has to be an open object)
|
|
||||||
// Does not add Shards or Indexes
|
// Does not add Shards or Indexes
|
||||||
void getPropertiesVPack(velocypack::Builder&,
|
void getPropertiesVPack(velocypack::Builder&,
|
||||||
bool translateCids) const;
|
bool translateCids) const;
|
||||||
|
@ -372,7 +367,9 @@ private:
|
||||||
|
|
||||||
// SECTION: Properties
|
// SECTION: Properties
|
||||||
bool _isLocal;
|
bool _isLocal;
|
||||||
|
public:
|
||||||
bool _isDeleted;
|
bool _isDeleted;
|
||||||
|
protected:
|
||||||
bool const _isSystem;
|
bool const _isSystem;
|
||||||
bool const _isVolatile;
|
bool const _isVolatile;
|
||||||
bool _waitForSync;
|
bool _waitForSync;
|
||||||
|
|
|
@ -78,6 +78,11 @@ class PhysicalCollection {
|
||||||
virtual bool applyForTickRange(TRI_voc_tick_t dataMin, TRI_voc_tick_t dataMax,
|
virtual bool applyForTickRange(TRI_voc_tick_t dataMin, TRI_voc_tick_t dataMax,
|
||||||
std::function<bool(TRI_voc_tick_t foundTick, TRI_df_marker_t const* marker)> const& callback) = 0;
|
std::function<bool(TRI_voc_tick_t foundTick, TRI_df_marker_t const* marker)> const& callback) = 0;
|
||||||
|
|
||||||
|
// @brief Return the number of documents in this collection
|
||||||
|
virtual uint64_t numberDocuments() const = 0;
|
||||||
|
|
||||||
|
virtual void sizeHint(transaction::Methods* trx, int64_t hint) = 0;
|
||||||
|
|
||||||
/// @brief report extra memory used by indexes etc.
|
/// @brief report extra memory used by indexes etc.
|
||||||
virtual size_t memory() const = 0;
|
virtual size_t memory() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "V8Server/v8-user-structures.h"
|
#include "V8Server/v8-user-structures.h"
|
||||||
#include "VocBase/Ditch.h"
|
#include "VocBase/Ditch.h"
|
||||||
#include "VocBase/LogicalCollection.h"
|
#include "VocBase/LogicalCollection.h"
|
||||||
|
#include "VocBase/PhysicalCollection.h"
|
||||||
#include "VocBase/replication-applier.h"
|
#include "VocBase/replication-applier.h"
|
||||||
#include "VocBase/ticks.h"
|
#include "VocBase/ticks.h"
|
||||||
|
|
||||||
|
@ -652,6 +653,7 @@ void TRI_vocbase_t::shutdown() {
|
||||||
|
|
||||||
// free collections
|
// free collections
|
||||||
for (auto& collection : _collections) {
|
for (auto& collection : _collections) {
|
||||||
|
collection->getPhysical()->close();
|
||||||
delete collection;
|
delete collection;
|
||||||
}
|
}
|
||||||
_collections.clear();
|
_collections.clear();
|
||||||
|
|
Loading…
Reference in New Issue