diff options
author | Hari Khalsa <hkhalsa@10gen.com> | 2013-04-02 14:28:21 -0400 |
---|---|---|
committer | Hari Khalsa <hkhalsa@10gen.com> | 2013-04-08 15:30:35 -0400 |
commit | 50c89129eaa8c77ce24bb1e2f2965996f3757143 (patch) | |
tree | c15d1af387590bec5c51d8886aabb18bfec6b751 /src/mongo/db/index/hash_access_method.cpp | |
parent | ac39ed282dc9610a115d09cbf88cd1bdf0fa3ba6 (diff) | |
download | mongo-50c89129eaa8c77ce24bb1e2f2965996f3757143.tar.gz |
migrate hash index to new index api SERVER-8791 SERVER-9164
Diffstat (limited to 'src/mongo/db/index/hash_access_method.cpp')
-rw-r--r-- | src/mongo/db/index/hash_access_method.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/mongo/db/index/hash_access_method.cpp b/src/mongo/db/index/hash_access_method.cpp new file mode 100644 index 00000000000..d547f7fce1b --- /dev/null +++ b/src/mongo/db/index/hash_access_method.cpp @@ -0,0 +1,87 @@ +/** +* 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/>. +*/ + +#include "mongo/db/btree.h" +#include "mongo/db/btreecursor.h" +#include "mongo/db/hasher.h" +#include "mongo/db/index/hash_access_method.h" +#include "mongo/db/index/hash_index_cursor.h" +#include "mongo/db/queryutil.h" + +namespace mongo { + + long long int HashAccessMethod::makeSingleKey(const BSONElement& e, HashSeed seed, int v) { + massert(16767, "Only HashVersion 0 has been defined" , v == 0 ); + return BSONElementHasher::hash64(e, seed); + } + + HashAccessMethod::HashAccessMethod(IndexDescriptor* descriptor) + : BtreeBasedAccessMethod(descriptor) { + + const string HASHED_INDEX_TYPE_IDENTIFIER = "hashed"; + + //change these if single-field limitation lifted later + uassert(16763, "Currently only single field hashed index supported." , + 1 == descriptor->getNumFields()); + uassert(16764, "Currently hashed indexes cannot guarantee uniqueness. Use a regular index.", + !descriptor->unique()); + + //Default _seed to 0 if "seed" is not included in the index spec + //or if the value of "seed" is not a number + _seed = descriptor->getInfoElement("seed").numberInt(); + + //In case we have hashed indexes based on other hash functions in + //the future, we store a hashVersion number. If hashVersion changes, + // "makeSingleKey" will need to change accordingly. + //Defaults to 0 if "hashVersion" is not included in the index spec + //or if the value of "hashversion" is not a number + _hashVersion = descriptor->getInfoElement("hashVersion").numberInt(); + + //Get the hashfield name + BSONElement firstElt = descriptor->keyPattern().firstElement(); + massert(16765, "error: no hashed index field", + firstElt.str().compare(HASHED_INDEX_TYPE_IDENTIFIER) == 0); + _hashedField = firstElt.fieldName(); + + // Explicit null valued fields and missing fields are both represented in hashed indexes + // using the hash value of the null BSONElement. This is partly for historical reasons + // (hash of null was used in the initial release of hashed indexes and changing would alter + // the data format). Additionally, in certain places the hashed index code and the index + // bound calculation code assume null and missing are indexed identically. + BSONObj nullObj = BSON("" << BSONNULL); + _missingKey = BSON("" << makeSingleKey(nullObj.firstElement(), _seed, _hashVersion)); + } + + Status HashAccessMethod::newCursor(IndexCursor** out) { + *out = new HashIndexCursor(_hashedField, _seed, _hashVersion, _descriptor); + return Status::OK(); + } + + void HashAccessMethod::getKeys(const BSONObj& obj, BSONObjSet* keys) { + const char* cstr = _hashedField.c_str(); + BSONElement fieldVal = obj.getFieldDottedOrArray(cstr); + uassert(16766, "Error: hashed indexes do not currently support array values", + fieldVal.type() != Array ); + + if (!fieldVal.eoo()) { + BSONObj key = BSON( "" << makeSingleKey( fieldVal , _seed , _hashVersion ) ); + keys->insert( key ); + } else if (!_descriptor->isSparse()) { + keys->insert( _missingKey.copy() ); + } + } + +} // namespace mongo |