diff options
author | Louis Williams <louis.williams@mongodb.com> | 2019-08-29 19:13:50 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-08-29 19:13:50 +0000 |
commit | c33abedcb7bd3a4c116e350d70be29f3fd4acd45 (patch) | |
tree | 7bf691d53c8ff842e855c6b3c7a2d3ea2e1c6bc5 /src/mongo | |
parent | a3014fa23e0123c3ac42b4d8e295c4f93600c685 (diff) | |
download | mongo-c33abedcb7bd3a4c116e350d70be29f3fd4acd45.tar.gz |
SERVER-42526 IndexBuildInterceptor should store KeyString keys
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/index/index_build_interceptor.cpp | 40 | ||||
-rw-r--r-- | src/mongo/db/storage/key_string.h | 37 |
2 files changed, 49 insertions, 28 deletions
diff --git a/src/mongo/db/index/index_build_interceptor.cpp b/src/mongo/db/index/index_build_interceptor.cpp index 510f275ce7b..a6a53894d1b 100644 --- a/src/mongo/db/index/index_build_interceptor.cpp +++ b/src/mongo/db/index/index_build_interceptor.cpp @@ -247,17 +247,20 @@ Status IndexBuildInterceptor::_applyWrite(OperationContext* opCtx, const InsertDeleteOptions& options, int64_t* const keysInserted, int64_t* const keysDeleted) { - const BSONObj key = operation["key"].Obj(); - const RecordId opRecordId = RecordId(operation["recordId"].Long()); + // Deserialize the encoded KeyString::Value. + int keyLen; + const char* binKey = operation["key"].binData(keyLen); + BufReader reader(binKey, keyLen); + const KeyString::Value keyString = KeyString::Value::deserialize( + reader, + _indexCatalogEntry->accessMethod()->getSortedDataInterface()->getKeyStringVersion()); + const Op opType = (strcmp(operation.getStringField("op"), "i") == 0) ? Op::kInsert : Op::kDelete; - KeyString::HeapBuilder keyString( - _indexCatalogEntry->accessMethod()->getSortedDataInterface()->getKeyStringVersion(), - key, - _indexCatalogEntry->ordering(), - opRecordId); - const KeyStringSet keySet{keyString.release()}; + const KeyStringSet keySet{keyString}; + const RecordId opRecordId = + KeyString::decodeRecordIdAtEnd(keyString.getBuffer(), keyString.getSize()); auto accessMethod = _indexCatalogEntry->accessMethod(); if (opType == Op::kInsert) { @@ -398,6 +401,8 @@ Status IndexBuildInterceptor::sideWrite(OperationContext* opCtx, return Status::OK(); } + // Reuse the same builder to avoid an allocation per key. + BufBuilder builder; std::vector<BSONObj> toInsert; for (const auto& keyString : keys) { // Documents inserted into this table must be consumed in insert-order. @@ -405,9 +410,14 @@ Status IndexBuildInterceptor::sideWrite(OperationContext* opCtx, // other writes making up this operation are given. When index builds can cope with // replication rollbacks, side table writes associated with a CUD operation should // remain/rollback along with the corresponding oplog entry. - auto key = KeyString::toBson(keyString, _indexCatalogEntry->ordering()); - toInsert.emplace_back(BSON("op" << (op == Op::kInsert ? "i" : "d") << "key" << key - << "recordId" << loc.repr())); + + // Serialize the KeyString::Value into a binary format for storage. Since the + // KeyString::Value also contains TypeBits information, it is not sufficient to just read + // from getBuffer(). + builder.reset(); + keyString.serialize(builder); + BSONBinData binData(builder.buf(), builder.getSize(), BinDataGeneral); + toInsert.emplace_back(BSON("op" << (op == Op::kInsert ? "i" : "d") << "key" << binData)); } if (op == Op::kInsert) { @@ -415,12 +425,12 @@ Status IndexBuildInterceptor::sideWrite(OperationContext* opCtx, // document, to the index itself. Multikey information is never deleted, so we only need // to add this data on the insert path. for (const auto& keyString : multikeyMetadataKeys) { - auto key = KeyString::toBson(keyString, _indexCatalogEntry->ordering()); + builder.reset(); + keyString.serialize(builder); + BSONBinData binData(builder.buf(), builder.getSize(), BinDataGeneral); toInsert.emplace_back(BSON("op" << "i" - << "key" << key << "recordId" - << static_cast<int64_t>( - RecordId::ReservedId::kWildcardMultikeyMetadataId))); + << "key" << binData)); } } diff --git a/src/mongo/db/storage/key_string.h b/src/mongo/db/storage/key_string.h index 404f4d9a30c..74fd5fd4d91 100644 --- a/src/mongo/db/storage/key_string.h +++ b/src/mongo/db/storage/key_string.h @@ -347,32 +347,43 @@ public: */ std::string toString() const; - /// Members for Sorter - struct SorterDeserializeSettings { - SorterDeserializeSettings(Version version) : keyStringVersion(version) {} - Version keyStringVersion; - }; - - void serializeForSorter(BufBuilder& buf) const { - buf.appendNum(_ksSize); // Serialize size of Keystring - buf.appendBuf(_buffer.get(), _ksSize); // Serialize Keystring - buf.appendBuf(_buffer.get() + _ksSize, _bufSize - _ksSize); // Serialize Typebits + // Serializes this Value into a storable format with TypeBits information. The serialized + // format takes the following form: + // [keystring size][keystring encoding][typebits encoding] + void serialize(BufBuilder& buf) const { + buf.appendNum(_ksSize); // Serialize size of Keystring + buf.appendBuf(_buffer.get(), _bufSize); // Serialize Keystring + Typebits } - static Value deserializeForSorter(BufReader& buf, const SorterDeserializeSettings& settings) { + // Deserialize the Value from a serialized format. + static Value deserialize(BufReader& buf, KeyString::Version version) { const int32_t sizeOfKeystring = buf.read<LittleEndian<int32_t>>(); const void* keystringPtr = buf.skip(sizeOfKeystring); BufBuilder newBuf; newBuf.appendBuf(keystringPtr, sizeOfKeystring); - auto typeBits = TypeBits::fromBuffer(settings.keyStringVersion, &buf); // advances the buf + auto typeBits = TypeBits::fromBuffer(version, &buf); // advances the buf if (typeBits.isAllZeros()) { newBuf.appendChar(0); } else { newBuf.appendBuf(typeBits.getBuffer(), typeBits.getSize()); } - return {settings.keyStringVersion, sizeOfKeystring, newBuf.len(), newBuf.release()}; + return {version, sizeOfKeystring, newBuf.len(), newBuf.release()}; + } + + /// Members for Sorter + struct SorterDeserializeSettings { + SorterDeserializeSettings(Version version) : keyStringVersion(version) {} + Version keyStringVersion; + }; + + void serializeForSorter(BufBuilder& buf) const { + serialize(buf); + } + + static Value deserializeForSorter(BufReader& buf, const SorterDeserializeSettings& settings) { + return deserialize(buf, settings.keyStringVersion); } int memUsageForSorter() const { |