diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-14 14:26:38 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-14 14:26:38 -0300 |
| commit | 294bc6ecabf14c09c9bc8644704921dcf97cb44e (patch) | |
| tree | 279b1e0bab53901a1647ac63c1c724f0f789a663 /src/mongo/db/exec/document_value/document.h | |
| parent | 70be7c27a251621187a1de533462ae2bb1e3bd39 (diff) | |
| parent | 1e917fd798aa25b7066d4b414b51184f13d5a092 (diff) | |
Update upstream source from tag 'upstream/6.0.10'debian/6.0.10-1
Update to upstream version '6.0.10'
with Debian dir 2d176fa254eee97b139f712fec5709641335a8c3
Diffstat (limited to 'src/mongo/db/exec/document_value/document.h')
| -rw-r--r-- | src/mongo/db/exec/document_value/document.h | 93 |
1 files changed, 71 insertions, 22 deletions
diff --git a/src/mongo/db/exec/document_value/document.h b/src/mongo/db/exec/document_value/document.h index 8fcfb28dd8b..062778628a0 100644 --- a/src/mongo/db/exec/document_value/document.h +++ b/src/mongo/db/exec/document_value/document.h @@ -100,7 +100,9 @@ public: static constexpr StringData metaFieldSearchScore = "$searchScore"_sd; static constexpr StringData metaFieldSearchHighlights = "$searchHighlights"_sd; static constexpr StringData metaFieldSearchScoreDetails = "$searchScoreDetails"_sd; + static constexpr StringData metaFieldSearchSortValues = "$searchSortValues"_sd; static constexpr StringData metaFieldIndexKey = "$indexKey"_sd; + static constexpr StringData metaFieldVectorSearchScore = "$vectorSearchScore"_sd; static const StringDataSet allMetadataFieldNames; @@ -191,7 +193,8 @@ public: /** * Get the approximate size of the Document, plus its underlying storage and sub-values. Returns - * size in bytes. + * size in bytes. The return value of this function is snapshotted. All subsequent calls of this + * method will return the same value. * * Note: Some memory may be shared with other Documents or between fields within a single * Document so this can overestimate usage. @@ -202,6 +205,11 @@ public: size_t getApproximateSize() const; /** + * Same as 'getApproximateSize()', but this method re-computes the size on every call. + */ + size_t getCurrentApproximateSize() const; + + /** * Return the approximate amount of space used by metadata. */ size_t getMetadataApproximateSize() const { @@ -253,12 +261,38 @@ public: void hash_combine(size_t& seed, const StringData::ComparatorInterface* stringComparator) const; /** + * Returns true, if this document is trivially convertible to BSON, meaning the underlying + * storage is already in BSON format and there are no damages. + */ + bool isTriviallyConvertible() const { + return !storage().isModified() && !storage().bsonHasMetadata(); + } + + /** + * Returns true, if this document is trivially convertible to BSON with metadata, meaning the + * underlying storage is already in BSON format and there are no damages. + */ + bool isTriviallyConvertibleWithMetadata() const { + return !storage().isModified() && !storage().isMetadataModified(); + } + + /** * Serializes this document to the BSONObj under construction in 'builder'. Metadata is not * included. Throws a AssertionException if 'recursionLevel' exceeds the maximum allowable * depth. */ void toBson(BSONObjBuilder* builder, size_t recursionLevel = 1) const; - BSONObj toBson() const; + + template <typename BSONTraits = BSONObj::DefaultSizeTrait> + BSONObj toBson() const { + if (isTriviallyConvertible()) { + return storage().bsonObj(); + } + + BSONObjBuilder bb; + toBson(&bb); + return bb.obj<BSONTraits>(); + } /** * Serializes this document iff the conversion is "trivial," meaning that the underlying storage @@ -272,7 +306,18 @@ public: /** * Like the 'toBson()' method, but includes metadata as top-level fields. */ - BSONObj toBsonWithMetaData() const; + void toBsonWithMetaData(BSONObjBuilder* builder) const; + + template <typename BSONTraits = BSONObj::DefaultSizeTrait> + BSONObj toBsonWithMetaData() const { + if (isTriviallyConvertibleWithMetadata()) { + return storage().bsonObj(); + } + + BSONObjBuilder bb; + toBsonWithMetaData(&bb); + return bb.obj<BSONTraits>(); + } /** * Like Document(BSONObj) but treats top-level fields with special names as metadata. @@ -370,12 +415,6 @@ private: getNestedFieldNonCachingHelper(const FieldPath& dottedField, size_t level) const; boost::intrusive_ptr<const DocumentStorage> _storage; - - /** - * Returns the approximate size of this `Document` instance without considering the size of its - * backing BSON object. - */ - size_t getApproximateSizeWithoutBackingBSON() const; }; // @@ -511,13 +550,11 @@ public: } /** - * Replace the current base Document with bson. - * - * The paramater 'stripMetadata' controls whether we strip the metadata fields from the - * underlying bson when converting the document object back to bson. + * Replace the current base Document with the BSON object. Setting 'bsonHasMetadata' to true + * signals that the BSON object contains metadata fields. */ - void reset(const BSONObj& bson, bool stripMetadata) { - storage().reset(bson, stripMetadata); + void reset(const BSONObj& bson, bool bsonHasMetadata) { + storage().reset(bson, bsonHasMetadata); } /** Add the given field to the Document. @@ -654,6 +691,7 @@ public: * TODO: there are some optimizations that may make sense at freeze time. */ Document freeze() { + resetSnapshottedApproximateSize(); // This essentially moves _storage into a new Document by way of temp. Document ret; boost::intrusive_ptr<const DocumentStorage> temp(storagePtr(), /*inc_ref_count=*/false); @@ -672,8 +710,12 @@ public: * Note that unlike freeze(), this indicates intention to continue * modifying this document. The returned Document will not observe * future changes to this MutableDocument. + * + * Note that the computed snapshotted approximate size of the Document + * is not preserved across calls. */ Document peek() { + resetSnapshottedApproximateSize(); return Document(storagePtr()); } @@ -695,13 +737,13 @@ public: storage().makeOwned(); } - /** Create a new document storage with the BSON object. - * - * The optional paramater 'stripMetadata' controls whether we strip the metadata fields (the - * complete list is in Document::allMetadataFieldNames). + /** + * Creates a new document storage with the BSON object. Setting 'bsonHasMetadata' to true + * signals that the BSON object contains metadata fields (the complete list is in + * Document::allMetadataFieldNames). */ - DocumentStorage& newStorageWithBson(const BSONObj& bson, bool stripMetadata) { - reset(make_intrusive<DocumentStorage>(bson, stripMetadata, false, 0)); + DocumentStorage& newStorageWithBson(const BSONObj& bson, bool bsonHasMetadata) { + reset(make_intrusive<DocumentStorage>(bson, bsonHasMetadata, false, 0)); return const_cast<DocumentStorage&>(*storagePtr()); } @@ -739,12 +781,19 @@ private: MutableValue getNestedFieldHelper(const FieldPath& dottedField, size_t level); MutableValue getNestedFieldHelper(const std::vector<Position>& positions, size_t level); - // this should only be called by storage methods and peek/freeze + // this should only be called by storage methods and peek/freeze/resetsnapshottedApproximateSize const DocumentStorage* storagePtr() const { dassert(!_storage || typeid(*_storage) == typeid(const DocumentStorage)); return static_cast<const DocumentStorage*>(_storage); } + void resetSnapshottedApproximateSize() { + auto mutableStorage = const_cast<DocumentStorage*>(storagePtr()); + if (mutableStorage) { + mutableStorage->resetSnapshottedApproximateSize(); + } + } + // These are both const to prevent modifications bypassing storage() method. // They always point to NULL or an object with dynamic type DocumentStorage. const RefCountable* _storageHolder; // Only used in constructors and destructor |
