summaryrefslogtreecommitdiff
path: root/src/mongo/bson/util
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/bson/util
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (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.cpp21
-rw-r--r--src/mongo/bson/util/bsoncolumn.h7
-rw-r--r--src/mongo/bson/util/bsoncolumn_test.cpp191
-rw-r--r--src/mongo/bson/util/bsoncolumn_util.h9
-rw-r--r--src/mongo/bson/util/builder.h10
-rw-r--r--src/mongo/bson/util/simple8b.cpp9
-rw-r--r--src/mongo/bson/util/simple8b_test.cpp34
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);
-}