/** * 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 . * * 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. */ #include "mongo/db/btree.h" #include "mongo/db/index/btree_interface.h" #include "mongo/db/pdfile.h" namespace mongo { template class BtreeInterfaceImpl : public BtreeInterface { public: // typedef typename BucketBasics::VersionNode VersionNode; virtual ~BtreeInterfaceImpl() { } virtual int bt_insert(const DiskLoc thisLoc, const DiskLoc recordLoc, const BSONObj& key, const Ordering &order, bool dupsAllowed, IndexDetails& idx, bool toplevel) const { // FYI: toplevel has a default value of true in btree.h return thisLoc.btree()->bt_insert( thisLoc, recordLoc, key, order, dupsAllowed, idx, toplevel); } virtual bool unindex(const DiskLoc thisLoc, IndexDetails& id, const BSONObj& key, const DiskLoc recordLoc) const { return thisLoc.btree()->unindex(thisLoc, id, key, recordLoc); } virtual DiskLoc locate(const IndexDetails& idx, const DiskLoc& thisLoc, const BSONObj& key, const Ordering& order, int& pos, bool& found, const DiskLoc& recordLoc, int direction) const { // FYI: direction has a default of 1 return thisLoc.btree()->locate( idx, thisLoc, key, order, pos, found, recordLoc, direction); } virtual bool wouldCreateDup(const IndexDetails& idx, const DiskLoc& thisLoc, const BSONObj& key, const Ordering& order, const DiskLoc& self) const { typename Version::KeyOwned ownedVersion(key); return thisLoc.btree()->wouldCreateDup( idx, thisLoc, ownedVersion, order, self); } virtual void customLocate(DiskLoc& locInOut, int& keyOfs, const BSONObj& keyBegin, int keyBeginLen, bool afterVersion, const vector& keyEnd, const vector& keyEndInclusive, const Ordering& order, int direction, pair& bestParent) { locInOut.btree()->customLocate( locInOut, keyOfs, keyBegin, keyBeginLen, afterVersion, keyEnd, keyEndInclusive, order, direction, bestParent); } virtual void advanceTo(DiskLoc &thisLoc, int &keyOfs, const BSONObj &keyBegin, int keyBeginLen, bool afterVersion, const vector& keyEnd, const vector& keyEndInclusive, const Ordering& order, int direction) const { thisLoc.btree()->advanceTo( thisLoc, keyOfs, keyBegin, keyBeginLen, afterVersion, keyEnd, keyEndInclusive, order, direction); } virtual bool keyIsUsed(DiskLoc bucket, int keyOffset) const { return bucket.btree()->k(keyOffset).isUsed(); } virtual BSONObj keyAt(DiskLoc bucket, int keyOffset) const { verify(!bucket.isNull()); const BtreeBucket *b = bucket.btree(); int n = b->getN(); if (n == b->INVALID_N_SENTINEL) { throw UserException(deletedBucketCode, "keyAt bucket deleted"); } dassert( n >= 0 && n < 10000 ); return keyOffset >= n ? BSONObj() : b->keyNode(keyOffset).key.toBson(); } virtual DiskLoc recordAt(DiskLoc bucket, int keyOffset) const { const BtreeBucket *b = bucket.btree(); return b->keyNode(keyOffset).recordLoc; } virtual void keyAndRecordAt(DiskLoc bucket, int keyOffset, BSONObj* keyOut, DiskLoc* recordOut) const { verify(!bucket.isNull()); const BtreeBucket *b = bucket.btree(); int n = b->getN(); // If n is 0xffff the bucket was deleted. if (keyOffset < 0 || keyOffset >= n || n == 0xffff || !b->isUsed(keyOffset)) { return; } if (keyOffset >= n) { *keyOut = BSONObj(); *recordOut = DiskLoc(); } else { *keyOut = b->keyNode(keyOffset).key.toBson(); *recordOut = b->keyNode(keyOffset).recordLoc; } } virtual string dupKeyError(DiskLoc bucket, const IndexDetails &idx, const BSONObj& keyObj) const { typename Version::KeyOwned key(keyObj); return bucket.btree()->dupKeyError(idx, key); } virtual DiskLoc advance(const DiskLoc& thisLoc, int& keyOfs, int direction, const char* caller) const { return thisLoc.btree()->advance(thisLoc, keyOfs, direction, caller); } virtual long long fullValidate(const DiskLoc& thisLoc, const BSONObj& keyPattern) { return thisLoc.btree()->fullValidate(thisLoc, keyPattern); } }; BtreeInterfaceImpl interface_v0; BtreeInterfaceImpl interface_v1; BtreeInterface* BtreeInterface::interfaces[] = { &interface_v0, &interface_v1 }; } // namespace mongo