本文整理汇总了C++中IndexDescriptor类的典型用法代码示例。如果您正苦于以下问题:C++ IndexDescriptor类的具体用法?C++ IndexDescriptor怎么用?C++ IndexDescriptor使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了IndexDescriptor类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getCollection
Status Database::renameCollection( OperationContext* txn,
const StringData& fromNS,
const StringData& toNS,
bool stayTemp ) {
audit::logRenameCollection( currentClient.get(), fromNS, toNS );
{ // remove anything cached
Collection* coll = getCollection( txn, fromNS );
if ( !coll )
return Status( ErrorCodes::NamespaceNotFound, "collection not found to rename" );
IndexCatalog::IndexIterator ii = coll->getIndexCatalog()->getIndexIterator( true );
while ( ii.more() ) {
IndexDescriptor* desc = ii.next();
_clearCollectionCache( desc->indexNamespace() );
}
{
scoped_lock lk( _collectionLock );
_clearCollectionCache_inlock( fromNS );
_clearCollectionCache_inlock( toNS );
}
Top::global.collectionDropped( fromNS.toString() );
}
return _dbEntry->renameCollection( txn, fromNS, toNS, stayTemp );
}
示例2: while
long long Database::getIndexSizeForCollection(OperationContext* opCtx,
Collection* coll,
BSONObjBuilder* details,
int scale ) {
if ( !coll )
return 0;
IndexCatalog::IndexIterator ii =
coll->getIndexCatalog()->getIndexIterator( true /*includeUnfinishedIndexes*/ );
long long totalSize = 0;
while ( ii.more() ) {
IndexDescriptor* d = ii.next();
string indNS = d->indexNamespace();
// XXX creating a Collection for an index which isn't a Collection
Collection* indColl = getCollection( opCtx, indNS );
if ( ! indColl ) {
log() << "error: have index descriptor [" << indNS
<< "] but no entry in the index collection." << endl;
continue;
}
totalSize += indColl->dataSize();
if ( details ) {
long long const indexSize = indColl->dataSize() / scale;
details->appendNumber( d->indexName() , indexSize );
}
}
return totalSize;
}
示例3: getIndex
IndexAccessMethod* KVDatabaseCatalogEntry::getIndex(OperationContext* opCtx,
const CollectionCatalogEntry* collection,
IndexCatalogEntry* index) {
IndexDescriptor* desc = index->descriptor();
const std::string& type = desc->getAccessMethodName();
std::string ident =
_engine->getCatalog()->getIndexIdent(opCtx, collection->ns().ns(), desc->indexName());
SortedDataInterface* sdi =
_engine->getEngine()->getGroupedSortedDataInterface(opCtx, ident, desc, index->getPrefix());
if ("" == type)
return new BtreeAccessMethod(index, sdi);
if (IndexNames::HASHED == type)
return new HashAccessMethod(index, sdi);
if (IndexNames::GEO_2DSPHERE == type)
return new S2AccessMethod(index, sdi);
if (IndexNames::TEXT == type)
return new FTSAccessMethod(index, sdi);
if (IndexNames::GEO_HAYSTACK == type)
return new HaystackAccessMethod(index, sdi);
if (IndexNames::GEO_2D == type)
return new TwoDAccessMethod(index, sdi);
log() << "Can't find index for keyPattern " << desc->keyPattern();
invariant(false);
}
示例4: invariant
Status Database::renameCollection(OperationContext* txn,
StringData fromNS,
StringData toNS,
bool stayTemp) {
audit::logRenameCollection(&cc(), fromNS, toNS);
invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X));
BackgroundOperation::assertNoBgOpInProgForNs(fromNS);
BackgroundOperation::assertNoBgOpInProgForNs(toNS);
{ // remove anything cached
Collection* coll = getCollection(fromNS);
if (!coll)
return Status(ErrorCodes::NamespaceNotFound, "collection not found to rename");
string clearCacheReason = str::stream() << "renamed collection '" << fromNS << "' to '"
<< toNS << "'";
IndexCatalog::IndexIterator ii = coll->getIndexCatalog()->getIndexIterator(txn, true);
while (ii.more()) {
IndexDescriptor* desc = ii.next();
_clearCollectionCache(txn, desc->indexNamespace(), clearCacheReason);
}
_clearCollectionCache(txn, fromNS, clearCacheReason);
_clearCollectionCache(txn, toNS, clearCacheReason);
Top::get(txn->getClient()->getServiceContext()).collectionDropped(fromNS.toString());
}
txn->recoveryUnit()->registerChange(new AddCollectionChange(txn, this, toNS));
Status s = _dbEntry->renameCollection(txn, fromNS, toNS, stayTemp);
_collections[toNS] = _getOrCreateCollectionInstance(txn, toNS);
return s;
}
示例5: run
void run() {
OperationContextImpl txn;
Client::WriteContext ctx(&txn, _ns);
int numFinishedIndexesStart = _catalog->numIndexesReady(&txn);
Helpers::ensureIndex(&txn, _coll, BSON("x" << 1), false, "_x_0");
Helpers::ensureIndex(&txn, _coll, BSON("y" << 1), false, "_y_0");
ASSERT_TRUE(_catalog->numIndexesReady(&txn) == numFinishedIndexesStart+2);
IndexCatalog::IndexIterator ii = _catalog->getIndexIterator(&txn,false);
int indexesIterated = 0;
bool foundIndex = false;
while (ii.more()) {
IndexDescriptor* indexDesc = ii.next();
indexesIterated++;
BSONObjIterator boit(indexDesc->infoObj());
while (boit.more() && !foundIndex) {
BSONElement e = boit.next();
if (str::equals(e.fieldName(), "name") &&
str::equals(e.valuestrsafe(), "_y_0")) {
foundIndex = true;
break;
}
}
}
ctx.commit();
ASSERT_TRUE(indexesIterated == _catalog->numIndexesReady(&txn));
ASSERT_TRUE(foundIndex);
}
示例6: invariant
Status Database::renameCollection( OperationContext* txn,
StringData fromNS,
StringData toNS,
bool stayTemp ) {
audit::logRenameCollection( currentClient.get(), fromNS, toNS );
invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X));
{ // remove anything cached
Collection* coll = getCollection( fromNS );
if ( !coll )
return Status( ErrorCodes::NamespaceNotFound, "collection not found to rename" );
IndexCatalog::IndexIterator ii = coll->getIndexCatalog()->getIndexIterator( txn, true );
while ( ii.more() ) {
IndexDescriptor* desc = ii.next();
_clearCollectionCache( txn, desc->indexNamespace() );
}
_clearCollectionCache( txn, fromNS );
_clearCollectionCache( txn, toNS );
Top::global.collectionDropped( fromNS.toString() );
}
txn->recoveryUnit()->registerChange( new AddCollectionChange(this, toNS) );
Status s = _dbEntry->renameCollection( txn, fromNS, toNS, stayTemp );
_collections[toNS] = _getOrCreateCollectionInstance(txn, toNS);
return s;
}
示例7: run
void run() {
IndexDescriptor* id = addIndexWithInfo();
// Create a SortPhaseOne.
SortPhaseOne phaseOne;
phaseOne.sorter.reset( new BSONObjExternalSorter(_aFirstSort));
// Add index keys to the phaseOne.
int32_t nKeys = 130;
for( int32_t i = 0; i < nKeys; ++i ) {
phaseOne.sorter->add( BSON( "a" << i ), /* dummy disk loc */ DiskLoc(), false );
}
phaseOne.nkeys = phaseOne.n = nKeys;
phaseOne.sorter->sort( false );
// Set up remaining arguments.
set<DiskLoc> dups;
CurOp* op = cc().curop();
ProgressMeterHolder pm (op->setMessage("BuildBottomUp",
"BuildBottomUp Progress",
nKeys,
nKeys));
pm.finished();
Timer timer;
// The index's root has not yet been set.
ASSERT( id->getHead().isNull() );
// Finish building the index.
buildBottomUpPhases2And3<V1>( true,
id,
*phaseOne.sorter,
false,
dups,
op,
&phaseOne,
pm,
timer,
true );
// The index's root is set after the build is complete.
ASSERT( !id->getHead().isNull() );
// Create a cursor over the index.
scoped_ptr<BtreeCursor> cursor(
BtreeCursor::make( nsdetails( _ns ),
id->getOnDisk(),
BSON( "" << -1 ), // startKey below minimum key.
BSON( "" << nKeys ), // endKey above maximum key.
true, // endKeyInclusive true.
1 // direction forward.
) );
// Check that the keys in the index are the expected ones.
int32_t expectedKey = 0;
for( ; cursor->ok(); cursor->advance(), ++expectedKey ) {
ASSERT_EQUALS( expectedKey, cursor->currKey().firstElement().number() );
}
ASSERT_EQUALS( nKeys, expectedKey );
}
示例8: while
void CollectionInfoCache::computeIndexKeys() {
DEV Lock::assertWriteLocked( _collection->ns().ns() );
_indexedPaths.clear();
IndexCatalog::IndexIterator i = _collection->getIndexCatalog()->getIndexIterator(true);
while (i.more()) {
IndexDescriptor* descriptor = i.next();
if (descriptor->getAccessMethodName() != IndexNames::TEXT) {
BSONObj key = descriptor->keyPattern();
BSONObjIterator j(key);
while (j.more()) {
BSONElement e = j.next();
_indexedPaths.addPath(e.fieldName());
}
}
else {
fts::FTSSpec ftsSpec(descriptor->infoObj());
if (ftsSpec.wildcard()) {
_indexedPaths.allPathsIndexed();
}
else {
for (size_t i = 0; i < ftsSpec.numExtraBefore(); ++i) {
_indexedPaths.addPath(ftsSpec.extraBefore(i));
}
for (fts::Weights::const_iterator it = ftsSpec.weights().begin();
it != ftsSpec.weights().end();
++it) {
_indexedPaths.addPath(it->first);
}
for (size_t i = 0; i < ftsSpec.numExtraAfter(); ++i) {
_indexedPaths.addPath(ftsSpec.extraAfter(i));
}
// Any update to a path containing "language" as a component could change the
// language of a subdocument. Add the override field as a path component.
_indexedPaths.addPathComponent(ftsSpec.languageOverrideField());
}
}
}
_keysComputed = true;
}
示例9: getIndexCatalog
uint64_t Collection::getIndexSize(OperationContext* opCtx, BSONObjBuilder* details, int scale) {
IndexCatalog* idxCatalog = getIndexCatalog();
IndexCatalog::IndexIterator ii = idxCatalog->getIndexIterator(opCtx, true);
uint64_t totalSize = 0;
while (ii.more()) {
IndexDescriptor* d = ii.next();
IndexAccessMethod* iam = idxCatalog->getIndex(d);
long long ds = iam->getSpaceUsedBytes(opCtx);
totalSize += ds;
if (details) {
details->appendNumber(d->indexName(), ds / scale);
}
}
return totalSize;
}
示例10: run
void run() {
Client::WriteContext ctx(_ns);
int numFinishedIndexesStart = _catalog->numIndexesReady();
BSONObjBuilder b1;
b1.append("key", BSON("x" << 1));
b1.append("ns", _ns);
b1.append("name", "_x_0");
_catalog->createIndex(b1.obj(), true);
BSONObjBuilder b2;
b2.append("key", BSON("y" << 1));
b2.append("ns", _ns);
b2.append("name", "_y_0");
_catalog->createIndex(b2.obj(), true);
ASSERT_TRUE(_catalog->numIndexesReady() == numFinishedIndexesStart+2);
IndexCatalog::IndexIterator ii = _catalog->getIndexIterator(false);
int indexesIterated = 0;
bool foundIndex = false;
while (ii.more()) {
IndexDescriptor* indexDesc = ii.next();
indexesIterated++;
BSONObjIterator boit(indexDesc->infoObj());
while (boit.more() && !foundIndex) {
BSONElement e = boit.next();
if (str::equals(e.fieldName(), "name") &&
str::equals(e.valuestrsafe(), "_y_0")) {
foundIndex = true;
break;
}
}
}
ASSERT_TRUE(indexesIterated == _catalog->numIndexesReady());
ASSERT_TRUE(foundIndex);
}
示例11: ii
StatusWith<CompactStats> Collection::compact( OperationContext* txn,
const CompactOptions* compactOptions ) {
if ( !_recordStore->compactSupported() )
return StatusWith<CompactStats>( ErrorCodes::BadValue,
str::stream() <<
"cannot compact collection with record store: " <<
_recordStore->name() );
if ( _indexCatalog.numIndexesInProgress() )
return StatusWith<CompactStats>( ErrorCodes::BadValue,
"cannot compact when indexes in progress" );
// same data, but might perform a little different after compact?
_infoCache.reset();
vector<BSONObj> indexSpecs;
{
IndexCatalog::IndexIterator ii( _indexCatalog.getIndexIterator( false ) );
while ( ii.more() ) {
IndexDescriptor* descriptor = ii.next();
const BSONObj spec = _compactAdjustIndexSpec(descriptor->infoObj());
const BSONObj key = spec.getObjectField("key");
const Status keyStatus = validateKeyPattern(key);
if (!keyStatus.isOK()) {
return StatusWith<CompactStats>(
ErrorCodes::CannotCreateIndex,
str::stream() << "Cannot compact collection due to invalid index "
<< spec << ": " << keyStatus.reason() << " For more info see"
<< " http://dochub.mongodb.org/core/index-validation");
}
indexSpecs.push_back(spec);
}
}
// note that the drop indexes call also invalidates all clientcursors for the namespace,
// which is important and wanted here
log() << "compact dropping indexes" << endl;
Status status = _indexCatalog.dropAllIndexes(txn, true);
if ( !status.isOK() ) {
return StatusWith<CompactStats>( status );
}
txn->checkForInterrupt();
CompactStats stats;
MultiIndexBlock multiIndexBlock(txn, this);
status = multiIndexBlock.init( indexSpecs );
if ( !status.isOK() )
return StatusWith<CompactStats>( status );
MyCompactAdaptor adaptor(this, &multiIndexBlock);
_recordStore->compact( txn, &adaptor, compactOptions, &stats );
log() << "starting index commits";
status = multiIndexBlock.commit();
if ( !status.isOK() )
return StatusWith<CompactStats>( status );
return StatusWith<CompactStats>( stats );
}
示例12: scopedXact
Status MigrationChunkClonerSourceLegacy::_storeCurrentLocs(OperationContext* txn) {
ScopedTransaction scopedXact(txn, MODE_IS);
AutoGetCollection autoColl(txn, _args.getNss(), MODE_IS);
Collection* const collection = autoColl.getCollection();
if (!collection) {
return {ErrorCodes::NamespaceNotFound,
str::stream() << "Collection " << _args.getNss().ns() << " does not exist."};
}
// Allow multiKey based on the invariant that shard keys must be single-valued. Therefore, any
// multi-key index prefixed by shard key cannot be multikey over the shard key fields.
IndexDescriptor* idx =
collection->getIndexCatalog()->findShardKeyPrefixedIndex(txn,
_shardKeyPattern.toBSON(),
false); // requireSingleKey
if (!idx) {
return {ErrorCodes::IndexNotFound,
str::stream() << "can't find index with prefix " << _shardKeyPattern.toBSON()
<< " in storeCurrentLocs for "
<< _args.getNss().ns()};
}
// Install the stage, which will listen for notifications on the collection
{
stdx::lock_guard<stdx::mutex> sl(_mutex);
invariant(!_deleteNotifyExec);
// Takes ownership of 'ws' and 'dns'.
auto statusWithPlanExecutor =
PlanExecutor::make(txn,
stdx::make_unique<WorkingSet>(),
stdx::make_unique<DeleteNotificationStage>(this, txn),
collection,
PlanExecutor::YIELD_MANUAL);
invariant(statusWithPlanExecutor.isOK());
_deleteNotifyExec = std::move(statusWithPlanExecutor.getValue());
_deleteNotifyExec->registerExec(collection);
}
// Assume both min and max non-empty, append MinKey's to make them fit chosen index
const KeyPattern kp(idx->keyPattern());
BSONObj min = Helpers::toKeyFormat(kp.extendRangeBound(_args.getMinKey(), false));
BSONObj max = Helpers::toKeyFormat(kp.extendRangeBound(_args.getMaxKey(), false));
std::unique_ptr<PlanExecutor> exec(InternalPlanner::indexScan(txn,
collection,
idx,
min,
max,
false, // endKeyInclusive
PlanExecutor::YIELD_MANUAL));
// We can afford to yield here because any change to the base data that we might miss is already
// being queued and will migrate in the 'transferMods' stage.
exec->setYieldPolicy(PlanExecutor::YIELD_AUTO, collection);
// Use the average object size to estimate how many objects a full chunk would carry do that
// while traversing the chunk's range using the sharding index, below there's a fair amount of
// slack before we determine a chunk is too large because object sizes will vary.
unsigned long long maxRecsWhenFull;
long long avgRecSize;
const long long totalRecs = collection->numRecords(txn);
if (totalRecs > 0) {
avgRecSize = collection->dataSize(txn) / totalRecs;
maxRecsWhenFull = _args.getMaxChunkSizeBytes() / avgRecSize;
maxRecsWhenFull = std::min((unsigned long long)(Chunk::MaxObjectPerChunk + 1),
130 * maxRecsWhenFull / 100 /* slack */);
} else {
avgRecSize = 0;
maxRecsWhenFull = Chunk::MaxObjectPerChunk + 1;
}
// Do a full traversal of the chunk and don't stop even if we think it is a large chunk we want
// the number of records to better report, in that case.
bool isLargeChunk = false;
unsigned long long recCount = 0;
BSONObj obj;
RecordId recordId;
PlanExecutor::ExecState state;
while (PlanExecutor::ADVANCED == (state = exec->getNext(&obj, &recordId))) {
if (!isLargeChunk) {
stdx::lock_guard<stdx::mutex> lk(_mutex);
_cloneLocs.insert(recordId);
}
if (++recCount > maxRecsWhenFull) {
isLargeChunk = true;
// Continue on despite knowing that it will fail, just to get the correct value for
// recCount
}
}
if (PlanExecutor::DEAD == state || PlanExecutor::FAILURE == state) {
return {ErrorCodes::InternalError,
//.........这里部分代码省略.........
示例13: checkValidation
StatusWith<RecordId> Collection::updateDocument(OperationContext* txn,
const RecordId& oldLocation,
const Snapshotted<BSONObj>& oldDoc,
const BSONObj& newDoc,
bool enforceQuota,
bool indexesAffected,
OpDebug* debug,
oplogUpdateEntryArgs& args) {
{
auto status = checkValidation(txn, newDoc);
if (!status.isOK()) {
if (_validationLevel == STRICT_V) {
return status;
}
// moderate means we have to check the old doc
auto oldDocStatus = checkValidation(txn, oldDoc.value());
if (oldDocStatus.isOK()) {
// transitioning from good -> bad is not ok
return status;
}
// bad -> bad is ok in moderate mode
}
}
dassert(txn->lockState()->isCollectionLockedForMode(ns().toString(), MODE_IX));
invariant(oldDoc.snapshotId() == txn->recoveryUnit()->getSnapshotId());
if (_needCappedLock) {
// X-lock the metadata resource for this capped collection until the end of the WUOW. This
// prevents the primary from executing with more concurrency than secondaries.
// See SERVER-21646.
Lock::ResourceLock{txn->lockState(), ResourceId(RESOURCE_METADATA, _ns.ns()), MODE_X};
}
SnapshotId sid = txn->recoveryUnit()->getSnapshotId();
BSONElement oldId = oldDoc.value()["_id"];
if (!oldId.eoo() && (oldId != newDoc["_id"]))
return StatusWith<RecordId>(
ErrorCodes::InternalError, "in Collection::updateDocument _id mismatch", 13596);
// The MMAPv1 storage engine implements capped collections in a way that does not allow records
// to grow beyond their original size. If MMAPv1 part of a replicaset with storage engines that
// do not have this limitation, replication could result in errors, so it is necessary to set a
// uniform rule here. Similarly, it is not sufficient to disallow growing records, because this
// happens when secondaries roll back an update shrunk a record. Exactly replicating legacy
// MMAPv1 behavior would require padding shrunk documents on all storage engines. Instead forbid
// all size changes.
const auto oldSize = oldDoc.value().objsize();
if (_recordStore->isCapped() && oldSize != newDoc.objsize())
return {ErrorCodes::CannotGrowDocumentInCappedNamespace,
str::stream() << "Cannot change the size of a document in a capped collection: "
<< oldSize << " != " << newDoc.objsize()};
// At the end of this step, we will have a map of UpdateTickets, one per index, which
// represent the index updates needed to be done, based on the changes between oldDoc and
// newDoc.
OwnedPointerMap<IndexDescriptor*, UpdateTicket> updateTickets;
if (indexesAffected) {
IndexCatalog::IndexIterator ii = _indexCatalog.getIndexIterator(txn, true);
while (ii.more()) {
IndexDescriptor* descriptor = ii.next();
IndexCatalogEntry* entry = ii.catalogEntry(descriptor);
IndexAccessMethod* iam = ii.accessMethod(descriptor);
InsertDeleteOptions options;
options.logIfError = false;
options.dupsAllowed =
!(KeyPattern::isIdKeyPattern(descriptor->keyPattern()) || descriptor->unique()) ||
repl::getGlobalReplicationCoordinator()->shouldIgnoreUniqueIndex(descriptor);
UpdateTicket* updateTicket = new UpdateTicket();
updateTickets.mutableMap()[descriptor] = updateTicket;
Status ret = iam->validateUpdate(txn,
oldDoc.value(),
newDoc,
oldLocation,
options,
updateTicket,
entry->getFilterExpression());
if (!ret.isOK()) {
return StatusWith<RecordId>(ret);
}
}
}
// This can call back into Collection::recordStoreGoingToMove. If that happens, the old
// object is removed from all indexes.
StatusWith<RecordId> newLocation = _recordStore->updateRecord(
txn, oldLocation, newDoc.objdata(), newDoc.objsize(), _enforceQuota(enforceQuota), this);
if (!newLocation.isOK()) {
return newLocation;
}
// At this point, the old object may or may not still be indexed, depending on if it was
// moved. If the object did move, we need to add the new location to all indexes.
if (newLocation.getValue() != oldLocation) {
if (debug) {
if (debug->nmoved == -1) // default of -1 rather than 0
debug->nmoved = 1;
//.........这里部分代码省略.........
示例14: invariant
//.........这里部分代码省略.........
}
namespacesToCopy[ns] = options;
}
}
}
for ( map<string,CollectionOptions>::const_iterator i = namespacesToCopy.begin();
i != namespacesToCopy.end();
++i ) {
string ns = i->first;
CollectionOptions options = i->second;
Collection* tempCollection = NULL;
{
Client::Context tempContext(txn, ns, tempDatabase );
WriteUnitOfWork wunit(txn);
tempCollection = tempDatabase->createCollection(txn, ns, options, true, false);
wunit.commit();
}
Client::Context readContext(txn, ns, originalDatabase);
Collection* originalCollection = originalDatabase->getCollection( txn, ns );
invariant( originalCollection );
// data
// TODO SERVER-14812 add a mode that drops duplicates rather than failing
MultiIndexBlock indexer(txn, tempCollection );
{
vector<BSONObj> indexes;
IndexCatalog::IndexIterator ii =
originalCollection->getIndexCatalog()->getIndexIterator( false );
while ( ii.more() ) {
IndexDescriptor* desc = ii.next();
indexes.push_back( desc->infoObj() );
}
Client::Context tempContext(txn, ns, tempDatabase);
Status status = indexer.init( indexes );
if ( !status.isOK() )
return status;
}
scoped_ptr<RecordIterator> iterator(
originalCollection->getIterator( txn, DiskLoc(), false,
CollectionScanParams::FORWARD ));
while ( !iterator->isEOF() ) {
DiskLoc loc = iterator->getNext();
invariant( !loc.isNull() );
BSONObj doc = originalCollection->docFor( loc );
Client::Context tempContext(txn, ns, tempDatabase);
WriteUnitOfWork wunit(txn);
StatusWith<DiskLoc> result = tempCollection->insertDocument(txn,
doc,
&indexer,
false);
if ( !result.isOK() )
return result.getStatus();
wunit.commit();
txn->checkForInterrupt(false);
}
示例15: while
void CollectionInfoCache::computeIndexKeys(OperationContext* opCtx) {
_indexedPaths.clear();
bool hadTTLIndex = _hasTTLIndex;
_hasTTLIndex = false;
IndexCatalog::IndexIterator i = _collection->getIndexCatalog()->getIndexIterator(opCtx, true);
while (i.more()) {
IndexDescriptor* descriptor = i.next();
if (descriptor->getAccessMethodName() != IndexNames::TEXT) {
BSONObj key = descriptor->keyPattern();
const BSONObj& infoObj = descriptor->infoObj();
if (infoObj.hasField("expireAfterSeconds")) {
_hasTTLIndex = true;
}
BSONObjIterator j(key);
while (j.more()) {
BSONElement e = j.next();
_indexedPaths.addPath(e.fieldName());
}
} else {
fts::FTSSpec ftsSpec(descriptor->infoObj());
if (ftsSpec.wildcard()) {
_indexedPaths.allPathsIndexed();
} else {
for (size_t i = 0; i < ftsSpec.numExtraBefore(); ++i) {
_indexedPaths.addPath(ftsSpec.extraBefore(i));
}
for (fts::Weights::const_iterator it = ftsSpec.weights().begin();
it != ftsSpec.weights().end();
++it) {
_indexedPaths.addPath(it->first);
}
for (size_t i = 0; i < ftsSpec.numExtraAfter(); ++i) {
_indexedPaths.addPath(ftsSpec.extraAfter(i));
}
// Any update to a path containing "language" as a component could change the
// language of a subdocument. Add the override field as a path component.
_indexedPaths.addPathComponent(ftsSpec.languageOverrideField());
}
}
// handle partial indexes
const IndexCatalogEntry* entry = i.catalogEntry(descriptor);
const MatchExpression* filter = entry->getFilterExpression();
if (filter) {
unordered_set<std::string> paths;
QueryPlannerIXSelect::getFields(filter, "", &paths);
for (auto it = paths.begin(); it != paths.end(); ++it) {
_indexedPaths.addPath(*it);
}
}
}
TTLCollectionCache& ttlCollectionCache = TTLCollectionCache::get(getGlobalServiceContext());
if (_hasTTLIndex != hadTTLIndex) {
if (_hasTTLIndex) {
ttlCollectionCache.registerCollection(_collection->ns());
} else {
ttlCollectionCache.unregisterCollection(_collection->ns());
}
}
_keysComputed = true;
}