summaryrefslogtreecommitdiff
path: root/src/mongo/db/index/haystack_access_method.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/index/haystack_access_method.cpp')
-rw-r--r--src/mongo/db/index/haystack_access_method.cpp151
1 files changed, 77 insertions, 74 deletions
diff --git a/src/mongo/db/index/haystack_access_method.cpp b/src/mongo/db/index/haystack_access_method.cpp
index 263568af37a..66f1b09e813 100644
--- a/src/mongo/db/index/haystack_access_method.cpp
+++ b/src/mongo/db/index/haystack_access_method.cpp
@@ -44,94 +44,97 @@
namespace mongo {
- using std::unique_ptr;
-
- HaystackAccessMethod::HaystackAccessMethod(IndexCatalogEntry* btreeState, SortedDataInterface* btree)
- : IndexAccessMethod(btreeState, btree) {
+using std::unique_ptr;
+
+HaystackAccessMethod::HaystackAccessMethod(IndexCatalogEntry* btreeState,
+ SortedDataInterface* btree)
+ : IndexAccessMethod(btreeState, btree) {
+ const IndexDescriptor* descriptor = btreeState->descriptor();
+
+ ExpressionParams::parseHaystackParams(
+ descriptor->infoObj(), &_geoField, &_otherFields, &_bucketSize);
+
+ uassert(16773, "no geo field specified", _geoField.size());
+ uassert(16774, "no non-geo fields specified", _otherFields.size());
+}
+
+void HaystackAccessMethod::getKeys(const BSONObj& obj, BSONObjSet* keys) const {
+ ExpressionKeysPrivate::getHaystackKeys(obj, _geoField, _otherFields, _bucketSize, keys);
+}
+
+void HaystackAccessMethod::searchCommand(OperationContext* txn,
+ Collection* collection,
+ const BSONObj& nearObj,
+ double maxDistance,
+ const BSONObj& search,
+ BSONObjBuilder* result,
+ unsigned limit) {
+ Timer t;
+
+ LOG(1) << "SEARCH near:" << nearObj << " maxDistance:" << maxDistance << " search: " << search
+ << endl;
+ int x, y;
+ {
+ BSONObjIterator i(nearObj);
+ x = ExpressionKeysPrivate::hashHaystackElement(i.next(), _bucketSize);
+ y = ExpressionKeysPrivate::hashHaystackElement(i.next(), _bucketSize);
+ }
+ int scale = static_cast<int>(ceil(maxDistance / _bucketSize));
- const IndexDescriptor* descriptor = btreeState->descriptor();
+ GeoHaystackSearchHopper hopper(txn, nearObj, maxDistance, limit, _geoField, collection);
- ExpressionParams::parseHaystackParams(descriptor->infoObj(),
- &_geoField,
- &_otherFields,
- &_bucketSize);
+ long long btreeMatches = 0;
- uassert(16773, "no geo field specified", _geoField.size());
- uassert(16774, "no non-geo fields specified", _otherFields.size());
- }
-
- void HaystackAccessMethod::getKeys(const BSONObj& obj, BSONObjSet* keys) const {
- ExpressionKeysPrivate::getHaystackKeys(obj, _geoField, _otherFields, _bucketSize, keys);
- }
+ for (int a = -scale; a <= scale && !hopper.limitReached(); ++a) {
+ for (int b = -scale; b <= scale && !hopper.limitReached(); ++b) {
+ BSONObjBuilder bb;
+ bb.append("", ExpressionKeysPrivate::makeHaystackString(x + a, y + b));
- void HaystackAccessMethod::searchCommand(OperationContext* txn, Collection* collection,
- const BSONObj& nearObj, double maxDistance,
- const BSONObj& search, BSONObjBuilder* result,
- unsigned limit) {
- Timer t;
-
- LOG(1) << "SEARCH near:" << nearObj << " maxDistance:" << maxDistance
- << " search: " << search << endl;
- int x, y;
- {
- BSONObjIterator i(nearObj);
- x = ExpressionKeysPrivate::hashHaystackElement(i.next(), _bucketSize);
- y = ExpressionKeysPrivate::hashHaystackElement(i.next(), _bucketSize);
- }
- int scale = static_cast<int>(ceil(maxDistance / _bucketSize));
+ for (unsigned i = 0; i < _otherFields.size(); i++) {
+ // See if the non-geo field we're indexing on is in the provided search term.
+ BSONElement e = search.getFieldDotted(_otherFields[i]);
+ if (e.eoo())
+ bb.appendNull("");
+ else
+ bb.appendAs(e, "");
+ }
- GeoHaystackSearchHopper hopper(txn, nearObj, maxDistance, limit, _geoField, collection);
+ BSONObj key = bb.obj();
- long long btreeMatches = 0;
+ unordered_set<RecordId, RecordId::Hasher> thisPass;
- for (int a = -scale; a <= scale && !hopper.limitReached(); ++a) {
- for (int b = -scale; b <= scale && !hopper.limitReached(); ++b) {
- BSONObjBuilder bb;
- bb.append("", ExpressionKeysPrivate::makeHaystackString(x + a, y + b));
- for (unsigned i = 0; i < _otherFields.size(); i++) {
- // See if the non-geo field we're indexing on is in the provided search term.
- BSONElement e = search.getFieldDotted(_otherFields[i]);
- if (e.eoo())
- bb.appendNull("");
- else
- bb.appendAs(e, "");
+ unique_ptr<PlanExecutor> exec(
+ InternalPlanner::indexScan(txn, collection, _descriptor, key, key, true));
+ PlanExecutor::ExecState state;
+ RecordId loc;
+ while (PlanExecutor::ADVANCED == (state = exec->getNext(NULL, &loc))) {
+ if (hopper.limitReached()) {
+ break;
}
-
- BSONObj key = bb.obj();
-
- unordered_set<RecordId, RecordId::Hasher> thisPass;
-
-
- unique_ptr<PlanExecutor> exec(InternalPlanner::indexScan(txn, collection,
- _descriptor, key, key, true));
- PlanExecutor::ExecState state;
- RecordId loc;
- while (PlanExecutor::ADVANCED == (state = exec->getNext(NULL, &loc))) {
- if (hopper.limitReached()) { break; }
- pair<unordered_set<RecordId, RecordId::Hasher>::iterator, bool> p
- = thisPass.insert(loc);
- // If a new element was inserted (haven't seen the RecordId before), p.second
- // is true.
- if (p.second) {
- hopper.consider(loc);
- btreeMatches++;
- }
+ pair<unordered_set<RecordId, RecordId::Hasher>::iterator, bool> p =
+ thisPass.insert(loc);
+ // If a new element was inserted (haven't seen the RecordId before), p.second
+ // is true.
+ if (p.second) {
+ hopper.consider(loc);
+ btreeMatches++;
}
}
}
+ }
- BSONArrayBuilder arr(result->subarrayStart("results"));
- int num = hopper.appendResultsTo(&arr);
- arr.done();
+ BSONArrayBuilder arr(result->subarrayStart("results"));
+ int num = hopper.appendResultsTo(&arr);
+ arr.done();
- {
- BSONObjBuilder b(result->subobjStart("stats"));
- b.append("time", t.millis());
- b.appendNumber("btreeMatches", btreeMatches);
- b.append("n", num);
- b.done();
- }
+ {
+ BSONObjBuilder b(result->subobjStart("stats"));
+ b.append("time", t.millis());
+ b.appendNumber("btreeMatches", btreeMatches);
+ b.append("n", num);
+ b.done();
}
+}
} // namespace mongo