0
0
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:
Mathias Stearn 2015-03-17 12:59:05 -04:00
parent 061dab886c
commit af9ecc763e
18 changed files with 225 additions and 425 deletions

View File

@ -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",

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -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;

View File

@ -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;
};
/**

View File

@ -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();
}

View File

@ -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).

View File

@ -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"

View File

@ -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"