summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2020-12-18 16:18:04 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-12-18 22:17:28 +0000
commita56d682b08d9a72ef54fde6d47c978b8eb54bfbc (patch)
tree603c9d290766759b3f9503ec90cfd0bb655f5500
parenta2a154c9a9aa133603d0f2797d77479a7f192ac8 (diff)
downloadmongo-a56d682b08d9a72ef54fde6d47c978b8eb54bfbc.tar.gz
SERVER-53395 time-series insert uses delta updates instead of classic update
-rw-r--r--src/mongo/db/commands/write_commands/write_commands.cpp57
1 files changed, 49 insertions, 8 deletions
diff --git a/src/mongo/db/commands/write_commands/write_commands.cpp b/src/mongo/db/commands/write_commands/write_commands.cpp
index 954154ba5fb..443f01bb160 100644
--- a/src/mongo/db/commands/write_commands/write_commands.cpp
+++ b/src/mongo/db/commands/write_commands/write_commands.cpp
@@ -65,6 +65,7 @@
#include "mongo/db/write_concern.h"
#include "mongo/s/stale_exception.h"
#include "mongo/util/fail_point.h"
+#include "mongo/util/string_map.h"
namespace mongo {
namespace {
@@ -175,16 +176,56 @@ write_ops::UpdateOpEntry makeTimeseriesUpdateOpEntry(const OID& bucketId,
const BSONObj& metadata) {
BSONObjBuilder updateBuilder;
{
- BSONObjBuilder setOpBuilder(updateBuilder.subobjStart("$set"));
- setOpBuilder.append("control.min", data.bucketMin);
- setOpBuilder.append("control.max", data.bucketMax);
- auto metadataElem = metadata.firstElement();
- appendTimeseriesDataFields(
- data.docs, metadataElem, data.numCommittedMeasurements, &setOpBuilder);
+ // doc_diff::kSubDiffSectionFieldPrefix + <field name>
+ BSONObjBuilder controlBuilder(updateBuilder.subobjStart("scontrol"));
+ {
+ // doc_diff::kUpdateSectionFieldName
+ BSONObjBuilder controlUpdateBuilder(controlBuilder.subobjStart("u"));
+ controlUpdateBuilder.append("min", data.bucketMin);
+ controlUpdateBuilder.append("max", data.bucketMax);
+ }
}
+ {
+ // doc_diff::kSubDiffSectionFieldPrefix + <field name> => {<index_0>: ..., <index_1>: ...}
+ StringDataMap<BSONObjBuilder> dataFieldBuilders;
+ auto metadataElem = metadata.firstElement();
+ auto count = data.numCommittedMeasurements;
+ for (const auto& doc : data.docs) {
+ for (const auto& elem : doc) {
+ auto key = elem.fieldNameStringData();
+ if (metadataElem && key == metadataElem.fieldNameStringData()) {
+ continue;
+ }
+ auto& builder = dataFieldBuilders[key];
+ builder.appendAs(elem, std::to_string(count));
+ }
+ count++;
+ }
- write_ops::UpdateModification u(updateBuilder.obj(),
- write_ops::UpdateModification::ClassicTag{});
+ // doc_diff::kSubDiffSectionFieldPrefix + <field name>
+ BSONObjBuilder dataBuilder(updateBuilder.subobjStart("sdata"));
+ BSONObjBuilder newDataFieldsBuilder;
+ for (auto& pair : dataFieldBuilders) {
+ // Existing 'data' fields with measurements require different treatment from fields
+ // not observed before (missing from control.min and control.max).
+ if (data.newFieldNamesToBeInserted.count(pair.first)) {
+ newDataFieldsBuilder.append(pair.first, pair.second.obj());
+ }
+ }
+ auto newDataFields = newDataFieldsBuilder.obj();
+ if (!newDataFields.isEmpty()) {
+ dataBuilder.append(doc_diff::kInsertSectionFieldName, newDataFields);
+ }
+ for (auto& pair : dataFieldBuilders) {
+ // Existing 'data' fields with measurements require different treatment from fields
+ // not observed before (missing from control.min and control.max).
+ if (!data.newFieldNamesToBeInserted.count(pair.first)) {
+ dataBuilder.append(doc_diff::kSubDiffSectionFieldPrefix + pair.first.toString(),
+ BSON(doc_diff::kInsertSectionFieldName << pair.second.obj()));
+ }
+ }
+ }
+ write_ops::UpdateModification u(updateBuilder.obj(), write_ops::UpdateModification::DiffTag{});
write_ops::UpdateOpEntry update(BSON("_id" << bucketId), std::move(u));
invariant(!update.getMulti(), bucketId.toString());
invariant(!update.getUpsert(), bucketId.toString());