summaryrefslogtreecommitdiff
path: root/src/mongo/db/index/hash_access_method.cpp
diff options
context:
space:
mode:
authorHari Khalsa <hkhalsa@10gen.com>2013-04-02 14:28:21 -0400
committerHari Khalsa <hkhalsa@10gen.com>2013-04-08 15:30:35 -0400
commit50c89129eaa8c77ce24bb1e2f2965996f3757143 (patch)
treec15d1af387590bec5c51d8886aabb18bfec6b751 /src/mongo/db/index/hash_access_method.cpp
parentac39ed282dc9610a115d09cbf88cd1bdf0fa3ba6 (diff)
downloadmongo-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.cpp87
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