diff options
Diffstat (limited to 'src/mongo/db/exec/sbe/values/slot.cpp')
| -rw-r--r-- | src/mongo/db/exec/sbe/values/slot.cpp | 110 |
1 files changed, 32 insertions, 78 deletions
diff --git a/src/mongo/db/exec/sbe/values/slot.cpp b/src/mongo/db/exec/sbe/values/slot.cpp index 93605a9abfa..45cbc977980 100644 --- a/src/mongo/db/exec/sbe/values/slot.cpp +++ b/src/mongo/db/exec/sbe/values/slot.cpp @@ -42,9 +42,7 @@ #include "mongo/util/bufreader.h" namespace mongo::sbe::value { - -static std::pair<TypeTags, Value> deserializeValue(BufReader& buf, - const CollatorInterface* collator) { +static std::pair<TypeTags, Value> deserializeValue(BufReader& buf) { auto tag = static_cast<TypeTags>(buf.read<uint8_t>()); Value val; @@ -109,7 +107,7 @@ static std::pair<TypeTags, Value> deserializeValue(BufReader& buf, if (cnt) { arr->reserve(cnt); for (size_t idx = 0; idx < cnt; ++idx) { - auto [tag, val] = deserializeValue(buf, collator); + auto [tag, val] = deserializeValue(buf); arr->push_back(tag, val); } } @@ -118,16 +116,13 @@ static std::pair<TypeTags, Value> deserializeValue(BufReader& buf, break; } case TypeTags::ArraySet: { - // The first byte is a flag to tell us whether the ArraySet had a collation prior to - // serialization. - auto collated = buf.read<char>(); - auto [arrTag, arrVal] = makeNewArraySet(collated ? collator : nullptr); auto cnt = buf.read<LittleEndian<size_t>>(); + auto [arrTag, arrVal] = makeNewArraySet(); auto arr = getArraySetView(arrVal); if (cnt) { arr->reserve(cnt); for (size_t idx = 0; idx < cnt; ++idx) { - auto [tag, val] = deserializeValue(buf, collator); + auto [tag, val] = deserializeValue(buf); arr->push_back(tag, val); } } @@ -143,7 +138,7 @@ static std::pair<TypeTags, Value> deserializeValue(BufReader& buf, obj->reserve(cnt); for (size_t idx = 0; idx < cnt; ++idx) { auto fieldName = buf.readCStr(); - auto [tag, val] = deserializeValue(buf, collator); + auto [tag, val] = deserializeValue(buf); obj->push_back(fieldName, tag, val); } } @@ -218,12 +213,12 @@ static std::pair<TypeTags, Value> deserializeValue(BufReader& buf, } MaterializedRow MaterializedRow::deserializeForSorter(BufReader& buf, - const SorterDeserializeSettings& settings) { + const SorterDeserializeSettings&) { auto cnt = buf.read<LittleEndian<size_t>>(); MaterializedRow result{cnt}; for (size_t idx = 0; idx < cnt; ++idx) { - auto [tag, val] = deserializeValue(buf, settings.collator); + auto [tag, val] = deserializeValue(buf); result.reset(idx, true, tag, val); } @@ -293,12 +288,6 @@ static void serializeValue(BufBuilder& buf, TypeTags tag, Value val) { } case TypeTags::ArraySet: { auto arr = getArraySetView(val); - // If an ArraySet has a collation, we serialize a byte which acts as a flag as to - // whether the set should be created with a collation upon deserialization. Also, we - // assume that the caller which does deserialization will have the context about what - // the collation is, and therefore we can save space by not serializing the full - // description of the collation. - buf.appendChar(arr->getCollator() ? 1 : 0); buf.appendNum(arr->size()); for (auto& kv : arr->values()) { serializeValue(buf, kv.first, kv.second); @@ -382,22 +371,7 @@ static void serializeValue(BufBuilder& buf, TypeTags tag, Value val) { } } -/** - * If non-null 'collator' is provided during serialization, then the encoding guarantees that values - * which are equal up to the collation will encode to the same result, allowing for collation-aware - * equality comparisons. However, the collator-aware encoded values are not always decodable. Groups - * store an original copy of the group key alongside the encoded key string when there is a - * collation, so the key string does not need to be decodable. - */ -static void serializeValueIntoKeyString(KeyString::Builder& buf, - TypeTags tag, - Value val, - const CollatorInterface* collator) { - - const auto stringTransformFn = [&](StringData stringData) { - return collator->getComparisonString(stringData); - }; - +static void serializeValueIntoKeyString(KeyString::Builder& buf, TypeTags tag, Value val) { switch (tag) { case TypeTags::Nothing: { buf.appendBool(false); @@ -460,21 +434,19 @@ static void serializeValueIntoKeyString(KeyString::Builder& buf, buf.appendUndefined(); break; } - case TypeTags::StringSmall: + case TypeTags::StringSmall: { + // Small strings cannot contain null bytes, so it is safe to serialize them as plain + // C-strings with a null terminator. + buf.appendBool(true); + buf.appendString(getStringView(tag, val)); + break; + } case TypeTags::StringBig: case TypeTags::bsonString: { buf.appendBool(true); - if (collator) { - buf.appendString(getStringView(tag, val), stringTransformFn); - } else { - buf.appendString(getStringView(tag, val)); - } + buf.appendString(getStringOrSymbolView(tag, val)); break; } - // Note that the collation would have to apply to bsonSymbol values to match the - // behavior of the Classic engine when spilling groups to disk. bsonSymbol is - // deprecated, however, and SBE no longer provides strict correctness guarantees about - // computations on bsonSymbol values. case TypeTags::bsonSymbol: { buf.appendBool(true); buf.appendSymbol(getStringOrSymbolView(tag, val)); @@ -485,13 +457,9 @@ static void serializeValueIntoKeyString(KeyString::Builder& buf, // TODO SERVER-61629: convert this to serialize the 'arr' directly instead of // constructing a BSONArray. BSONArrayBuilder builder; - bson::convertToBsonObj(builder, value::ArrayEnumerator{tag, val}); + bson::convertToBsonObj(builder, getArrayView(val)); buf.appendBool(true); - if (collator) { - buf.appendArray(builder.arr(), stringTransformFn); - } else { - buf.appendArray(builder.arr()); - } + buf.appendArray(BSONArray(builder.done())); break; } case TypeTags::Object: { @@ -500,37 +468,27 @@ static void serializeValueIntoKeyString(KeyString::Builder& buf, BSONObjBuilder builder; bson::convertToBsonObj(builder, getObjectView(val)); buf.appendBool(true); - if (collator) { - buf.appendObject(builder.done(), stringTransformFn); - } else { - buf.appendObject(builder.done()); - } + buf.appendObject(builder.done()); break; } - case TypeTags::bsonObjectId: case TypeTags::ObjectId: { buf.appendBool(true); - buf.appendOID(OID::from(getRawPointerView(val))); + buf.appendBytes(getObjectIdView(val), sizeof(ObjectIdType)); break; } case TypeTags::bsonObject: { - BSONObj bson{getRawPointerView(val)}; buf.appendBool(true); - if (collator) { - buf.appendObject(bson, stringTransformFn); - } else { - buf.appendObject(bson); - } + buf.appendObject(BSONObj(getRawPointerView(val))); break; } case TypeTags::bsonArray: { - BSONObj bson{getRawPointerView(val)}; buf.appendBool(true); - if (collator) { - buf.appendArray(BSONArray(BSONObj(bson)), stringTransformFn); - } else { - buf.appendArray(BSONArray(BSONObj(bson))); - } + buf.appendArray(BSONArray(BSONObj(getRawPointerView(val)))); + break; + } + case TypeTags::bsonObjectId: { + buf.appendBool(true); + buf.appendOID(OID::from(getRawPointerView(val))); break; } case TypeTags::bsonBinData: { @@ -599,18 +557,15 @@ void MaterializedRow::serializeForSorter(BufBuilder& buf) const { } } -void MaterializedRow::serializeIntoKeyString(KeyString::Builder& buf, - const CollatorInterface* collator) const { +void MaterializedRow::serializeIntoKeyString(KeyString::Builder& buf) const { for (size_t idx = 0; idx < size(); ++idx) { auto [tag, val] = getViewOfValue(idx); - serializeValueIntoKeyString(buf, tag, val, collator); + serializeValueIntoKeyString(buf, tag, val); } } -MaterializedRow MaterializedRow::deserializeFromKeyString( - const KeyString::Value& keyString, - BufBuilder* valueBufferBuilder, - boost::optional<size_t> numPrefixValsToRead) { +MaterializedRow MaterializedRow::deserializeFromKeyString(const KeyString::Value& keyString, + BufBuilder* valueBufferBuilder) { BufReader reader(keyString.getBuffer(), keyString.getSize()); KeyString::TypeBits typeBits(keyString.getTypeBits()); KeyString::TypeBits::Reader typeBitsReader(typeBits); @@ -622,8 +577,7 @@ MaterializedRow MaterializedRow::deserializeFromKeyString( &reader, &typeBitsReader, false /* inverted */, typeBits.version, &valBuilder); } while (keepReading); - size_t sizeOfRow = numPrefixValsToRead ? *numPrefixValsToRead : valBuilder.numValues(); - MaterializedRow result{sizeOfRow}; + MaterializedRow result{valBuilder.numValues()}; valBuilder.readValues(result); return result; |
