diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
| commit | 4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch) | |
| tree | 1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/bson/util | |
| parent | aa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff) | |
| parent | 8f0827553e09872941945a093b647a4211a9db7f (diff) | |
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0'
with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'src/mongo/bson/util')
| -rw-r--r-- | src/mongo/bson/util/bsoncolumn.cpp | 21 | ||||
| -rw-r--r-- | src/mongo/bson/util/bsoncolumn.h | 7 | ||||
| -rw-r--r-- | src/mongo/bson/util/bsoncolumn_test.cpp | 191 | ||||
| -rw-r--r-- | src/mongo/bson/util/bsoncolumn_util.h | 9 | ||||
| -rw-r--r-- | src/mongo/bson/util/builder.h | 10 | ||||
| -rw-r--r-- | src/mongo/bson/util/simple8b.cpp | 9 | ||||
| -rw-r--r-- | src/mongo/bson/util/simple8b_test.cpp | 34 |
7 files changed, 21 insertions, 260 deletions
diff --git a/src/mongo/bson/util/bsoncolumn.cpp b/src/mongo/bson/util/bsoncolumn.cpp index df2d74b5b0f..aa81339f9aa 100644 --- a/src/mongo/bson/util/bsoncolumn.cpp +++ b/src/mongo/bson/util/bsoncolumn.cpp @@ -157,11 +157,11 @@ BSONColumn::ElementStorage::ContiguousBlock::~ContiguousBlock() { } } -std::pair<const char*, int> BSONColumn::ElementStorage::ContiguousBlock::done() { +const char* BSONColumn::ElementStorage::ContiguousBlock::done() { auto ptr = _storage.contiguous(); - int size = _storage._endContiguous(); + _storage._endContiguous(); _finished = true; - return std::make_pair(ptr, size); + return ptr; } char* BSONColumn::ElementStorage::allocate(int bytes) { @@ -211,9 +211,8 @@ void BSONColumn::ElementStorage::_beginContiguous() { _contiguousEnabled = true; } -int BSONColumn::ElementStorage::_endContiguous() { +void BSONColumn::ElementStorage::_endContiguous() { _contiguousEnabled = false; - return _pos - _contiguousPos; } BSONColumn::ElementStorage::Element BSONColumn::ElementStorage::allocate(BSONType type, @@ -523,12 +522,12 @@ void BSONColumn::Iterator::_incrementInterleaved() { } // Store built BSONObj in the decompressed list - auto [objdata, objsize] = contiguous.done(); - BSONElement obj; + const char* objdata = contiguous.done(); + BSONElement obj(objdata); - // If no data was added, use a EOO literal. As buffer size is 0 we cannot interpret it as BSON. - if (objsize > 0) { - obj = BSONElement(objdata); + // If no data was added, use a EOO literal instead of an empty object. + if (obj.objsize() == 0) { + obj = BSONElement(); } _column->_decompressed.emplace_back(obj); @@ -541,7 +540,7 @@ void BSONColumn::Iterator::_handleEOO() { } bool BSONColumn::Iterator::_isLiteral(char control) { - return (control & 0xE0) == 0 || control == (char)MinKey || control == (char)MaxKey; + return (control & 0xE0) == 0; } bool BSONColumn::Iterator::_isInterleavedStart(char control) { diff --git a/src/mongo/bson/util/bsoncolumn.h b/src/mongo/bson/util/bsoncolumn.h index 9bfee3e76cf..23d4b19c7b5 100644 --- a/src/mongo/bson/util/bsoncolumn.h +++ b/src/mongo/bson/util/bsoncolumn.h @@ -307,8 +307,7 @@ private: ContiguousBlock(ElementStorage& storage); ~ContiguousBlock(); - // Return pointer to contigous block and the block size - std::pair<const char*, int> done(); + const char* done(); private: ElementStorage& _storage; @@ -360,8 +359,8 @@ private: // Starts contiguous mode void _beginContiguous(); - // Ends contiguous mode, returns size of block - int _endContiguous(); + // Ends contiguous mode + void _endContiguous(); // Full memory blocks that are kept alive. std::vector<std::unique_ptr<char[]>> _blocks; diff --git a/src/mongo/bson/util/bsoncolumn_test.cpp b/src/mongo/bson/util/bsoncolumn_test.cpp index a2ef0b2feae..0fe621fbd30 100644 --- a/src/mongo/bson/util/bsoncolumn_test.cpp +++ b/src/mongo/bson/util/bsoncolumn_test.cpp @@ -4967,43 +4967,6 @@ TEST_F(BSONColumnTest, ObjectWithOnlyEmptyObjsDoesNotStartInterleavingFromAppend test(true, appendInterleavedStart); } -TEST_F(BSONColumnTest, InterleavedFullSkipAfterObjectSkip) { - BSONColumnBuilder cb("test"_sd, true); - - // This test makes sure we're not leaking the skip from the 'yyyyyy' field into the next - // measurement. 'yyyyyy' will be written into the buffer for the second item before we realize - // that it only contain skips. We must not attempt to interpret this memory when the next - // measurement is all skips. - std::vector<BSONElement> elems = { - createElementObj(BSON("x" << 1 << "yyyyyy" << BSON("z" << 2))), - createElementObj(BSON("x" << 1)), - BSONElement()}; - - for (auto elem : elems) { - if (!elem.eoo()) - cb.append(elem); - else - cb.skip(); - } - - BufBuilder expected; - appendInterleavedStart(expected, elems.front().Obj()); - appendSimple8bControl(expected, 0b1000, 0b0000); - appendSimple8bBlocks64(expected, - {kDeltaForBinaryEqualValues, - deltaInt32(elems[1].Obj()["x"_sd], elems[0].Obj()["x"_sd]), - boost::none}, - 1); - appendSimple8bControl(expected, 0b1000, 0b0000); - appendSimple8bBlocks64(expected, {kDeltaForBinaryEqualValues, boost::none, boost::none}, 1); - appendEOO(expected); - appendEOO(expected); - - auto binData = cb.finalize(); - verifyBinary(binData, expected); - verifyDecompression(binData, elems); -} - TEST_F(BSONColumnTest, NonZeroRLEInFirstBlockAfterSimple8bBlocks) { BSONColumnBuilder cb("test"_sd); @@ -5337,160 +5300,6 @@ TEST_F(BSONColumnTest, AppendMinKeyInSubObjAfterMerge) { cb.append(createElementObj(obj.obj())), DBException, ErrorCodes::InvalidBSONType); } -TEST_F(BSONColumnTest, DecompressMinKey) { - BufBuilder expected; - appendLiteral(expected, createElementMinKey()); - appendEOO(expected); - - BSONBinData binData; - binData.data = expected.buf(); - binData.length = expected.len(); - binData.type = Column; - - verifyDecompression(binData, {createElementMinKey()}); -} - -TEST_F(BSONColumnTest, DecompressMaxKey) { - BufBuilder expected; - appendLiteral(expected, createElementMaxKey()); - appendEOO(expected); - - BSONBinData binData; - binData.data = expected.buf(); - binData.length = expected.len(); - binData.type = Column; - - verifyDecompression(binData, {createElementMaxKey()}); -} - -TEST_F(BSONColumnTest, DecompressMinKeyInSubObj) { - BSONObjBuilder obj; - { - BSONObjBuilder builder = obj.subobjStart("root"); - builder.append(createElementMinKey()); - } - - BSONObj ref = obj.obj(); - - BufBuilder expected; - appendInterleavedStart(expected, ref); - appendSimple8bControl(expected, 0b1000, 0b0000); - appendSimple8bBlocks64(expected, {kDeltaForBinaryEqualValues}, 1); - appendEOO(expected); - appendEOO(expected); - - BSONBinData binData; - binData.data = expected.buf(); - binData.length = expected.len(); - binData.type = Column; - - verifyDecompression(binData, {createElementObj(ref)}); -} - -TEST_F(BSONColumnTest, DecompressMinKeyInSubObjAfterInterleaveStart) { - - BSONObjBuilder obj; - { - BSONObjBuilder builder = obj.subobjStart("root"); - builder.append(createElementMinKey()); - } - - std::vector<BSONElement> elems = {createElementObj(BSON("root" << BSON("0" << 1))), - createElementObj(obj.obj())}; - - BufBuilder expected; - appendInterleavedStart(expected, elems[0].Obj()); - appendSimple8bControl(expected, 0b1000, 0b0000); - appendSimple8bBlocks64(expected, {kDeltaForBinaryEqualValues}, 1); - appendLiteral(expected, createElementMinKey()); - appendEOO(expected); - appendEOO(expected); - - BSONBinData binData; - binData.data = expected.buf(); - binData.length = expected.len(); - binData.type = Column; - - verifyDecompression(binData, elems); -} - -TEST_F(BSONColumnTest, DecompressMinKeyInSubObjAfterInterleaveStartInAppendMode) { - BSONObjBuilder obj; - { - BSONObjBuilder builder = obj.subobjStart("root"); - builder.append(createElementMinKey()); - } - - std::vector<BSONElement> elems(7, createElementObj(BSON("root" << BSON("0" << 1)))); - elems.push_back(createElementObj(obj.obj())); - - BufBuilder expected; - appendInterleavedStart(expected, elems[0].Obj()); - appendSimple8bControl(expected, 0b1000, 0b0000); - appendSimple8bBlocks64(expected, - {kDeltaForBinaryEqualValues, - kDeltaForBinaryEqualValues, - kDeltaForBinaryEqualValues, - kDeltaForBinaryEqualValues, - kDeltaForBinaryEqualValues, - kDeltaForBinaryEqualValues, - kDeltaForBinaryEqualValues}, - 1); - appendLiteral(expected, createElementMinKey()); - appendEOO(expected); - appendEOO(expected); - - BSONBinData binData; - binData.data = expected.buf(); - binData.length = expected.len(); - binData.type = Column; - - verifyDecompression(binData, elems); -} - -TEST_F(BSONColumnTest, DecompressMinKeyInSubObjAfterMerge) { - BSONObjBuilder obj; - { - BSONObjBuilder builder = obj.subobjStart("root"); - builder.append("a", "asd"); - builder.append(createElementMinKey()); - } - - // Make sure we handle MinKey even if we would detect that "a" needs to be merged before - // observing the MinKey. - std::vector<BSONElement> elems = {createElementObj(BSON("root" << BSON("0" << 1))), - createElementObj(obj.obj())}; - - BufBuilder expected; - appendInterleavedStart(expected, - BSON("root" << BSON("a" - << "asd" - << "0" << 1))); - appendSimple8bControl(expected, 0b1000, 0b0000); - appendSimple8bBlocks64(expected, - { - boost::none, - kDeltaForBinaryEqualValues, - }, - 1); - appendSimple8bControl(expected, 0b1000, 0b0000); - appendSimple8bBlocks64(expected, - { - kDeltaForBinaryEqualValues, - }, - 1); - appendLiteral(expected, createElementMinKey()); - appendEOO(expected); - appendEOO(expected); - - BSONBinData binData; - binData.data = expected.buf(); - binData.length = expected.len(); - binData.type = Column; - - verifyDecompression(binData, elems); -} - // The large literal emits this on Visual Studio: Fatal error C1091: compiler limit: string exceeds // 65535 bytes in length #if !defined(_MSC_VER) || _MSC_VER >= 1929 diff --git a/src/mongo/bson/util/bsoncolumn_util.h b/src/mongo/bson/util/bsoncolumn_util.h index 5b3110a13c9..9d9eec07e8e 100644 --- a/src/mongo/bson/util/bsoncolumn_util.h +++ b/src/mongo/bson/util/bsoncolumn_util.h @@ -37,15 +37,6 @@ static constexpr char kInterleavedStartControlByteLegacy = (char)0xF0; static constexpr char kInterleavedStartControlByte = (char)0xF1; static constexpr char kInterleavedStartArrayRootControlByte = (char)0xF2; -inline bool isUncompressedLiteralControlByte(uint8_t control) { - return (control & 0xE0) == 0 || control == (uint8_t)MinKey || control == (uint8_t)MaxKey; -} - -inline bool isInterleavedStartControlByte(char control) { - return control == kInterleavedStartControlByteLegacy || - control == kInterleavedStartControlByte || control == kInterleavedStartArrayRootControlByte; -} - inline bool isLiteralControlByte(char control) { return (control & 0xE0) == 0; } diff --git a/src/mongo/bson/util/builder.h b/src/mongo/bson/util/builder.h index c3fc7facf26..5d7d2d5673c 100644 --- a/src/mongo/bson/util/builder.h +++ b/src/mongo/bson/util/builder.h @@ -325,7 +325,7 @@ public: @return point to region that was skipped. pointer may change later (on realloc), so for immediate use only */ - char* skip(size_t n) { + char* skip(int n) { return grow(n); } @@ -394,7 +394,7 @@ public: } void appendBuf(const void* src, size_t len) { if (len) - memcpy(grow(len), src, len); + memcpy(grow((int)len), src, len); } template <class T> @@ -403,7 +403,7 @@ public: } void appendStr(StringData str, bool includeEndingNull = true) { - const size_t len = str.size() + (includeEndingNull ? 1 : 0); + const int len = str.size() + (includeEndingNull ? 1 : 0); str.copyTo(grow(len), includeEndingNull); } @@ -423,8 +423,8 @@ public: } /* returns the pre-grow write position */ - char* grow(size_t by) { - if (MONGO_likely(by <= static_cast<size_t>(_end - _nextByte))) { + char* grow(int by) { + if (MONGO_likely(by <= _end - _nextByte)) { char* oldNextByte = _nextByte; _nextByte += by; return oldNextByte; diff --git a/src/mongo/bson/util/simple8b.cpp b/src/mongo/bson/util/simple8b.cpp index 264e999b8a2..2efa9484cd3 100644 --- a/src/mongo/bson/util/simple8b.cpp +++ b/src/mongo/bson/util/simple8b.cpp @@ -130,9 +130,9 @@ constexpr std::array<uint8_t, 15> kBaseSelectorToShiftSize = { // Transfer from a selector to a specific extension type // This is for selector 7 and 8 extensions where the selector value is passed along with // selector index. -constexpr std::array<std::array<uint8_t, 16>, 2> kSelectorToExtension = { - std::array<uint8_t, 16>{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, - std::array<uint8_t, 16>{0, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 0, 0}}; +constexpr std::array<std::array<uint8_t, 14>, 2> kSelectorToExtension = { + std::array<uint8_t, 14>{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + std::array<uint8_t, 14>{0, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3}}; // Transfer from a extensionType and selectorIdx to the selector value to be held in the 4 lsb (base // selector) @@ -614,9 +614,6 @@ void Simple8bBuilder<T>::_handleRleTermination() { } --_rleCount; } - - // Reset which selectors are possible to use for next word - isSelectorPossible.fill(true); } template <typename T> diff --git a/src/mongo/bson/util/simple8b_test.cpp b/src/mongo/bson/util/simple8b_test.cpp index df8c849f73b..6ef1866f855 100644 --- a/src/mongo/bson/util/simple8b_test.cpp +++ b/src/mongo/bson/util/simple8b_test.cpp @@ -1407,37 +1407,3 @@ TEST(Simple8b, ValueTooLargeBitCountUsedForExtendedSelectors) { }); ASSERT_FALSE(builder.append(value)); } - -TEST(Simple8b, ResetRLEAfterLargeValue) { - uint8_t kRleMultiplier = 120; - uint8_t kBaseSelectorMask = 0x000000000000000F; - uint8_t kRleSelector = 15; - // Large value that can be only be stored in the extended selectors that encodes a bit shift - uint64_t large = 0xC000000000000000; - - BufBuilder buf; - Simple8bBuilder<uint64_t> b([&buf](uint64_t simple8bBlock) { - buf.appendNum(simple8bBlock); - return true; - }); - - // Write as many of these large values we need to ensure a non-RLE block is written followed by - // an RLE block. - for (int i = 0; i < kRleMultiplier + 7; ++i) { - ASSERT_TRUE(b.append(large)); - } - - // Add a large value that can only fit in the base selector which can encode up to 60 meaningful - // bits. When terminating RLE we should completely reset to allow this value to be appended. - ASSERT_TRUE(b.append(0x07FFFFFFFFFFFFFF)); - - b.flush(); - auto size = buf.len(); - auto data = buf.release(); - - // The second block should be an RLE block - ASSERT_GT(size, 16); - uint64_t secondBlock = - ConstDataView(data.get() + sizeof(uint64_t)).read<LittleEndian<uint64_t>>(); - ASSERT_TRUE((secondBlock & kBaseSelectorMask) == kRleSelector); -} |
