summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2019-08-29 19:13:50 +0000
committerevergreen <evergreen@mongodb.com>2019-08-29 19:13:50 +0000
commitc33abedcb7bd3a4c116e350d70be29f3fd4acd45 (patch)
tree7bf691d53c8ff842e855c6b3c7a2d3ea2e1c6bc5 /src/mongo
parenta3014fa23e0123c3ac42b4d8e295c4f93600c685 (diff)
downloadmongo-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.cpp40
-rw-r--r--src/mongo/db/storage/key_string.h37
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 {