diff options
author | David Storch <david.storch@10gen.com> | 2019-07-19 18:30:33 -0400 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2019-07-26 16:05:59 -0400 |
commit | 94fcb7d03e08014bb6a20ab010539811548d9e83 (patch) | |
tree | e44d2d923f59e0430645a13c3844f367cfa1bdb3 /src/mongo/db/exec | |
parent | dc4db514a1ee737db0553f9535033453502b3ac7 (diff) | |
download | mongo-94fcb7d03e08014bb6a20ab010539811548d9e83.tar.gz |
SERVER-42288 Consolidate Document and WorkingSetMember metadata implementations.
Diffstat (limited to 'src/mongo/db/exec')
-rw-r--r-- | src/mongo/db/exec/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/and_common.h | 8 | ||||
-rw-r--r-- | src/mongo/db/exec/change_stream_proxy.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/exec/distinct_scan.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/exec/ensure_sorted.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/exec/geo_near.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/exec/idhack.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/exec/index_scan.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/exec/projection.cpp | 40 | ||||
-rw-r--r-- | src/mongo/db/exec/projection_exec.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/exec/projection_exec.h | 7 | ||||
-rw-r--r-- | src/mongo/db/exec/projection_exec_test.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/exec/sort.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/exec/sort_key_generator.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/exec/sort_key_generator.h | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/text_or.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/exec/working_set.cpp | 20 | ||||
-rw-r--r-- | src/mongo/db/exec/working_set.h | 72 | ||||
-rw-r--r-- | src/mongo/db/exec/working_set_computed_data.cpp | 53 | ||||
-rw-r--r-- | src/mongo/db/exec/working_set_computed_data.h | 125 |
20 files changed, 71 insertions, 331 deletions
diff --git a/src/mongo/db/exec/SConscript b/src/mongo/db/exec/SConscript index 7ee2806711e..29ff41d620c 100644 --- a/src/mongo/db/exec/SConscript +++ b/src/mongo/db/exec/SConscript @@ -9,11 +9,11 @@ env.Library( target = "working_set", source = [ "working_set.cpp", - "working_set_computed_data.cpp" ], LIBDEPS = [ "$BUILD_DIR/mongo/base", "$BUILD_DIR/mongo/db/bson/dotted_path_support", + "$BUILD_DIR/mongo/db/pipeline/document_value", "$BUILD_DIR/mongo/db/service_context", ], ) diff --git a/src/mongo/db/exec/and_common.h b/src/mongo/db/exec/and_common.h index beb84e5751f..fe7a0573694 100644 --- a/src/mongo/db/exec/and_common.h +++ b/src/mongo/db/exec/and_common.h @@ -52,13 +52,7 @@ public: verify(src.hasRecordId()); verify(dest->recordId == src.recordId); - // Merge computed data. - typedef WorkingSetComputedDataType WSCD; - for (WSCD i = WSCD(0); i < WSM_COMPUTED_NUM_TYPES; i = WSCD(i + 1)) { - if (!dest->hasComputed(i) && src.hasComputed(i)) { - dest->addComputed(src.getComputed(i)->clone()); - } - } + dest->metadata().mergeWith(src.metadata()); if (dest->hasObj()) { // The merged WSM that we're creating already has the full document, so there's diff --git a/src/mongo/db/exec/change_stream_proxy.cpp b/src/mongo/db/exec/change_stream_proxy.cpp index 62e6de4aba6..d4f5ae39c6f 100644 --- a/src/mongo/db/exec/change_stream_proxy.cpp +++ b/src/mongo/db/exec/change_stream_proxy.cpp @@ -56,7 +56,7 @@ boost::optional<BSONObj> ChangeStreamProxyStage::getNextBson() { // the latest event observed in the oplog, the latter via its sort key metadata field. auto nextBSON = _validateAndConvertToBSON(*next); _latestOplogTimestamp = PipelineD::getLatestOplogTimestamp(_pipeline.get()); - _postBatchResumeToken = next->getSortKeyMetaField(); + _postBatchResumeToken = next->metadata().getSortKey(); _setSpeculativeReadTimestamp(); return nextBSON; } @@ -83,7 +83,7 @@ BSONObj ChangeStreamProxyStage::_validateAndConvertToBSON(const Document& event) } // Confirm that the document _id field matches the original resume token in the sort key field. auto eventBSON = event.toBson(); - auto resumeToken = event.getSortKeyMetaField(); + auto resumeToken = event.metadata().getSortKey(); auto idField = eventBSON.getObjectField("_id"); invariant(!resumeToken.isEmpty()); uassert(ErrorCodes::ChangeStreamFatalError, diff --git a/src/mongo/db/exec/distinct_scan.cpp b/src/mongo/db/exec/distinct_scan.cpp index af7d3c49cfa..22af764672f 100644 --- a/src/mongo/db/exec/distinct_scan.cpp +++ b/src/mongo/db/exec/distinct_scan.cpp @@ -35,7 +35,6 @@ #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/exec/filter.h" #include "mongo/db/exec/scoped_timer.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/index/index_access_method.h" #include "mongo/db/index/index_descriptor.h" diff --git a/src/mongo/db/exec/ensure_sorted.cpp b/src/mongo/db/exec/ensure_sorted.cpp index d10e7e95308..611835aaba6 100644 --- a/src/mongo/db/exec/ensure_sorted.cpp +++ b/src/mongo/db/exec/ensure_sorted.cpp @@ -34,7 +34,6 @@ #include <memory> #include "mongo/db/exec/scoped_timer.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/query/find_common.h" namespace mongo { @@ -60,12 +59,10 @@ PlanStage::StageState EnsureSortedStage::doWork(WorkingSetID* out) { StageState stageState = child()->work(out); if (PlanStage::ADVANCED == stageState) { - // We extract the sort key from the WSM's computed data. This must have been generated - // by a SortKeyGeneratorStage descendent in the execution tree. + // We extract the sort key from the WSM's metadata. This must have been generated by a + // SortKeyGeneratorStage descendent in the execution tree. WorkingSetMember* member = _ws->get(*out); - auto sortKeyComputedData = - static_cast<const SortKeyComputedData*>(member->getComputed(WSM_SORT_KEY)); - BSONObj curSortKey = sortKeyComputedData->getSortKey(); + auto curSortKey = member->metadata().getSortKey(); invariant(!curSortKey.isEmpty()); if (!_prevSortKey.isEmpty() && !isInOrder(_prevSortKey, curSortKey)) { diff --git a/src/mongo/db/exec/geo_near.cpp b/src/mongo/db/exec/geo_near.cpp index f3f08bd3be8..df28f3edcdb 100644 --- a/src/mongo/db/exec/geo_near.cpp +++ b/src/mongo/db/exec/geo_near.cpp @@ -41,12 +41,12 @@ #include "mongo/db/bson/dotted_path_support.h" #include "mongo/db/exec/fetch.h" #include "mongo/db/exec/index_scan.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/geo/geoconstants.h" #include "mongo/db/geo/geoparser.h" #include "mongo/db/geo/hash.h" #include "mongo/db/index/expression_params.h" #include "mongo/db/matcher/expression.h" +#include "mongo/db/pipeline/value.h" #include "mongo/db/query/expression_index.h" #include "mongo/db/query/expression_index_knobs_gen.h" #include "mongo/util/log.h" @@ -155,7 +155,7 @@ static StatusWith<double> computeGeoNearDistance(const GeoNearParams& nearParams // Compute the minimum distance of all the geometries in the document double minDistance = -1; - BSONObj minDistanceObj; + Value minDistanceMetadata; for (auto it = geometries.begin(); it != geometries.end(); ++it) { StoredGeometry& stored = **it; @@ -175,7 +175,7 @@ static StatusWith<double> computeGeoNearDistance(const GeoNearParams& nearParams if (minDistance < 0 || nextDistance < minDistance) { minDistance = nextDistance; - minDistanceObj = stored.element.Obj(); + minDistanceMetadata = Value{stored.element}; } } @@ -189,14 +189,14 @@ static StatusWith<double> computeGeoNearDistance(const GeoNearParams& nearParams // Hack for nearSphere // TODO: Remove nearSphere? invariant(SPHERE == queryCRS); - member->addComputed(new GeoDistanceComputedData(minDistance / kRadiusOfEarthInMeters)); + member->metadata().setGeoNearDistance(minDistance / kRadiusOfEarthInMeters); } else { - member->addComputed(new GeoDistanceComputedData(minDistance)); + member->metadata().setGeoNearDistance(minDistance); } } if (nearParams.addPointMeta) { - member->addComputed(new GeoNearPointComputedData(minDistanceObj)); + member->metadata().setGeoNearPoint(minDistanceMetadata); } return StatusWith<double>(minDistance); diff --git a/src/mongo/db/exec/idhack.cpp b/src/mongo/db/exec/idhack.cpp index b287dc12531..13a5837b53d 100644 --- a/src/mongo/db/exec/idhack.cpp +++ b/src/mongo/db/exec/idhack.cpp @@ -39,7 +39,6 @@ #include "mongo/db/exec/projection.h" #include "mongo/db/exec/scoped_timer.h" #include "mongo/db/exec/working_set_common.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/index/btree_access_method.h" namespace mongo { @@ -133,8 +132,7 @@ PlanStage::StageState IDHackStage::advance(WorkingSetID id, if (_addKeyMetadata) { BSONObj ownedKeyObj = member->obj.value()["_id"].wrap().getOwned(); - member->addComputed( - new IndexKeyComputedData(IndexKeyComputedData::rehydrateKey(_key, ownedKeyObj))); + member->metadata().setIndexKey(IndexKeyEntry::rehydrateKey(_key, ownedKeyObj)); } _done = true; diff --git a/src/mongo/db/exec/index_scan.cpp b/src/mongo/db/exec/index_scan.cpp index f74743629bb..7e5c9c19152 100644 --- a/src/mongo/db/exec/index_scan.cpp +++ b/src/mongo/db/exec/index_scan.cpp @@ -39,7 +39,6 @@ #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/exec/filter.h" #include "mongo/db/exec/scoped_timer.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/index/index_access_method.h" #include "mongo/db/index_names.h" #include "mongo/db/query/index_bounds_builder.h" @@ -217,8 +216,7 @@ PlanStage::StageState IndexScan::doWork(WorkingSetID* out) { _workingSet->transitionToRecordIdAndIdx(id); if (_addKeyMetadata) { - member->addComputed( - new IndexKeyComputedData(IndexKeyComputedData::rehydrateKey(_keyPattern, kv->key))); + member->metadata().setIndexKey(IndexKeyEntry::rehydrateKey(_keyPattern, kv->key)); } *out = id; diff --git a/src/mongo/db/exec/projection.cpp b/src/mongo/db/exec/projection.cpp index eb2933ffa63..f48a09ffb02 100644 --- a/src/mongo/db/exec/projection.cpp +++ b/src/mongo/db/exec/projection.cpp @@ -37,7 +37,6 @@ #include "mongo/db/exec/plan_stage.h" #include "mongo/db/exec/scoped_timer.h" #include "mongo/db/exec/working_set_common.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/jsobj.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/record_id.h" @@ -51,33 +50,30 @@ static const char* kIdField = "_id"; namespace { BSONObj indexKey(const WorkingSetMember& member) { - return static_cast<const IndexKeyComputedData*>(member.getComputed(WSM_INDEX_KEY))->getKey(); + return member.metadata().getIndexKey(); } BSONObj sortKey(const WorkingSetMember& member) { - return static_cast<const SortKeyComputedData*>(member.getComputed(WSM_SORT_KEY))->getSortKey(); + return member.metadata().getSortKey(); } double geoDistance(const WorkingSetMember& member) { - return static_cast<const GeoDistanceComputedData*>( - member.getComputed(WSM_COMPUTED_GEO_DISTANCE)) - ->getDist(); + return member.metadata().getGeoNearDistance(); } -BSONObj geoPoint(const WorkingSetMember& member) { - return static_cast<const GeoNearPointComputedData*>(member.getComputed(WSM_GEO_NEAR_POINT)) - ->getPoint(); +Value geoPoint(const WorkingSetMember& member) { + return member.metadata().getGeoNearPoint(); } double textScore(const WorkingSetMember& member) { - if (member.hasComputed(WSM_COMPUTED_TEXT_SCORE)) - return static_cast<const TextScoreComputedData*>( - member.getComputed(WSM_COMPUTED_TEXT_SCORE)) - ->getScore(); - // It is permitted to request a text score when none has been computed. Zero is returned as an - // empty value in this case. - else + auto&& metadata = member.metadata(); + if (metadata.hasTextScore()) { + return metadata.getTextScore(); + } else { + // It is permitted to request a text score when none has been computed. Zero is returned as + // an empty value in this case. return 0.0; + } } void transitionMemberToOwnedObj(const BSONObj& bo, WorkingSetMember* member) { @@ -89,10 +85,10 @@ void transitionMemberToOwnedObj(const BSONObj& bo, WorkingSetMember* member) { StatusWith<BSONObj> provideMetaFieldsAndPerformExec(const ProjectionExec& exec, const WorkingSetMember& member) { - if (exec.needsGeoNearDistance() && !member.hasComputed(WSM_COMPUTED_GEO_DISTANCE)) + if (exec.needsGeoNearDistance() && !member.metadata().hasGeoNearDistance()) return Status(ErrorCodes::InternalError, "near loc dist requested but no data available"); - if (exec.needsGeoNearPoint() && !member.hasComputed(WSM_GEO_NEAR_POINT)) + if (exec.needsGeoNearPoint() && !member.metadata().hasGeoNearPoint()) return Status(ErrorCodes::InternalError, "near loc proj requested but no data available"); return member.hasObj() @@ -100,7 +96,7 @@ StatusWith<BSONObj> provideMetaFieldsAndPerformExec(const ProjectionExec& exec, exec.needsGeoNearDistance() ? boost::optional<const double>(geoDistance(member)) : boost::none, - exec.needsGeoNearPoint() ? geoPoint(member) : BSONObj(), + exec.needsGeoNearPoint() ? geoPoint(member) : Value{}, exec.needsSortKey() ? sortKey(member) : BSONObj(), exec.needsTextScore() ? boost::optional<const double>(textScore(member)) : boost::none, @@ -109,7 +105,7 @@ StatusWith<BSONObj> provideMetaFieldsAndPerformExec(const ProjectionExec& exec, member.keyData, exec.needsGeoNearDistance() ? boost::optional<const double>(geoDistance(member)) : boost::none, - exec.needsGeoNearPoint() ? geoPoint(member) : BSONObj(), + exec.needsGeoNearPoint() ? geoPoint(member) : Value{}, exec.needsSortKey() ? sortKey(member) : BSONObj(), exec.needsTextScore() ? boost::optional<const double>(textScore(member)) : boost::none, @@ -204,13 +200,13 @@ ProjectionStageDefault::ProjectionStageDefault(OperationContext* opCtx, Status ProjectionStageDefault::transform(WorkingSetMember* member) const { // The default no-fast-path case. - if (_exec.needsSortKey() && !member->hasComputed(WSM_SORT_KEY)) + if (_exec.needsSortKey() && !member->metadata().hasSortKey()) return Status(ErrorCodes::InternalError, "sortKey meta-projection requested but no data available"); if (_exec.returnKey()) { auto keys = _exec.computeReturnKeyProjection( - member->hasComputed(WSM_INDEX_KEY) ? indexKey(*member) : BSONObj(), + member->metadata().hasIndexKey() ? indexKey(*member) : BSONObj(), _exec.needsSortKey() ? sortKey(*member) : BSONObj()); if (!keys.isOK()) return keys.getStatus(); diff --git a/src/mongo/db/exec/projection_exec.cpp b/src/mongo/db/exec/projection_exec.cpp index aae286bb318..736dd900545 100644 --- a/src/mongo/db/exec/projection_exec.cpp +++ b/src/mongo/db/exec/projection_exec.cpp @@ -218,7 +218,7 @@ StatusWith<BSONObj> ProjectionExec::computeReturnKeyProjection(const BSONObj& in StatusWith<BSONObj> ProjectionExec::project(const BSONObj& in, const boost::optional<const double> geoDistance, - const BSONObj& geoNearPoint, + Value geoNearPoint, const BSONObj& sortKey, const boost::optional<const double> textScore, const int64_t recordId) const { @@ -241,7 +241,7 @@ StatusWith<BSONObj> ProjectionExec::project(const BSONObj& in, StatusWith<BSONObj> ProjectionExec::projectCovered(const std::vector<IndexKeyDatum>& keyData, const boost::optional<const double> geoDistance, - const BSONObj& geoNearPoint, + Value geoNearPoint, const BSONObj& sortKey, const boost::optional<const double> textScore, const int64_t recordId) const { @@ -294,7 +294,7 @@ StatusWith<BSONObj> ProjectionExec::projectCovered(const std::vector<IndexKeyDat BSONObj ProjectionExec::addMeta(BSONObjBuilder bob, const boost::optional<const double> geoDistance, - const BSONObj& geoNearPoint, + Value geoNearPoint, const BSONObj& sortKey, const boost::optional<const double> textScore, const int64_t recordId) const { @@ -305,13 +305,8 @@ BSONObj ProjectionExec::addMeta(BSONObjBuilder bob, bob.append(it->first, geoDistance.get()); break; case META_GEONEAR_POINT: { - invariant(!geoNearPoint.isEmpty()); - auto& ptObj = geoNearPoint; - if (ptObj.couldBeArray()) { - bob.appendArray(it->first, ptObj); - } else { - bob.append(it->first, ptObj); - } + invariant(!geoNearPoint.missing()); + geoNearPoint.addToBsonObj(&bob, it->first); break; } case META_TEXT_SCORE: diff --git a/src/mongo/db/exec/projection_exec.h b/src/mongo/db/exec/projection_exec.h index ab4dc5f48dc..a6ce7b1317c 100644 --- a/src/mongo/db/exec/projection_exec.h +++ b/src/mongo/db/exec/projection_exec.h @@ -35,6 +35,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression_parser.h" +#include "mongo/db/pipeline/value.h" #include "mongo/util/string_map.h" namespace mongo { @@ -134,7 +135,7 @@ public: */ StatusWith<BSONObj> project(const BSONObj& in, const boost::optional<const double> geoDistance = boost::none, - const BSONObj& geoNearPoint = BSONObj(), + Value geoNearPoint = Value{}, const BSONObj& sortKey = BSONObj(), const boost::optional<const double> textScore = boost::none, const int64_t recordId = 0) const; @@ -147,7 +148,7 @@ public: StatusWith<BSONObj> projectCovered( const std::vector<IndexKeyDatum>& keyData, const boost::optional<const double> geoDistance = boost::none, - const BSONObj& geoNearPoint = BSONObj(), + Value geoNearPoint = Value{}, const BSONObj& sortKey = BSONObj(), const boost::optional<const double> textScore = boost::none, const int64_t recordId = 0) const; @@ -167,7 +168,7 @@ private: */ BSONObj addMeta(BSONObjBuilder bob, const boost::optional<const double> geoDistance, - const BSONObj& geoNearPoint, + Value geoNearPoint, const BSONObj& sortKey, const boost::optional<const double> textScore, const int64_t recordId) const; diff --git a/src/mongo/db/exec/projection_exec_test.cpp b/src/mongo/db/exec/projection_exec_test.cpp index 9c04e20c2d0..33e14d01406 100644 --- a/src/mongo/db/exec/projection_exec_test.cpp +++ b/src/mongo/db/exec/projection_exec_test.cpp @@ -37,7 +37,6 @@ #include "mongo/db/exec/projection_exec.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/json.h" #include "mongo/db/matcher/expression_parser.h" #include "mongo/db/pipeline/expression_context_for_test.h" @@ -81,10 +80,10 @@ boost::optional<std::string> project( auto objStr = stdx::get_if<const char*>(&objStrOrDatum); auto projected = objStr - ? exec.project(fromjson(*objStr), boost::none, BSONObj(), sortKey, textScore) + ? exec.project(fromjson(*objStr), boost::none, Value{}, sortKey, textScore) : exec.projectCovered({stdx::get<const IndexKeyDatum>(objStrOrDatum)}, boost::none, - BSONObj(), + Value{}, sortKey, textScore); diff --git a/src/mongo/db/exec/sort.cpp b/src/mongo/db/exec/sort.cpp index 9bf39c08773..13f1615ee11 100644 --- a/src/mongo/db/exec/sort.cpp +++ b/src/mongo/db/exec/sort.cpp @@ -37,7 +37,6 @@ #include "mongo/db/catalog/collection.h" #include "mongo/db/exec/scoped_timer.h" #include "mongo/db/exec/working_set_common.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/index/btree_key_generator.h" #include "mongo/db/index_names.h" #include "mongo/db/query/find_common.h" @@ -126,11 +125,9 @@ PlanStage::StageState SortStage::doWork(WorkingSetID* out) { SortableDataItem item; item.wsid = id; - // We extract the sort key from the WSM's computed data. This must have been generated - // by a SortKeyGeneratorStage descendent in the execution tree. - auto sortKeyComputedData = - static_cast<const SortKeyComputedData*>(member->getComputed(WSM_SORT_KEY)); - item.sortKey = sortKeyComputedData->getSortKey(); + // We extract the sort key from the WSM's metadata. This must have been generated by a + // SortKeyGeneratorStage descendent in the execution tree. + item.sortKey = member->metadata().getSortKey(); if (member->hasRecordId()) { // The RecordId breaks ties when sorting two WSMs with the same sort key. diff --git a/src/mongo/db/exec/sort_key_generator.cpp b/src/mongo/db/exec/sort_key_generator.cpp index 1aa3abf8660..7b846f18bad 100644 --- a/src/mongo/db/exec/sort_key_generator.cpp +++ b/src/mongo/db/exec/sort_key_generator.cpp @@ -41,7 +41,6 @@ #include "mongo/db/exec/scoped_timer.h" #include "mongo/db/exec/working_set.h" #include "mongo/db/exec/working_set_common.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/matcher/extensions_callback_noop.h" #include "mongo/db/query/collation/collator_interface.h" #include "mongo/util/log.h" @@ -74,8 +73,8 @@ PlanStage::StageState SortKeyGeneratorStage::doWork(WorkingSetID* out) { return PlanStage::FAILURE; } - // Add the sort key to the WSM as computed data. - member->addComputed(new SortKeyComputedData(sortKey.getValue())); + // Add the sort key to the WSM as metadata. + member->metadata().setSortKey(sortKey.getValue()); return PlanStage::ADVANCED; } diff --git a/src/mongo/db/exec/sort_key_generator.h b/src/mongo/db/exec/sort_key_generator.h index b5208ee78fb..79cb5a6fe49 100644 --- a/src/mongo/db/exec/sort_key_generator.h +++ b/src/mongo/db/exec/sort_key_generator.h @@ -45,7 +45,7 @@ class WorkingSetMember; /** * Passes results from the child through after adding the sort key for each result as - * WorkingSetMember computed data. + * WorkingSetMember metadata. */ class SortKeyGeneratorStage final : public PlanStage { public: diff --git a/src/mongo/db/exec/text_or.cpp b/src/mongo/db/exec/text_or.cpp index 2e3eb79d5a0..c945ccd2fcd 100644 --- a/src/mongo/db/exec/text_or.cpp +++ b/src/mongo/db/exec/text_or.cpp @@ -39,7 +39,6 @@ #include "mongo/db/exec/scoped_timer.h" #include "mongo/db/exec/working_set.h" #include "mongo/db/exec/working_set_common.h" -#include "mongo/db/exec/working_set_computed_data.h" #include "mongo/db/jsobj.h" #include "mongo/db/record_id.h" @@ -236,8 +235,8 @@ PlanStage::StageState TextOrStage::returnResults(WorkingSetID* out) { WorkingSetMember* wsm = _ws->get(textRecordData.wsid); - // Populate the working set member with the text score and return it. - wsm->addComputed(new TextScoreComputedData(textRecordData.score)); + // Populate the working set member with the text score metadata and return it. + wsm->metadata().setTextScore(textRecordData.score); *out = textRecordData.wsid; return PlanStage::ADVANCED; } diff --git a/src/mongo/db/exec/working_set.cpp b/src/mongo/db/exec/working_set.cpp index 79a0fbbcaa6..400be5acb83 100644 --- a/src/mongo/db/exec/working_set.cpp +++ b/src/mongo/db/exec/working_set.cpp @@ -125,10 +125,7 @@ WorkingSetMember::WorkingSetMember() {} WorkingSetMember::~WorkingSetMember() {} void WorkingSetMember::clear() { - for (size_t i = 0; i < WSM_COMPUTED_NUM_TYPES; i++) { - _computed[i].reset(); - } - + _metadata = DocumentMetadataFields{}; keyData.clear(); obj.reset(); _state = WorkingSetMember::INVALID; @@ -162,21 +159,6 @@ void WorkingSetMember::makeObjOwnedIfNeeded() { } } -bool WorkingSetMember::hasComputed(const WorkingSetComputedDataType type) const { - return _computed[type].get(); -} - -const WorkingSetComputedData* WorkingSetMember::getComputed( - const WorkingSetComputedDataType type) const { - verify(_computed[type]); - return _computed[type].get(); -} - -void WorkingSetMember::addComputed(WorkingSetComputedData* data) { - verify(!hasComputed(data->type())); - _computed[data->type()].reset(data); -} - bool WorkingSetMember::getFieldDotted(const string& field, BSONElement* out) const { // If our state is such that we have an object, use it. if (hasObj()) { diff --git a/src/mongo/db/exec/working_set.h b/src/mongo/db/exec/working_set.h index fc6a228036d..43814158fb5 100644 --- a/src/mongo/db/exec/working_set.h +++ b/src/mongo/db/exec/working_set.h @@ -33,6 +33,7 @@ #include <vector> #include "mongo/db/jsobj.h" +#include "mongo/db/pipeline/document_metadata_fields.h" #include "mongo/db/record_id.h" #include "mongo/db/storage/snapshot.h" #include "mongo/stdx/unordered_set.h" @@ -181,51 +182,6 @@ struct IndexKeyDatum { }; /** - * What types of computed data can we have? - */ -enum WorkingSetComputedDataType { - // What's the score of the document retrieved from a $text query? - WSM_COMPUTED_TEXT_SCORE = 0, - - // What's the distance from a geoNear query point to the document? - WSM_COMPUTED_GEO_DISTANCE = 1, - - // The index key used to retrieve the document, for returnKey query option. - WSM_INDEX_KEY = 2, - - // What point (of several possible points) was used to compute the distance to the document - // via geoNear? - WSM_GEO_NEAR_POINT = 3, - - // Comparison key for sorting. - WSM_SORT_KEY = 4, - - // Must be last. - WSM_COMPUTED_NUM_TYPES, -}; - -/** - * Data that is a computed function of a WSM. - */ -class WorkingSetComputedData { - WorkingSetComputedData(const WorkingSetComputedData&) = delete; - WorkingSetComputedData& operator=(const WorkingSetComputedData&) = delete; - -public: - WorkingSetComputedData(const WorkingSetComputedDataType type) : _type(type) {} - virtual ~WorkingSetComputedData() {} - - WorkingSetComputedDataType type() const { - return _type; - } - - virtual WorkingSetComputedData* clone() const = 0; - -private: - WorkingSetComputedDataType _type; -}; - -/** * The type of the data passed between query stages. In particular: * * Index scan stages return a WorkingSetMember in the RID_AND_IDX state. @@ -297,14 +253,6 @@ public: */ void makeObjOwnedIfNeeded(); - // - // Computed data - // - - bool hasComputed(const WorkingSetComputedDataType type) const; - const WorkingSetComputedData* getComputed(const WorkingSetComputedDataType type) const; - void addComputed(WorkingSetComputedData* data); - /** * getFieldDotted uses its state (obj or index data) to produce the field with the provided * name. @@ -321,12 +269,28 @@ public: */ size_t getMemUsage() const; + /** + * Returns a const reference to an object housing the metadata fields associated with this + * WorkingSetMember. + */ + const DocumentMetadataFields& metadata() const { + return _metadata; + } + + /** + * Returns a non-const reference to an object housing the metadata fields associated with this + * WorkingSetMember. + */ + DocumentMetadataFields& metadata() { + return _metadata; + } + private: friend class WorkingSet; MemberState _state = WorkingSetMember::INVALID; - std::unique_ptr<WorkingSetComputedData> _computed[WSM_COMPUTED_NUM_TYPES]; + DocumentMetadataFields _metadata; }; } // namespace mongo diff --git a/src/mongo/db/exec/working_set_computed_data.cpp b/src/mongo/db/exec/working_set_computed_data.cpp deleted file mode 100644 index 5b8170778f8..00000000000 --- a/src/mongo/db/exec/working_set_computed_data.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * 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 Server Side 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. - */ - -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault - -#include "mongo/db/exec/working_set_computed_data.h" - -#include "mongo/util/log.h" - -namespace mongo { - -BSONObj IndexKeyComputedData::rehydrateKey(const BSONObj& keyPattern, - const BSONObj& dehydratedKey) { - BSONObjBuilder bob; - BSONObjIterator keyIter(keyPattern); - BSONObjIterator valueIter(dehydratedKey); - - while (keyIter.more() && valueIter.more()) { - bob.appendAs(valueIter.next(), keyIter.next().fieldNameStringData()); - } - - invariant(!keyIter.more()); - invariant(!valueIter.more()); - - return bob.obj(); -} -} // namespace mongo diff --git a/src/mongo/db/exec/working_set_computed_data.h b/src/mongo/db/exec/working_set_computed_data.h deleted file mode 100644 index 3d71d4a815e..00000000000 --- a/src/mongo/db/exec/working_set_computed_data.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * 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 Server Side 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 "mongo/db/exec/working_set.h" - -namespace mongo { - -class TextScoreComputedData : public WorkingSetComputedData { -public: - TextScoreComputedData(double score) - : WorkingSetComputedData(WSM_COMPUTED_TEXT_SCORE), _score(score) {} - - double getScore() const { - return _score; - } - - TextScoreComputedData* clone() const final { - return new TextScoreComputedData(_score); - } - -private: - double _score; -}; - -class GeoDistanceComputedData : public WorkingSetComputedData { -public: - GeoDistanceComputedData(double dist) - : WorkingSetComputedData(WSM_COMPUTED_GEO_DISTANCE), _dist(dist) {} - - double getDist() const { - return _dist; - } - - GeoDistanceComputedData* clone() const final { - return new GeoDistanceComputedData(_dist); - } - -private: - double _dist; -}; - -class IndexKeyComputedData : public WorkingSetComputedData { -public: - // Given an index key 'dehydratedKey' with no field names, returns a new BSONObj after adding - // field names according to 'keyPattern'. - static BSONObj rehydrateKey(const BSONObj& keyPattern, const BSONObj& dehydratedKey); - - IndexKeyComputedData(BSONObj key) - : WorkingSetComputedData(WSM_INDEX_KEY), _key(key.getOwned()) {} - - BSONObj getKey() const { - return _key; - } - - IndexKeyComputedData* clone() const final { - return new IndexKeyComputedData(_key); - } - -private: - BSONObj _key; -}; - -class GeoNearPointComputedData : public WorkingSetComputedData { -public: - GeoNearPointComputedData(BSONObj point) - : WorkingSetComputedData(WSM_GEO_NEAR_POINT), _point(point.getOwned()) {} - - BSONObj getPoint() const { - return _point; - } - - GeoNearPointComputedData* clone() const final { - return new GeoNearPointComputedData(_point); - } - -private: - BSONObj _point; -}; - -class SortKeyComputedData : public WorkingSetComputedData { -public: - SortKeyComputedData(BSONObj sortKey) - : WorkingSetComputedData(WSM_SORT_KEY), _sortKey(sortKey.getOwned()) {} - - BSONObj getSortKey() const { - return _sortKey; - } - - SortKeyComputedData* clone() const final { - return new SortKeyComputedData(_sortKey); - } - -private: - BSONObj _sortKey; -}; - -} // namespace mongo |