0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 01:21:03 +01:00

SERVER-17623 Fix direct users of BtreeBasedAccessMethod and BtreeIndexCursor

This commit is contained in:
Mathias Stearn 2015-03-17 13:39:24 -04:00
parent af9ecc763e
commit a2d60db504
23 changed files with 78 additions and 144 deletions

View File

@ -182,11 +182,7 @@ namespace mongo {
if ( indexFound )
*indexFound = 1;
// See SERVER-12397. This may not always be true.
BtreeBasedAccessMethod* accessMethod =
static_cast<BtreeBasedAccessMethod*>(catalog->getIndex( desc ));
RecordId loc = accessMethod->findSingle( txn, query["_id"].wrap() );
RecordId loc = catalog->getIndex(desc)->findSingle( txn, query["_id"].wrap() );
if ( loc.isNull() )
return false;
result = collection->docFor(txn, loc).value();
@ -200,10 +196,7 @@ namespace mongo {
IndexCatalog* catalog = collection->getIndexCatalog();
const IndexDescriptor* desc = catalog->findIdIndex( txn );
uassert(13430, "no _id index", desc);
// See SERVER-12397. This may not always be true.
BtreeBasedAccessMethod* accessMethod =
static_cast<BtreeBasedAccessMethod*>(catalog->getIndex( desc ));
return accessMethod->findSingle( txn, idquery["_id"].wrap() );
return catalog->getIndex(desc)->findSingle( txn, idquery["_id"].wrap() );
}
/* Get the first object from a collection. Generally only useful if the collection

View File

@ -48,7 +48,6 @@ namespace mongo {
_workingSet(workingSet),
_descriptor(params.descriptor),
_iam(params.descriptor->getIndexCatalog()->getIndex(params.descriptor)),
_btreeCursor(NULL),
_params(params),
_hitEnd(false),
_shouldDedup(params.descriptor->isMultikey(txn)),
@ -67,13 +66,11 @@ namespace mongo {
Status s = _iam->newCursor(_txn, cursorOptions, &cursor);
verify(s.isOK());
verify(cursor);
_cursor.reset(cursor);
// Is this assumption always valid? See SERVER-12397
_btreeCursor.reset(static_cast<BtreeIndexCursor*>(cursor));
// _btreeCursor points at our start position. We move it forward until it hits a cursor
// _cursor points at our start position. We move it forward until it hits a cursor
// that points at the end.
_btreeCursor->seek(_params.startKey, !_params.startKeyInclusive);
_cursor->seek(_params.startKey, !_params.startKeyInclusive);
++_specificStats.keysExamined;
@ -81,9 +78,7 @@ namespace mongo {
IndexCursor* endCursor;
verify(_iam->newCursor(_txn, cursorOptions, &endCursor).isOK());
verify(endCursor);
// Is this assumption always valid? See SERVER-12397
_endCursor.reset(static_cast<BtreeIndexCursor*>(endCursor));
_endCursor.reset(endCursor);
// If the end key is inclusive we want to point *past* it since that's the end.
_endCursor->seek(_params.endKey, _params.endKeyInclusive);
@ -99,11 +94,11 @@ namespace mongo {
if (_endCursor->isEOF()) {
// If the endCursor is EOF we're only done when our 'current count position' hits EOF.
_hitEnd = _btreeCursor->isEOF();
_hitEnd = _cursor->isEOF();
}
else {
// If not, we're only done when we hit the end cursor's (valid) position.
_hitEnd = _btreeCursor->pointsAt(*_endCursor.get());
_hitEnd = _cursor->pointsAt(*_endCursor.get());
}
}
@ -113,7 +108,7 @@ namespace mongo {
// Adds the amount of time taken by work() to executionTimeMillis.
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (NULL == _btreeCursor.get()) {
if (NULL == _cursor.get()) {
// First call to work(). Perform cursor init.
try {
initIndexCursor();
@ -121,7 +116,7 @@ namespace mongo {
}
catch (const WriteConflictException& wce) {
// Release our owned cursors and try again next time.
_btreeCursor.reset();
_cursor.reset();
_endCursor.reset();
*out = WorkingSet::INVALID_ID;
return PlanStage::NEED_YIELD;
@ -132,14 +127,14 @@ namespace mongo {
if (isEOF()) { return PlanStage::IS_EOF; }
RecordId loc = _btreeCursor->getValue();
RecordId loc = _cursor->getValue();
try {
_btreeCursor->next();
_cursor->next();
}
catch (const WriteConflictException& wce) {
// The cursor shouldn't have moved.
invariant(_btreeCursor->getValue() == loc);
invariant(_cursor->getValue() == loc);
*out = WorkingSet::INVALID_ID;
return PlanStage::NEED_YIELD;
}
@ -164,20 +159,20 @@ namespace mongo {
}
bool CountScan::isEOF() {
if (NULL == _btreeCursor.get()) {
if (NULL == _cursor.get()) {
// Have to call work() at least once.
return false;
}
return _hitEnd || _btreeCursor->isEOF();
return _hitEnd || _cursor->isEOF();
}
void CountScan::saveState() {
_txn = NULL;
++_commonStats.yields;
if (_hitEnd || (NULL == _btreeCursor.get())) { return; }
if (_hitEnd || (NULL == _cursor.get())) { return; }
_btreeCursor->savePosition();
_cursor->savePosition();
_endCursor->savePosition();
}
@ -185,21 +180,21 @@ namespace mongo {
invariant(_txn == NULL);
_txn = opCtx;
++_commonStats.unyields;
if (_hitEnd || (NULL == _btreeCursor.get())) { return; }
if (_hitEnd || (NULL == _cursor.get())) { return; }
if (!_btreeCursor->restorePosition( opCtx ).isOK()) {
if (!_cursor->restorePosition( opCtx ).isOK()) {
_hitEnd = true;
return;
}
if (_btreeCursor->isEOF()) {
if (_cursor->isEOF()) {
_hitEnd = true;
return;
}
// See if we're somehow already past our end key (maybe the thing we were pointing at got
// deleted...)
int cmp = _btreeCursor->getKey().woCompare(_params.endKey, _descriptor->keyPattern(), false);
int cmp = _cursor->getKey().woCompare(_params.endKey, _descriptor->keyPattern(), false);
if (cmp > 0 || (cmp == 0 && !_params.endKeyInclusive)) {
_hitEnd = true;
return;
@ -210,7 +205,7 @@ namespace mongo {
return;
}
// If we were EOF when we yielded we don't always want to have _btreeCursor run until
// If we were EOF when we yielded we don't always want to have _cursor run until
// EOF. New documents may have been inserted after our endKey and our end marker
// may be before them.
//

View File

@ -109,11 +109,11 @@ namespace mongo {
const IndexDescriptor* _descriptor;
const IndexAccessMethod* _iam;
// Our start cursor is _btreeCursor.
boost::scoped_ptr<BtreeIndexCursor> _btreeCursor;
// Our start cursor.
boost::scoped_ptr<IndexCursor> _cursor;
// Our end marker.
boost::scoped_ptr<BtreeIndexCursor> _endCursor;
boost::scoped_ptr<IndexCursor> _endCursor;
// Could our index have duplicates? If so, we use _returned to dedup.
unordered_set<RecordId, RecordId::Hasher> _returned;

View File

@ -48,7 +48,6 @@ namespace mongo {
_workingSet(workingSet),
_descriptor(params.descriptor),
_iam(params.descriptor->getIndexCatalog()->getIndex(params.descriptor)),
_btreeCursor(NULL),
_scanState(INITIALIZING),
_params(params),
_commonStats(kStageType) {
@ -76,8 +75,7 @@ namespace mongo {
Status s = _iam->newCursor(_txn, cursorOptions, &cursor);
verify(s.isOK());
verify(cursor);
// Is this assumption always valid? See SERVER-12397
_btreeCursor.reset(static_cast<BtreeIndexCursor*>(cursor));
_cursor.reset(cursor);
// Create a new bounds checker. The bounds checker gets our start key and assists in
// executing the scan and staying within the required bounds.
@ -92,7 +90,7 @@ namespace mongo {
key.resize(nFields);
inc.resize(nFields);
if (_checker->getStartKey(&key, &inc)) {
_btreeCursor->seek(key, inc);
_cursor->seek(key, inc);
_keyElts.resize(nFields);
_keyEltsInc.resize(nFields);
}
@ -116,7 +114,7 @@ namespace mongo {
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (INITIALIZING == _scanState) {
invariant(NULL == _btreeCursor.get());
invariant(NULL == _cursor.get());
initIndexCursor();
}
@ -131,8 +129,8 @@ namespace mongo {
if (GETTING_NEXT == _scanState) {
// Grab the next (key, value) from the index.
BSONObj ownedKeyObj = _btreeCursor->getKey().getOwned();
RecordId loc = _btreeCursor->getValue();
BSONObj ownedKeyObj = _cursor->getKey().getOwned();
RecordId loc = _cursor->getValue();
// The underlying IndexCursor points at the *next* thing we want to return. We do this
// so that if we're scanning an index looking for docs to delete we don't continually
@ -140,11 +138,11 @@ namespace mongo {
// We skip to the next value of the _params.fieldNo-th field in the index key pattern.
// This is the field we're distinct-ing over.
_btreeCursor->skip(_btreeCursor->getKey(),
_params.fieldNo + 1,
true,
_keyElts,
_keyEltsInc);
_cursor->skip(_cursor->getKey(),
_params.fieldNo + 1,
true,
_keyElts,
_keyEltsInc);
// On the next call to work, make sure that the cursor is still within the bounds.
_scanState = CHECKING_END;
@ -171,7 +169,7 @@ namespace mongo {
return false;
}
return HIT_END == _scanState || _btreeCursor->isEOF();
return HIT_END == _scanState || _cursor->isEOF();
}
void DistinctScan::saveState() {
@ -181,11 +179,11 @@ namespace mongo {
if (HIT_END == _scanState || INITIALIZING == _scanState) { return; }
// We save these so that we know if the cursor moves during the yield. If it moves, we have
// to make sure its ending position is valid w.r.t. our bounds.
if (!_btreeCursor->isEOF()) {
_savedKey = _btreeCursor->getKey().getOwned();
_savedLoc = _btreeCursor->getValue();
if (!_cursor->isEOF()) {
_savedKey = _cursor->getKey().getOwned();
_savedLoc = _cursor->getValue();
}
_btreeCursor->savePosition();
_cursor->savePosition();
}
void DistinctScan::restoreState(OperationContext* opCtx) {
@ -197,12 +195,12 @@ namespace mongo {
// We can have a valid position before we check isEOF(), restore the position, and then be
// EOF upon restore.
if (!_btreeCursor->restorePosition( opCtx ).isOK() || _btreeCursor->isEOF()) {
if (!_cursor->restorePosition( opCtx ).isOK() || _cursor->isEOF()) {
_scanState = HIT_END;
return;
}
if (!_savedKey.binaryEqual(_btreeCursor->getKey()) || _savedLoc != _btreeCursor->getValue()) {
if (!_savedKey.binaryEqual(_cursor->getKey()) || _savedLoc != _cursor->getValue()) {
// Our restored position might be past endKey, see if we've hit the end.
_scanState = CHECKING_END;
}
@ -220,7 +218,7 @@ namespace mongo {
// Use _checker to see how things are.
IndexBoundsChecker::KeyState keyState;
keyState = _checker->checkKey(_btreeCursor->getKey(),
keyState = _checker->checkKey(_cursor->getKey(),
&_keyEltsToUse,
&_movePastKeyElts,
&_keyElts,
@ -240,11 +238,11 @@ namespace mongo {
}
verify(IndexBoundsChecker::MUST_ADVANCE == keyState);
_btreeCursor->skip(_btreeCursor->getKey(), _keyEltsToUse, _movePastKeyElts,
_keyElts, _keyEltsInc);
_cursor->skip(_cursor->getKey(), _keyEltsToUse, _movePastKeyElts,
_keyElts, _keyEltsInc);
// Must check underlying cursor EOF after every cursor movement.
if (_btreeCursor->isEOF()) {
if (_cursor->isEOF()) {
_scanState = HIT_END;
}
}

View File

@ -137,7 +137,7 @@ namespace mongo {
const IndexAccessMethod* _iam; // owned by Collection -> IndexCatalog
// The cursor we use to navigate the tree.
boost::scoped_ptr<BtreeIndexCursor> _btreeCursor;
boost::scoped_ptr<IndexCursor> _cursor;
// Keeps track of what work we need to do next.
ScanState _scanState;

View File

@ -118,12 +118,8 @@ namespace mongo {
return PlanStage::IS_EOF;
}
// This may not be valid always. See SERVER-12397.
const BtreeBasedAccessMethod* accessMethod =
static_cast<const BtreeBasedAccessMethod*>(catalog->getIndex(idDesc));
// Look up the key by going directly to the Btree.
RecordId loc = accessMethod->findSingle(_txn, _key);
// Look up the key by going directly to the index.
RecordId loc = catalog->getIndex(idDesc)->findSingle(_txn, _key);
// Key not found.
if (loc.isNull()) {

View File

@ -72,7 +72,6 @@ namespace mongo {
_shouldDedup(true),
_params(params),
_commonStats(kStageType),
_btreeCursor(NULL),
_keyEltsToUse(0),
_movePastKeyElts(false),
_endKeyInclusive(false) {
@ -127,8 +126,6 @@ namespace mongo {
}
}
else {
_btreeCursor = static_cast<BtreeIndexCursor*>(_indexCursor.get());
// For single intervals, we can use an optimized scan which checks against the position
// of an end cursor. For all other index scans, we fall back on using
// IndexBoundsChecker to determine when we've finished the scan.
@ -141,14 +138,12 @@ namespace mongo {
&_endKeyInclusive)) {
// We want to point at the start key if it's inclusive, and we want to point past
// the start key if it's exclusive.
_btreeCursor->seek(startKey, !startKeyInclusive);
_indexCursor->seek(startKey, !startKeyInclusive);
IndexCursor* endCursor;
invariant(_iam->newCursor(_txn, cursorOptions, &endCursor).isOK());
invariant(endCursor);
// TODO: Get rid of this cast. See SERVER-12397.
_endCursor.reset(static_cast<BtreeIndexCursor*>(endCursor));
_endCursor.reset(endCursor);
// If the end key is inclusive, we want to point *past* it since that's the end.
_endCursor->seek(_endKey, _endKeyInclusive);
@ -164,7 +159,7 @@ namespace mongo {
key.resize(nFields);
inc.resize(nFields);
if (_checker->getStartKey(&key, &inc)) {
_btreeCursor->seek(key, inc);
_indexCursor->seek(key, inc);
_keyElts.resize(nFields);
_keyEltsInc.resize(nFields);
}
@ -199,7 +194,6 @@ namespace mongo {
_scanState = INITIALIZING;
_indexCursor.reset();
_endCursor.reset();
_btreeCursor = NULL;
*out = WorkingSet::INVALID_ID;
return PlanStage::NEED_YIELD;
}
@ -348,12 +342,12 @@ namespace mongo {
return;
}
// If we were EOF when we yielded, we don't always want to have '_btreeCursor' run until
// If we were EOF when we yielded, we don't always want to have '_indexCursor' run until
// EOF. New documents may have been inserted after our end key, and our end marker may
// be before them.
//
// As an example, say we're counting from 5 to 10 and the index only has keys for 6, 7,
// 8, and 9. '_btreeCursor' will point at key 6 at the start and '_endCursor' will be
// 8, and 9. '_indexCursor' will point at key 6 at the start and '_endCursor' will be
// EOF. If we insert a document with key 11 during a yield, we need to relocate
// '_endCursor' to point at the new key as the end key of our scan.
_endCursor->seek(_endKey, _endKeyInclusive);
@ -417,7 +411,7 @@ namespace mongo {
_scanState = GETTING_NEXT;
// "Normal" start -> end scanning.
verify(NULL == _btreeCursor);
verify(NULL == _endCursor);
verify(NULL == _checker.get());
// If there is an empty endKey we will scan until we run out of index to scan over.
@ -440,7 +434,7 @@ namespace mongo {
_scanState = GETTING_NEXT;
invariant(!_checker);
if (_endCursor->pointsAt(*_btreeCursor)) {
if (_endCursor->pointsAt(*_indexCursor)) {
_scanState = HIT_END;
}
else {
@ -448,7 +442,7 @@ namespace mongo {
}
}
else {
verify(NULL != _btreeCursor);
verify(NULL != _indexCursor);
verify(NULL != _checker.get());
IndexBoundsChecker::KeyState keyState;
@ -472,11 +466,11 @@ namespace mongo {
}
verify(IndexBoundsChecker::MUST_ADVANCE == keyState);
_btreeCursor->skip(_indexCursor->getKey(), _keyEltsToUse, _movePastKeyElts,
_indexCursor->skip(_indexCursor->getKey(), _keyEltsToUse, _movePastKeyElts,
_keyElts, _keyEltsInc);
// Must check underlying cursor EOF after every cursor movement.
if (_btreeCursor->isEOF()) {
if (_indexCursor->isEOF()) {
_scanState = HIT_END;
return;
}

View File

@ -71,12 +71,6 @@ namespace mongo {
* Stage scans over an index from startKey to endKey, returning results that pass the provided
* filter. Internally dedups on RecordId.
*
* TODO: we probably should split this into 2 stages: one btree-only "fast" ixscan and one that
* strictly talks through the index API. Need to figure out what we really want to ship down
* through that API predicate-wise though, currently the language is a BSONObj but that's
* clearly not enough (or we need different index scan exec nodes per index type?). See
* SERVER-12397 for tracking.
*
* Sub-stage preconditions: None. Is a leaf and consumes no stage data.
*/
class IndexScan : public PlanStage {
@ -168,18 +162,8 @@ namespace mongo {
IndexScanStats _specificStats;
//
// Btree-specific navigation state.
//
// Either NULL or points to the same object as '_indexCursor'. The index scan stage should
// not need to use both IndexCursor and BtreeIndexCursor. This is being tracked in
// SERVER-12397.
BtreeIndexCursor* _btreeCursor;
//
// If we have decided to use the BtreeIndexCursor methods for navigation, we make a decision
// to employ one of two different algorithms for determining when the index scan has reached
// the end:
// If we aren't doing a "simple" index scan, we make a decision to employ one of two
// different algorithms for determining when the index scan has reached the end:
//
//
@ -202,7 +186,7 @@ namespace mongo {
//
// The end cursor.
boost::scoped_ptr<BtreeIndexCursor> _endCursor;
boost::scoped_ptr<IndexCursor> _endCursor;
// The key that the end cursor should point to.
BSONObj _endKey;

View File

@ -41,7 +41,7 @@ namespace mongo {
TwoDAccessMethod::TwoDAccessMethod(IndexCatalogEntry* btreeState,
SortedDataInterface* btree)
: BtreeBasedAccessMethod(btreeState, btree) {
: IndexAccessMethod(btreeState, btree) {
const IndexDescriptor* descriptor = btreeState->descriptor();

View File

@ -40,13 +40,9 @@ namespace mongo {
class IndexDescriptor;
struct TwoDIndexingParams;
class TwoDAccessMethod : public BtreeBasedAccessMethod {
class TwoDAccessMethod : public IndexAccessMethod {
public:
using BtreeBasedAccessMethod::_descriptor;
TwoDAccessMethod(IndexCatalogEntry* btreeState,
SortedDataInterface* btree);
virtual ~TwoDAccessMethod() { }
TwoDAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree);
private:

View File

@ -40,7 +40,7 @@ namespace mongo {
// Standard Btree implementation below.
BtreeAccessMethod::BtreeAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree )
: BtreeBasedAccessMethod(btreeState, btree) {
: IndexAccessMethod(btreeState, btree) {
// The key generation wants these values.
vector<const char*> fieldNames;

View File

@ -45,15 +45,9 @@ namespace mongo {
* The IndexAccessMethod for a Btree index.
* Any index created with {field: 1} or {field: -1} uses this.
*/
class BtreeAccessMethod : public BtreeBasedAccessMethod {
class BtreeAccessMethod : public IndexAccessMethod {
public:
// Every Btree-based index needs these. We put them in the BtreeBasedAccessMethod
// superclass and subclasses (like this) can use them.
using BtreeBasedAccessMethod::_descriptor;
BtreeAccessMethod(IndexCatalogEntry* btreeState,
SortedDataInterface* btree );
virtual ~BtreeAccessMethod() { }
BtreeAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree );
private:
virtual void getKeys(const BSONObj& obj, BSONObjSet* keys) const;

View File

@ -32,7 +32,7 @@
namespace mongo {
FTSAccessMethod::FTSAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree )
: BtreeBasedAccessMethod(btreeState, btree), _ftsSpec(btreeState->descriptor()->infoObj()) { }
: IndexAccessMethod(btreeState, btree), _ftsSpec(btreeState->descriptor()->infoObj()) { }
void FTSAccessMethod::getKeys(const BSONObj& obj, BSONObjSet* keys) const {
ExpressionKeysPrivate::getFTSKeys(obj, _ftsSpec, keys);

View File

@ -36,10 +36,9 @@
namespace mongo {
class FTSAccessMethod : public BtreeBasedAccessMethod {
class FTSAccessMethod : public IndexAccessMethod {
public:
FTSAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree );
virtual ~FTSAccessMethod() { }
FTSAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree);
const fts::FTSSpec& getSpec() const { return _ftsSpec; }

View File

@ -34,7 +34,7 @@
namespace mongo {
HashAccessMethod::HashAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree)
: BtreeBasedAccessMethod(btreeState, btree) {
: IndexAccessMethod(btreeState, btree) {
const IndexDescriptor* descriptor = btreeState->descriptor();

View File

@ -41,12 +41,9 @@ namespace mongo {
/**
* This is the access method for "hashed" indices.
*/
class HashAccessMethod : public BtreeBasedAccessMethod {
class HashAccessMethod : public IndexAccessMethod {
public:
using BtreeBasedAccessMethod::_descriptor;
HashAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree);
virtual ~HashAccessMethod() { }
private:
virtual void getKeys(const BSONObj& obj, BSONObjSet* keys) const;

View File

@ -48,7 +48,7 @@ namespace mongo {
using boost::scoped_ptr;
HaystackAccessMethod::HaystackAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree)
: BtreeBasedAccessMethod(btreeState, btree) {
: IndexAccessMethod(btreeState, btree) {
const IndexDescriptor* descriptor = btreeState->descriptor();

View File

@ -54,12 +54,9 @@ namespace mongo {
* bucketSize specifies the dimension of the square bucket for the data in pos.
* ALL fields are mandatory.
*/
class HaystackAccessMethod : public BtreeBasedAccessMethod {
class HaystackAccessMethod : public IndexAccessMethod {
public:
using BtreeBasedAccessMethod::_descriptor;
HaystackAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree);
virtual ~HaystackAccessMethod() { }
protected:
friend class GeoHaystackSearchCommand;

View File

@ -166,7 +166,7 @@ namespace mongo {
Status IndexAccessMethod::newCursor(OperationContext* txn, const CursorOptions& opts,
IndexCursor** out) const {
*out = new BtreeIndexCursor(_newInterface->newCursor(txn, opts.direction));
*out = new IndexCursor(_newInterface->newCursor(txn, opts.direction));
return Status::OK();
}

View File

@ -251,9 +251,6 @@ namespace mongo {
const std::unique_ptr<SortedDataInterface> _newInterface;
};
// Temporary typedef to old name
using BtreeBasedAccessMethod = IndexAccessMethod;
/**
* Updates are two steps: verify that it's a valid update, and perform it.
* validateUpdate fills out the UpdateStatus and update actually applies it.

View File

@ -170,9 +170,6 @@ namespace mongo {
const std::unique_ptr<SortedDataInterface::Cursor> _cursor;
};
// Temporary typedef to old name
using BtreeIndexCursor = IndexCursor;
// All the options we might want to set on a cursor.
struct CursorOptions {
// Set the direction of the scan. Ignored if the cursor doesn't have directions (geo).

View File

@ -47,7 +47,7 @@ namespace mongo {
static const string kIndexVersionFieldName("2dsphereIndexVersion");
S2AccessMethod::S2AccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree)
: BtreeBasedAccessMethod(btreeState, btree) {
: IndexAccessMethod(btreeState, btree) {
const IndexDescriptor* descriptor = btreeState->descriptor();

View File

@ -39,12 +39,9 @@ namespace mongo {
class IndexCursor;
struct S2IndexingParams;
class S2AccessMethod : public BtreeBasedAccessMethod {
class S2AccessMethod : public IndexAccessMethod {
public:
using BtreeBasedAccessMethod::_descriptor;
S2AccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree);
virtual ~S2AccessMethod() { }
/**
* Takes an index spec object for this index and returns a copy tweaked to conform to the