mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-28 07:59:02 +01:00
SERVER-17623 Merge BtreeBasedAccessMethod into IndexAccessMethod
This leaves typedefs for the old names of BtreeBasedAccessMethod and BtreeIndexCursro. A follow up commit will fix all direct users of these classes.
This commit is contained in:
parent
061dab886c
commit
af9ecc763e
@ -738,11 +738,11 @@ serverOnlyFiles = [ "db/background.cpp",
|
||||
"db/global_environment_d.cpp",
|
||||
"db/index/2d_access_method.cpp",
|
||||
"db/index/btree_access_method.cpp",
|
||||
"db/index/btree_based_access_method.cpp",
|
||||
"db/index/btree_index_cursor.cpp",
|
||||
"db/index/fts_access_method.cpp",
|
||||
"db/index/hash_access_method.cpp",
|
||||
"db/index/haystack_access_method.cpp",
|
||||
"db/index/index_access_method.cpp",
|
||||
"db/index/index_cursor.cpp",
|
||||
"db/index/s2_access_method.cpp",
|
||||
"db/index_builder.cpp",
|
||||
"db/index_legacy.cpp",
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include "mongo/db/exec/plan_stage.h"
|
||||
#include "mongo/db/index/btree_index_cursor.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/matcher/expression.h"
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include "mongo/db/exec/plan_stage.h"
|
||||
#include "mongo/db/index/btree_index_cursor.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/matcher/expression.h"
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include "mongo/db/exec/plan_stage.h"
|
||||
#include "mongo/db/index/btree_index_cursor.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/matcher/expression.h"
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/index/2d_common.h"
|
||||
#include "mongo/db/index/btree_based_access_method.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
|
||||
namespace mongo {
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/index/btree_index_cursor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/keypattern.h"
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/index/btree_based_access_method.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/index/btree_key_generator.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
|
@ -1,151 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2013-2014 MongoDB Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the GNU Affero General Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "mongo/base/disallow_copying.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/index/index_cursor.h"
|
||||
#include "mongo/db/index/index_descriptor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/record_id.h"
|
||||
#include "mongo/db/storage/sorted_data_interface.h"
|
||||
#include "mongo/db/sorter/sorter.h"
|
||||
|
||||
namespace mongo {
|
||||
|
||||
/**
|
||||
* Any access method that is Btree based subclasses from this.
|
||||
*
|
||||
* Subclassers must:
|
||||
* 1. Call the constructor for this class from their constructors, and
|
||||
* 2. override getKeys.
|
||||
*
|
||||
* XXX: Should really think of the sub-class as providing an expression mapping of the input,
|
||||
* don't need so many AMs, just really precomputing some data and mapping doc for getKeys(?).
|
||||
* See SERVER-12397 for tracking.
|
||||
*/
|
||||
class BtreeBasedAccessMethod : public IndexAccessMethod {
|
||||
MONGO_DISALLOW_COPYING( BtreeBasedAccessMethod );
|
||||
public:
|
||||
BtreeBasedAccessMethod( IndexCatalogEntry* btreeState,
|
||||
SortedDataInterface* btree );
|
||||
|
||||
virtual ~BtreeBasedAccessMethod() { }
|
||||
|
||||
virtual Status insert(OperationContext* txn,
|
||||
const BSONObj& obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
int64_t* numInserted);
|
||||
|
||||
virtual Status remove(OperationContext* txn,
|
||||
const BSONObj& obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
int64_t* numDeleted);
|
||||
|
||||
virtual Status validateUpdate(OperationContext* txn,
|
||||
const BSONObj& from,
|
||||
const BSONObj& to,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
UpdateTicket* ticket);
|
||||
|
||||
virtual Status update(OperationContext* txn,
|
||||
const UpdateTicket& ticket,
|
||||
int64_t* numUpdated);
|
||||
|
||||
virtual Status newCursor(OperationContext* txn,
|
||||
const CursorOptions& opts,
|
||||
IndexCursor** out) const;
|
||||
|
||||
virtual Status initializeAsEmpty(OperationContext* txn);
|
||||
|
||||
virtual std::unique_ptr<BulkBuilder> initiateBulk();
|
||||
|
||||
virtual Status commitBulk(OperationContext* txn,
|
||||
std::unique_ptr<BulkBuilder> bulk,
|
||||
bool mayInterrupt,
|
||||
bool dupsAllowed,
|
||||
std::set<RecordId>* dups);
|
||||
|
||||
virtual Status touch(OperationContext* txn, const BSONObj& obj);
|
||||
|
||||
virtual Status touch(OperationContext* txn) const;
|
||||
|
||||
virtual Status validate(OperationContext* txn, bool full, int64_t* numKeys,
|
||||
BSONObjBuilder* output);
|
||||
|
||||
virtual bool appendCustomStats(OperationContext* txn, BSONObjBuilder* output, double scale)
|
||||
const;
|
||||
virtual long long getSpaceUsedBytes( OperationContext* txn ) const;
|
||||
|
||||
// XXX: consider migrating callers to use IndexCursor instead
|
||||
virtual RecordId findSingle( OperationContext* txn, const BSONObj& key ) const;
|
||||
|
||||
protected:
|
||||
// See below for body.
|
||||
class BtreeBasedPrivateUpdateData;
|
||||
|
||||
// Determines whether it's OK to ignore ErrorCodes::KeyTooLong for this OperationContext
|
||||
bool ignoreKeyTooLong(OperationContext* txn);
|
||||
|
||||
IndexCatalogEntry* _btreeState; // owned by IndexCatalogEntry
|
||||
const IndexDescriptor* _descriptor;
|
||||
|
||||
private:
|
||||
void removeOneKey(OperationContext* txn,
|
||||
const BSONObj& key,
|
||||
const RecordId& loc,
|
||||
bool dupsAllowed);
|
||||
|
||||
const std::unique_ptr<SortedDataInterface> _newInterface;
|
||||
};
|
||||
|
||||
/**
|
||||
* What data do we need to perform an update?
|
||||
*/
|
||||
class BtreeBasedAccessMethod::BtreeBasedPrivateUpdateData
|
||||
: public UpdateTicket::PrivateUpdateData {
|
||||
public:
|
||||
virtual ~BtreeBasedPrivateUpdateData() { }
|
||||
|
||||
BSONObjSet oldKeys, newKeys;
|
||||
|
||||
// These point into the sets oldKeys and newKeys.
|
||||
std::vector<BSONObj*> removed, added;
|
||||
|
||||
RecordId loc;
|
||||
bool dupsAllowed;
|
||||
};
|
||||
|
||||
} // namespace mongo
|
@ -1,106 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2013 10gen Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the GNU Affero General Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/index/index_cursor.h"
|
||||
#include "mongo/db/index/index_descriptor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/record_id.h"
|
||||
#include "mongo/db/storage/sorted_data_interface.h"
|
||||
|
||||
namespace mongo {
|
||||
|
||||
class BtreeIndexCursor : public IndexCursor {
|
||||
public:
|
||||
bool isEOF() const;
|
||||
|
||||
virtual Status seek(const BSONObj& position);
|
||||
|
||||
// Btree-specific seeking functions.
|
||||
Status seek(const std::vector<const BSONElement*>& position,
|
||||
const std::vector<bool>& inclusive);
|
||||
|
||||
/**
|
||||
* Seek to the key 'position'. If 'afterKey' is true, seeks to the first
|
||||
* key that is oriented after 'position'.
|
||||
*
|
||||
* Btree-specific.
|
||||
*/
|
||||
void seek(const BSONObj& position, bool afterKey);
|
||||
|
||||
Status skip(const BSONObj& keyBegin,
|
||||
int keyBeginLen,
|
||||
bool afterKey,
|
||||
const std::vector<const BSONElement*>& keyEnd,
|
||||
const std::vector<bool>& keyEndInclusive);
|
||||
|
||||
virtual BSONObj getKey() const;
|
||||
virtual RecordId getValue() const;
|
||||
virtual void next();
|
||||
|
||||
/**
|
||||
* BtreeIndexCursor-only.
|
||||
* Returns true if 'this' points at the same exact key as 'other'.
|
||||
* Returns false otherwise.
|
||||
*/
|
||||
bool pointsAt(const BtreeIndexCursor& other);
|
||||
|
||||
virtual Status savePosition();
|
||||
|
||||
virtual Status restorePosition(OperationContext* txn);
|
||||
|
||||
virtual std::string toString();
|
||||
|
||||
private:
|
||||
// We keep the constructor private and only allow the AM to create us.
|
||||
friend class BtreeBasedAccessMethod;
|
||||
|
||||
/**
|
||||
* interface is an abstraction to hide the fact that we have two types of Btrees.
|
||||
*
|
||||
* Intentionally private, we're friends with the only class allowed to call it.
|
||||
*/
|
||||
BtreeIndexCursor(SortedDataInterface::Cursor* cursor);
|
||||
|
||||
bool isSavedPositionValid();
|
||||
|
||||
/**
|
||||
* Move to the next (or previous depending on the direction) key. Used by normal getNext
|
||||
* and also skipping unused keys.
|
||||
*/
|
||||
void advance();
|
||||
|
||||
boost::scoped_ptr<SortedDataInterface::Cursor> _cursor;
|
||||
};
|
||||
|
||||
} // namespace mongo
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/fts/fts_spec.h"
|
||||
#include "mongo/db/index/btree_based_access_method.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/index/index_descriptor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/hasher.h" // For HashSeed.
|
||||
#include "mongo/db/index/index_descriptor.h"
|
||||
#include "mongo/db/index/btree_based_access_method.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
|
||||
namespace mongo {
|
||||
|
@ -29,7 +29,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/index/btree_based_access_method.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/index/index_descriptor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/concurrency/write_conflict_exception.h"
|
||||
#include "mongo/db/curop.h"
|
||||
#include "mongo/db/index/btree_index_cursor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/keypattern.h"
|
||||
#include "mongo/db/server_parameters.h"
|
||||
@ -83,25 +82,25 @@ namespace mongo {
|
||||
const int _version;
|
||||
};
|
||||
|
||||
BtreeBasedAccessMethod::BtreeBasedAccessMethod(IndexCatalogEntry* btreeState,
|
||||
SortedDataInterface* btree)
|
||||
IndexAccessMethod::IndexAccessMethod(IndexCatalogEntry* btreeState,
|
||||
SortedDataInterface* btree)
|
||||
: _btreeState(btreeState),
|
||||
_descriptor(btreeState->descriptor()),
|
||||
_newInterface(btree) {
|
||||
verify(0 == _descriptor->version() || 1 == _descriptor->version());
|
||||
}
|
||||
|
||||
bool BtreeBasedAccessMethod::ignoreKeyTooLong(OperationContext *txn) {
|
||||
bool IndexAccessMethod::ignoreKeyTooLong(OperationContext *txn) {
|
||||
// Ignore this error if we're on a secondary or if the user requested it
|
||||
return !txn->isPrimaryFor(_btreeState->ns()) || !failIndexKeyTooLong;
|
||||
}
|
||||
|
||||
// Find the keys for obj, put them in the tree pointing to loc
|
||||
Status BtreeBasedAccessMethod::insert(OperationContext* txn,
|
||||
const BSONObj& obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
int64_t* numInserted) {
|
||||
Status IndexAccessMethod::insert(OperationContext* txn,
|
||||
const BSONObj& obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
int64_t* numInserted) {
|
||||
*numInserted = 0;
|
||||
|
||||
BSONObjSet keys;
|
||||
@ -149,10 +148,10 @@ namespace mongo {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BtreeBasedAccessMethod::removeOneKey(OperationContext* txn,
|
||||
const BSONObj& key,
|
||||
const RecordId& loc,
|
||||
bool dupsAllowed) {
|
||||
void IndexAccessMethod::removeOneKey(OperationContext* txn,
|
||||
const BSONObj& key,
|
||||
const RecordId& loc,
|
||||
bool dupsAllowed) {
|
||||
try {
|
||||
_newInterface->unindex(txn, key, loc, dupsAllowed);
|
||||
} catch (AssertionException& e) {
|
||||
@ -165,17 +164,18 @@ namespace mongo {
|
||||
}
|
||||
}
|
||||
|
||||
Status BtreeBasedAccessMethod::newCursor(OperationContext* txn, const CursorOptions& opts, IndexCursor** out) const {
|
||||
Status IndexAccessMethod::newCursor(OperationContext* txn, const CursorOptions& opts,
|
||||
IndexCursor** out) const {
|
||||
*out = new BtreeIndexCursor(_newInterface->newCursor(txn, opts.direction));
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
// Remove the provided doc from the index.
|
||||
Status BtreeBasedAccessMethod::remove(OperationContext* txn,
|
||||
const BSONObj &obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions &options,
|
||||
int64_t* numDeleted) {
|
||||
Status IndexAccessMethod::remove(OperationContext* txn,
|
||||
const BSONObj &obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions &options,
|
||||
int64_t* numDeleted) {
|
||||
|
||||
BSONObjSet keys;
|
||||
getKeys(obj, &keys);
|
||||
@ -209,11 +209,11 @@ namespace mongo {
|
||||
}
|
||||
}
|
||||
|
||||
Status BtreeBasedAccessMethod::initializeAsEmpty(OperationContext* txn) {
|
||||
Status IndexAccessMethod::initializeAsEmpty(OperationContext* txn) {
|
||||
return _newInterface->initAsEmpty(txn);
|
||||
}
|
||||
|
||||
Status BtreeBasedAccessMethod::touch(OperationContext* txn, const BSONObj& obj) {
|
||||
Status IndexAccessMethod::touch(OperationContext* txn, const BSONObj& obj) {
|
||||
BSONObjSet keys;
|
||||
getKeys(obj, &keys);
|
||||
|
||||
@ -226,11 +226,11 @@ namespace mongo {
|
||||
}
|
||||
|
||||
|
||||
Status BtreeBasedAccessMethod::touch( OperationContext* txn ) const {
|
||||
Status IndexAccessMethod::touch( OperationContext* txn ) const {
|
||||
return _newInterface->touch(txn);
|
||||
}
|
||||
|
||||
RecordId BtreeBasedAccessMethod::findSingle(OperationContext* txn, const BSONObj& key) const {
|
||||
RecordId IndexAccessMethod::findSingle(OperationContext* txn, const BSONObj& key) const {
|
||||
boost::scoped_ptr<SortedDataInterface::Cursor> cursor(_newInterface->newCursor(txn, 1));
|
||||
cursor->locate(key, RecordId::min());
|
||||
|
||||
@ -249,8 +249,8 @@ namespace mongo {
|
||||
return cursor->getRecordId();
|
||||
}
|
||||
|
||||
Status BtreeBasedAccessMethod::validate(OperationContext* txn, bool full, int64_t* numKeys,
|
||||
BSONObjBuilder* output) {
|
||||
Status IndexAccessMethod::validate(OperationContext* txn, bool full, int64_t* numKeys,
|
||||
BSONObjBuilder* output) {
|
||||
// XXX: long long vs int64_t
|
||||
long long keys = 0;
|
||||
_newInterface->fullValidate(txn, full, &keys, output);
|
||||
@ -258,81 +258,75 @@ namespace mongo {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
bool BtreeBasedAccessMethod::appendCustomStats(OperationContext* txn,
|
||||
BSONObjBuilder* output,
|
||||
double scale) const {
|
||||
bool IndexAccessMethod::appendCustomStats(OperationContext* txn,
|
||||
BSONObjBuilder* output,
|
||||
double scale) const {
|
||||
return _newInterface->appendCustomStats(txn, output, scale);
|
||||
}
|
||||
|
||||
long long BtreeBasedAccessMethod::getSpaceUsedBytes( OperationContext* txn ) const {
|
||||
long long IndexAccessMethod::getSpaceUsedBytes( OperationContext* txn ) const {
|
||||
return _newInterface->getSpaceUsedBytes( txn );
|
||||
}
|
||||
|
||||
Status BtreeBasedAccessMethod::validateUpdate(OperationContext* txn,
|
||||
const BSONObj &from,
|
||||
const BSONObj &to,
|
||||
const RecordId &record,
|
||||
const InsertDeleteOptions &options,
|
||||
UpdateTicket* status) {
|
||||
Status IndexAccessMethod::validateUpdate(OperationContext* txn,
|
||||
const BSONObj &from,
|
||||
const BSONObj &to,
|
||||
const RecordId &record,
|
||||
const InsertDeleteOptions &options,
|
||||
UpdateTicket* ticket) {
|
||||
|
||||
BtreeBasedPrivateUpdateData *data = new BtreeBasedPrivateUpdateData();
|
||||
status->_indexSpecificUpdateData.reset(data);
|
||||
getKeys(from, &ticket->oldKeys);
|
||||
getKeys(to, &ticket->newKeys);
|
||||
ticket->loc = record;
|
||||
ticket->dupsAllowed = options.dupsAllowed;
|
||||
|
||||
getKeys(from, &data->oldKeys);
|
||||
getKeys(to, &data->newKeys);
|
||||
data->loc = record;
|
||||
data->dupsAllowed = options.dupsAllowed;
|
||||
setDifference(ticket->oldKeys, ticket->newKeys, &ticket->removed);
|
||||
setDifference(ticket->newKeys, ticket->oldKeys, &ticket->added);
|
||||
|
||||
setDifference(data->oldKeys, data->newKeys, &data->removed);
|
||||
setDifference(data->newKeys, data->oldKeys, &data->added);
|
||||
|
||||
status->_isValid = true;
|
||||
ticket->_isValid = true;
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status BtreeBasedAccessMethod::update(OperationContext* txn,
|
||||
const UpdateTicket& ticket,
|
||||
int64_t* numUpdated) {
|
||||
Status IndexAccessMethod::update(OperationContext* txn,
|
||||
const UpdateTicket& ticket,
|
||||
int64_t* numUpdated) {
|
||||
if (!ticket._isValid) {
|
||||
return Status(ErrorCodes::InternalError, "Invalid UpdateTicket in update");
|
||||
}
|
||||
|
||||
BtreeBasedPrivateUpdateData* data =
|
||||
static_cast<BtreeBasedPrivateUpdateData*>(ticket._indexSpecificUpdateData.get());
|
||||
|
||||
if (data->oldKeys.size() + data->added.size() - data->removed.size() > 1) {
|
||||
if (ticket.oldKeys.size() + ticket.added.size() - ticket.removed.size() > 1) {
|
||||
_btreeState->setMultikey( txn );
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < data->removed.size(); ++i) {
|
||||
for (size_t i = 0; i < ticket.removed.size(); ++i) {
|
||||
_newInterface->unindex(txn,
|
||||
*data->removed[i],
|
||||
data->loc,
|
||||
data->dupsAllowed);
|
||||
*ticket.removed[i],
|
||||
ticket.loc,
|
||||
ticket.dupsAllowed);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < data->added.size(); ++i) {
|
||||
for (size_t i = 0; i < ticket.added.size(); ++i) {
|
||||
Status status = _newInterface->insert(txn,
|
||||
*data->added[i],
|
||||
data->loc,
|
||||
data->dupsAllowed);
|
||||
*ticket.added[i],
|
||||
ticket.loc,
|
||||
ticket.dupsAllowed);
|
||||
if ( !status.isOK() ) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
*numUpdated = data->added.size();
|
||||
*numUpdated = ticket.added.size();
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
std::unique_ptr<IndexAccessMethod::BulkBuilder> BtreeBasedAccessMethod::initiateBulk() {
|
||||
std::unique_ptr<IndexAccessMethod::BulkBuilder> IndexAccessMethod::initiateBulk() {
|
||||
|
||||
return std::unique_ptr<BulkBuilder>(new BulkBuilder(this, _descriptor));
|
||||
}
|
||||
|
||||
IndexAccessMethod::BulkBuilder::BulkBuilder(const BtreeBasedAccessMethod* index,
|
||||
IndexAccessMethod::BulkBuilder::BulkBuilder(const IndexAccessMethod* index,
|
||||
const IndexDescriptor* descriptor)
|
||||
: _sorter(Sorter::make(SortOptions().TempDir(storageGlobalParams.dbpath + "/_tmp")
|
||||
.ExtSortAllowed()
|
||||
@ -364,11 +358,12 @@ namespace mongo {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status BtreeBasedAccessMethod::commitBulk(OperationContext* txn,
|
||||
std::unique_ptr<BulkBuilder> bulk,
|
||||
bool mayInterrupt,
|
||||
bool dupsAllowed,
|
||||
set<RecordId>* dupsToDrop) {
|
||||
|
||||
Status IndexAccessMethod::commitBulk(OperationContext* txn,
|
||||
std::unique_ptr<BulkBuilder> bulk,
|
||||
bool mayInterrupt,
|
||||
bool dupsAllowed,
|
||||
set<RecordId>* dupsToDrop) {
|
||||
|
||||
Timer timer;
|
||||
|
@ -28,22 +28,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include "mongo/base/disallow_copying.h"
|
||||
#include "mongo/db/index/index_cursor.h"
|
||||
#include "mongo/db/index/index_descriptor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/operation_context.h"
|
||||
#include "mongo/db/record_id.h"
|
||||
#include "mongo/db/sorter/sorter.h"
|
||||
#include "mongo/db/storage/sorted_data_interface.h"
|
||||
|
||||
namespace mongo {
|
||||
|
||||
class BSONObjBuilder;
|
||||
class UpdateTicket;
|
||||
struct InsertDeleteOptions;
|
||||
class BtreeBasedAccessMethod;
|
||||
|
||||
/**
|
||||
* An IndexAccessMethod is the interface through which all the mutation, lookup, and
|
||||
@ -56,7 +56,10 @@ namespace mongo {
|
||||
*
|
||||
*/
|
||||
class IndexAccessMethod {
|
||||
MONGO_DISALLOW_COPYING(IndexAccessMethod);
|
||||
public:
|
||||
|
||||
IndexAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree);
|
||||
virtual ~IndexAccessMethod() { }
|
||||
|
||||
//
|
||||
@ -71,21 +74,21 @@ namespace mongo {
|
||||
*
|
||||
* The behavior of the insertion can be specified through 'options'.
|
||||
*/
|
||||
virtual Status insert(OperationContext* txn,
|
||||
const BSONObj& obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
int64_t* numInserted) = 0;
|
||||
Status insert(OperationContext* txn,
|
||||
const BSONObj& obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
int64_t* numInserted);
|
||||
|
||||
/**
|
||||
* Analogous to above, but remove the records instead of inserting them. If not NULL,
|
||||
* numDeleted will be set to the number of keys removed from the index for the document.
|
||||
*/
|
||||
virtual Status remove(OperationContext* txn,
|
||||
const BSONObj& obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
int64_t* numDeleted) = 0;
|
||||
Status remove(OperationContext* txn,
|
||||
const BSONObj& obj,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
int64_t* numDeleted);
|
||||
|
||||
/**
|
||||
* Checks whether the index entries for the document 'from', which is placed at location
|
||||
@ -97,12 +100,12 @@ namespace mongo {
|
||||
*
|
||||
* There is no obligation to perform the update after performing validation.
|
||||
*/
|
||||
virtual Status validateUpdate(OperationContext* txn,
|
||||
const BSONObj& from,
|
||||
const BSONObj& to,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
UpdateTicket* ticket) = 0;
|
||||
Status validateUpdate(OperationContext* txn,
|
||||
const BSONObj& from,
|
||||
const BSONObj& to,
|
||||
const RecordId& loc,
|
||||
const InsertDeleteOptions& options,
|
||||
UpdateTicket* ticket);
|
||||
|
||||
/**
|
||||
* Perform a validated update. The keys for the 'from' object will be removed, and the keys
|
||||
@ -112,15 +115,13 @@ namespace mongo {
|
||||
* called. If the index was changed, we may return an error, as our ticket may have been
|
||||
* invalidated.
|
||||
*/
|
||||
virtual Status update(OperationContext* txn,
|
||||
const UpdateTicket& ticket,
|
||||
int64_t* numUpdated) = 0;
|
||||
Status update(OperationContext* txn, const UpdateTicket& ticket, int64_t* numUpdated);
|
||||
|
||||
/**
|
||||
* Fills in '*out' with an IndexCursor. Return a status indicating success or reason of
|
||||
* failure. If the latter, '*out' contains NULL. See index_cursor.h for IndexCursor usage.
|
||||
*/
|
||||
virtual Status newCursor(OperationContext* txn, const CursorOptions& opts, IndexCursor** out) const = 0;
|
||||
Status newCursor(OperationContext* txn, const CursorOptions& opts, IndexCursor** out) const;
|
||||
|
||||
// ------ index level operations ------
|
||||
|
||||
@ -130,7 +131,7 @@ namespace mongo {
|
||||
* only called once for the lifetime of the index
|
||||
* if called multiple times, is an error
|
||||
*/
|
||||
virtual Status initializeAsEmpty(OperationContext* txn) = 0;
|
||||
Status initializeAsEmpty(OperationContext* txn);
|
||||
|
||||
/**
|
||||
* Try to page-in the pages that contain the keys generated from 'obj'.
|
||||
@ -138,12 +139,12 @@ namespace mongo {
|
||||
* appropriate pages are not swapped out.
|
||||
* See prefetch.cpp.
|
||||
*/
|
||||
virtual Status touch(OperationContext* txn, const BSONObj& obj) = 0;
|
||||
Status touch(OperationContext* txn, const BSONObj& obj);
|
||||
|
||||
/**
|
||||
* this pages in the entire index
|
||||
*/
|
||||
virtual Status touch(OperationContext* txn) const = 0;
|
||||
Status touch(OperationContext* txn) const;
|
||||
|
||||
/**
|
||||
* Walk the entire index, checking the internal structure for consistency.
|
||||
@ -157,8 +158,7 @@ namespace mongo {
|
||||
* Currently wasserts that the index is invalid. This could/should be changed in
|
||||
* the future to return a Status.
|
||||
*/
|
||||
virtual Status validate(OperationContext* txn, bool full, int64_t* numKeys,
|
||||
BSONObjBuilder* output) = 0;
|
||||
Status validate(OperationContext* txn, bool full, int64_t* numKeys, BSONObjBuilder* output);
|
||||
|
||||
/**
|
||||
* Add custom statistics about this index to BSON object builder, for display.
|
||||
@ -167,14 +167,16 @@ namespace mongo {
|
||||
*
|
||||
* Returns true if stats were appended.
|
||||
*/
|
||||
virtual bool appendCustomStats(OperationContext* txn, BSONObjBuilder* result, double scale)
|
||||
const = 0;
|
||||
bool appendCustomStats(OperationContext* txn, BSONObjBuilder* result, double scale) const;
|
||||
|
||||
/**
|
||||
* @return The number of bytes consumed by this index.
|
||||
* Exactly what is counted is not defined based on padding, re-use, etc...
|
||||
*/
|
||||
virtual long long getSpaceUsedBytes( OperationContext* txn ) const = 0;
|
||||
long long getSpaceUsedBytes( OperationContext* txn ) const;
|
||||
|
||||
// XXX: consider migrating callers to use IndexCursor instead
|
||||
RecordId findSingle( OperationContext* txn, const BSONObj& key ) const;
|
||||
|
||||
//
|
||||
// Bulk operations support
|
||||
@ -192,14 +194,14 @@ namespace mongo {
|
||||
int64_t* numInserted);
|
||||
|
||||
private:
|
||||
friend class BtreeBasedAccessMethod;
|
||||
friend class IndexAccessMethod;
|
||||
|
||||
using Sorter = mongo::Sorter<BSONObj, RecordId>;
|
||||
|
||||
BulkBuilder(const BtreeBasedAccessMethod* index, const IndexDescriptor* descriptor);
|
||||
BulkBuilder(const IndexAccessMethod* index, const IndexDescriptor* descriptor);
|
||||
|
||||
std::unique_ptr<Sorter> _sorter;
|
||||
const BtreeBasedAccessMethod* _real;
|
||||
const IndexAccessMethod* _real;
|
||||
int64_t _keysInserted = 0;
|
||||
bool _isMultiKey = false;
|
||||
};
|
||||
@ -211,7 +213,7 @@ namespace mongo {
|
||||
*
|
||||
* It is only legal to initiate bulk when the index is new and empty.
|
||||
*/
|
||||
virtual std::unique_ptr<BulkBuilder> initiateBulk() = 0;
|
||||
std::unique_ptr<BulkBuilder> initiateBulk();
|
||||
|
||||
/**
|
||||
* Call this when you are ready to finish your bulk work.
|
||||
@ -222,41 +224,56 @@ namespace mongo {
|
||||
* @param dups - if NULL, error out on dups if not allowed
|
||||
* if not NULL, put the bad RecordIds there
|
||||
*/
|
||||
virtual Status commitBulk( OperationContext* txn,
|
||||
std::unique_ptr<BulkBuilder> bulk,
|
||||
bool mayInterrupt,
|
||||
bool dupsAllowed,
|
||||
std::set<RecordId>* dups ) = 0;
|
||||
Status commitBulk(OperationContext* txn,
|
||||
std::unique_ptr<BulkBuilder> bulk,
|
||||
bool mayInterrupt,
|
||||
bool dupsAllowed,
|
||||
std::set<RecordId>* dups);
|
||||
|
||||
/**
|
||||
* Fills 'keys' with the keys that should be generated for 'obj' on this index.
|
||||
*/
|
||||
virtual void getKeys(const BSONObj &obj, BSONObjSet *keys) const = 0;
|
||||
|
||||
protected:
|
||||
// Determines whether it's OK to ignore ErrorCodes::KeyTooLong for this OperationContext
|
||||
bool ignoreKeyTooLong(OperationContext* txn);
|
||||
|
||||
IndexCatalogEntry* _btreeState; // owned by IndexCatalogEntry
|
||||
const IndexDescriptor* _descriptor;
|
||||
|
||||
private:
|
||||
void removeOneKey(OperationContext* txn,
|
||||
const BSONObj& key,
|
||||
const RecordId& loc,
|
||||
bool dupsAllowed);
|
||||
|
||||
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.
|
||||
*/
|
||||
class UpdateTicket {
|
||||
public:
|
||||
UpdateTicket() : _isValid(false) { }
|
||||
|
||||
protected:
|
||||
// These friends are the classes that actually fill out an UpdateStatus.
|
||||
friend class BtreeBasedAccessMethod;
|
||||
|
||||
class PrivateUpdateData;
|
||||
// No public interface
|
||||
private:
|
||||
friend class IndexAccessMethod;
|
||||
|
||||
bool _isValid;
|
||||
|
||||
// This is meant to be filled out only by the friends above.
|
||||
boost::scoped_ptr<PrivateUpdateData> _indexSpecificUpdateData;
|
||||
};
|
||||
BSONObjSet oldKeys;
|
||||
BSONObjSet newKeys;
|
||||
|
||||
class UpdateTicket::PrivateUpdateData {
|
||||
public:
|
||||
virtual ~PrivateUpdateData() { }
|
||||
// These point into the sets oldKeys and newKeys.
|
||||
std::vector<BSONObj*> removed;
|
||||
std::vector<BSONObj*> added;
|
||||
|
||||
RecordId loc;
|
||||
bool dupsAllowed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -26,7 +26,7 @@
|
||||
* it in the license file.
|
||||
*/
|
||||
|
||||
#include "mongo/db/index/btree_index_cursor.h"
|
||||
#include "mongo/db/index/index_cursor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -42,27 +42,27 @@ namespace mongo {
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
BtreeIndexCursor::BtreeIndexCursor(SortedDataInterface::Cursor* cursor) : _cursor(cursor) { }
|
||||
IndexCursor::IndexCursor(SortedDataInterface::Cursor* cursor) : _cursor(cursor) { }
|
||||
|
||||
bool BtreeIndexCursor::isEOF() const { return _cursor->isEOF(); }
|
||||
bool IndexCursor::isEOF() const { return _cursor->isEOF(); }
|
||||
|
||||
Status BtreeIndexCursor::seek(const BSONObj& position) {
|
||||
Status IndexCursor::seek(const BSONObj& position) {
|
||||
_cursor->locate(position,
|
||||
1 == _cursor->getDirection() ? RecordId::min() : RecordId::max());
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
void BtreeIndexCursor::seek(const BSONObj& position, bool afterKey) {
|
||||
void IndexCursor::seek(const BSONObj& position, bool afterKey) {
|
||||
const bool forward = (1 == _cursor->getDirection());
|
||||
_cursor->locate(position, (afterKey == forward) ? RecordId::max() : RecordId::min());
|
||||
}
|
||||
|
||||
bool BtreeIndexCursor::pointsAt(const BtreeIndexCursor& other) {
|
||||
bool IndexCursor::pointsAt(const IndexCursor& other) {
|
||||
return _cursor->pointsToSamePlaceAs(*other._cursor);
|
||||
}
|
||||
|
||||
Status BtreeIndexCursor::seek(const vector<const BSONElement*>& position,
|
||||
const vector<bool>& inclusive) {
|
||||
Status IndexCursor::seek(const vector<const BSONElement*>& position,
|
||||
const vector<bool>& inclusive) {
|
||||
|
||||
BSONObj emptyObj;
|
||||
|
||||
@ -74,11 +74,11 @@ namespace mongo {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status BtreeIndexCursor::skip(const BSONObj &keyBegin,
|
||||
int keyBeginLen,
|
||||
bool afterKey,
|
||||
const vector<const BSONElement*>& keyEnd,
|
||||
const vector<bool>& keyEndInclusive) {
|
||||
Status IndexCursor::skip(const BSONObj &keyBegin,
|
||||
int keyBeginLen,
|
||||
bool afterKey,
|
||||
const vector<const BSONElement*>& keyEnd,
|
||||
const vector<bool>& keyEndInclusive) {
|
||||
|
||||
_cursor->advanceTo(keyBegin,
|
||||
keyBeginLen,
|
||||
@ -88,35 +88,35 @@ namespace mongo {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
BSONObj BtreeIndexCursor::getKey() const {
|
||||
BSONObj IndexCursor::getKey() const {
|
||||
return _cursor->getKey();
|
||||
}
|
||||
|
||||
RecordId BtreeIndexCursor::getValue() const {
|
||||
RecordId IndexCursor::getValue() const {
|
||||
return _cursor->getRecordId();
|
||||
}
|
||||
|
||||
void BtreeIndexCursor::next() {
|
||||
void IndexCursor::next() {
|
||||
advance();
|
||||
}
|
||||
|
||||
Status BtreeIndexCursor::savePosition() {
|
||||
Status IndexCursor::savePosition() {
|
||||
_cursor->savePosition();
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status BtreeIndexCursor::restorePosition(OperationContext* txn) {
|
||||
Status IndexCursor::restorePosition(OperationContext* txn) {
|
||||
_cursor->restorePosition(txn);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
string BtreeIndexCursor::toString() {
|
||||
string IndexCursor::toString() {
|
||||
// TODO: is this ever called?
|
||||
return "I AM A BTREE INDEX CURSOR!\n";
|
||||
}
|
||||
|
||||
// Move to the next/prev. key. Used by normal getNext and also skipping unused keys.
|
||||
void BtreeIndexCursor::advance() {
|
||||
void IndexCursor::advance() {
|
||||
_cursor->advance();
|
||||
}
|
||||
|
@ -28,16 +28,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/index/index_cursor.h"
|
||||
#include "mongo/db/index/index_descriptor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/record_id.h"
|
||||
#include "mongo/db/storage/sorted_data_interface.h"
|
||||
|
||||
namespace mongo {
|
||||
|
||||
struct CursorOptions;
|
||||
|
||||
/**
|
||||
* TODO remove this class in favor of direct usage of SortedDataInterface::Cursor.
|
||||
*
|
||||
* An IndexCursor is the interface through which one traverses the entries of a given
|
||||
* index. The internal structure of an index is kept isolated.
|
||||
*
|
||||
@ -53,7 +60,6 @@ namespace mongo {
|
||||
*/
|
||||
class IndexCursor {
|
||||
public:
|
||||
virtual ~IndexCursor() { }
|
||||
|
||||
/**
|
||||
* A cursor doesn't point anywhere by default. You must seek to the start position.
|
||||
@ -65,27 +71,50 @@ namespace mongo {
|
||||
* 2. Success: seeked to 'closest' key oriented according to the cursor's direction.
|
||||
* 3. Error: can't seek to the position.
|
||||
*/
|
||||
virtual Status seek(const BSONObj& position) = 0;
|
||||
Status seek(const BSONObj& position);
|
||||
|
||||
Status seek(const std::vector<const BSONElement*>& position,
|
||||
const std::vector<bool>& inclusive);
|
||||
|
||||
/**
|
||||
* Seek to the key 'position'. If 'afterKey' is true, seeks to the first
|
||||
* key that is oriented after 'position'.
|
||||
*
|
||||
* Btree-specific.
|
||||
*/
|
||||
void seek(const BSONObj& position, bool afterKey);
|
||||
|
||||
Status skip(const BSONObj& keyBegin,
|
||||
int keyBeginLen,
|
||||
bool afterKey,
|
||||
const std::vector<const BSONElement*>& keyEnd,
|
||||
const std::vector<bool>& keyEndInclusive);
|
||||
|
||||
/**
|
||||
* Returns true if 'this' points at the same exact key as 'other'.
|
||||
* Returns false otherwise.
|
||||
*/
|
||||
bool pointsAt(const IndexCursor& other);
|
||||
|
||||
//
|
||||
// Iteration support
|
||||
//
|
||||
|
||||
// Are we out of documents?
|
||||
virtual bool isEOF() const = 0;
|
||||
bool isEOF() const;
|
||||
|
||||
// Move to the next key/value pair. Assumes !isEOF().
|
||||
virtual void next() = 0;
|
||||
void next();
|
||||
|
||||
//
|
||||
// Accessors
|
||||
//
|
||||
|
||||
// Current key we point at. Assumes !isEOF().
|
||||
virtual BSONObj getKey() const = 0;
|
||||
BSONObj getKey() const;
|
||||
|
||||
// Current value we point at. Assumes !isEOF().
|
||||
virtual RecordId getValue() const = 0;
|
||||
RecordId getValue() const;
|
||||
|
||||
//
|
||||
// Yielding support
|
||||
@ -106,24 +135,44 @@ namespace mongo {
|
||||
/**
|
||||
* Save our current position in the index.
|
||||
*/
|
||||
virtual Status savePosition() = 0;
|
||||
Status savePosition();
|
||||
|
||||
/**
|
||||
* Restore the saved position. Errors if there is no saved position.
|
||||
* The cursor may be EOF after a restore.
|
||||
*/
|
||||
virtual Status restorePosition(OperationContext* txn) = 0;
|
||||
|
||||
// Return a std::string describing the cursor.
|
||||
virtual std::string toString() = 0;
|
||||
Status restorePosition(OperationContext* txn);
|
||||
|
||||
/**
|
||||
* Add debugging info to the provided builder.
|
||||
* TODO(hk): We can do this better, perhaps with a more structured format.
|
||||
* Return a std::string describing the cursor.
|
||||
*/
|
||||
virtual void explainDetails(BSONObjBuilder* b) { }
|
||||
std::string toString();
|
||||
|
||||
private:
|
||||
// We keep the constructor private and only allow the AM to create us.
|
||||
friend class IndexAccessMethod;
|
||||
|
||||
/**
|
||||
* interface is an abstraction to hide the fact that we have two types of Btrees.
|
||||
*
|
||||
* Intentionally private, we're friends with the only class allowed to call it.
|
||||
*/
|
||||
IndexCursor(SortedDataInterface::Cursor* cursor);
|
||||
|
||||
bool isSavedPositionValid();
|
||||
|
||||
/**
|
||||
* Move to the next (or previous depending on the direction) key. Used by normal getNext
|
||||
* and also skipping unused keys.
|
||||
*/
|
||||
void advance();
|
||||
|
||||
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).
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include "mongo/base/status.h"
|
||||
#include "mongo/db/index/s2_common.h"
|
||||
#include "mongo/db/index/btree_based_access_method.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/index/index_descriptor.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "mongo/db/catalog/index_catalog_entry.h"
|
||||
#include "mongo/db/index/2d_access_method.h"
|
||||
#include "mongo/db/index/btree_access_method.h"
|
||||
#include "mongo/db/index/btree_based_access_method.h"
|
||||
#include "mongo/db/index/index_access_method.h"
|
||||
#include "mongo/db/index/fts_access_method.h"
|
||||
#include "mongo/db/index/hash_access_method.h"
|
||||
#include "mongo/db/index/haystack_access_method.h"
|
||||
|
Loading…
Reference in New Issue
Block a user