Skip to content

Commit c33abed

Browse files
louiswilliamsevergreen
authored andcommitted
SERVER-42526 IndexBuildInterceptor should store KeyString keys
1 parent a3014fa commit c33abed

File tree

2 files changed

+49
-28
lines changed

2 files changed

+49
-28
lines changed

src/mongo/db/index/index_build_interceptor.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,20 @@ Status IndexBuildInterceptor::_applyWrite(OperationContext* opCtx,
247247
const InsertDeleteOptions& options,
248248
int64_t* const keysInserted,
249249
int64_t* const keysDeleted) {
250-
const BSONObj key = operation["key"].Obj();
251-
const RecordId opRecordId = RecordId(operation["recordId"].Long());
250+
// Deserialize the encoded KeyString::Value.
251+
int keyLen;
252+
const char* binKey = operation["key"].binData(keyLen);
253+
BufReader reader(binKey, keyLen);
254+
const KeyString::Value keyString = KeyString::Value::deserialize(
255+
reader,
256+
_indexCatalogEntry->accessMethod()->getSortedDataInterface()->getKeyStringVersion());
257+
252258
const Op opType =
253259
(strcmp(operation.getStringField("op"), "i") == 0) ? Op::kInsert : Op::kDelete;
254260

255-
KeyString::HeapBuilder keyString(
256-
_indexCatalogEntry->accessMethod()->getSortedDataInterface()->getKeyStringVersion(),
257-
key,
258-
_indexCatalogEntry->ordering(),
259-
opRecordId);
260-
const KeyStringSet keySet{keyString.release()};
261+
const KeyStringSet keySet{keyString};
262+
const RecordId opRecordId =
263+
KeyString::decodeRecordIdAtEnd(keyString.getBuffer(), keyString.getSize());
261264

262265
auto accessMethod = _indexCatalogEntry->accessMethod();
263266
if (opType == Op::kInsert) {
@@ -398,29 +401,36 @@ Status IndexBuildInterceptor::sideWrite(OperationContext* opCtx,
398401
return Status::OK();
399402
}
400403

404+
// Reuse the same builder to avoid an allocation per key.
405+
BufBuilder builder;
401406
std::vector<BSONObj> toInsert;
402407
for (const auto& keyString : keys) {
403408
// Documents inserted into this table must be consumed in insert-order.
404409
// Additionally, these writes should be timestamped with the same timestamps that the
405410
// other writes making up this operation are given. When index builds can cope with
406411
// replication rollbacks, side table writes associated with a CUD operation should
407412
// remain/rollback along with the corresponding oplog entry.
408-
auto key = KeyString::toBson(keyString, _indexCatalogEntry->ordering());
409-
toInsert.emplace_back(BSON("op" << (op == Op::kInsert ? "i" : "d") << "key" << key
410-
<< "recordId" << loc.repr()));
413+
414+
// Serialize the KeyString::Value into a binary format for storage. Since the
415+
// KeyString::Value also contains TypeBits information, it is not sufficient to just read
416+
// from getBuffer().
417+
builder.reset();
418+
keyString.serialize(builder);
419+
BSONBinData binData(builder.buf(), builder.getSize(), BinDataGeneral);
420+
toInsert.emplace_back(BSON("op" << (op == Op::kInsert ? "i" : "d") << "key" << binData));
411421
}
412422

413423
if (op == Op::kInsert) {
414424
// Wildcard indexes write multikey path information, typically part of the catalog
415425
// document, to the index itself. Multikey information is never deleted, so we only need
416426
// to add this data on the insert path.
417427
for (const auto& keyString : multikeyMetadataKeys) {
418-
auto key = KeyString::toBson(keyString, _indexCatalogEntry->ordering());
428+
builder.reset();
429+
keyString.serialize(builder);
430+
BSONBinData binData(builder.buf(), builder.getSize(), BinDataGeneral);
419431
toInsert.emplace_back(BSON("op"
420432
<< "i"
421-
<< "key" << key << "recordId"
422-
<< static_cast<int64_t>(
423-
RecordId::ReservedId::kWildcardMultikeyMetadataId)));
433+
<< "key" << binData));
424434
}
425435
}
426436

src/mongo/db/storage/key_string.h

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -347,32 +347,43 @@ class Value {
347347
*/
348348
std::string toString() const;
349349

350-
/// Members for Sorter
351-
struct SorterDeserializeSettings {
352-
SorterDeserializeSettings(Version version) : keyStringVersion(version) {}
353-
Version keyStringVersion;
354-
};
355-
356-
void serializeForSorter(BufBuilder& buf) const {
357-
buf.appendNum(_ksSize); // Serialize size of Keystring
358-
buf.appendBuf(_buffer.get(), _ksSize); // Serialize Keystring
359-
buf.appendBuf(_buffer.get() + _ksSize, _bufSize - _ksSize); // Serialize Typebits
350+
// Serializes this Value into a storable format with TypeBits information. The serialized
351+
// format takes the following form:
352+
// [keystring size][keystring encoding][typebits encoding]
353+
void serialize(BufBuilder& buf) const {
354+
buf.appendNum(_ksSize); // Serialize size of Keystring
355+
buf.appendBuf(_buffer.get(), _bufSize); // Serialize Keystring + Typebits
360356
}
361357

362-
static Value deserializeForSorter(BufReader& buf, const SorterDeserializeSettings& settings) {
358+
// Deserialize the Value from a serialized format.
359+
static Value deserialize(BufReader& buf, KeyString::Version version) {
363360
const int32_t sizeOfKeystring = buf.read<LittleEndian<int32_t>>();
364361
const void* keystringPtr = buf.skip(sizeOfKeystring);
365362

366363
BufBuilder newBuf;
367364
newBuf.appendBuf(keystringPtr, sizeOfKeystring);
368365

369-
auto typeBits = TypeBits::fromBuffer(settings.keyStringVersion, &buf); // advances the buf
366+
auto typeBits = TypeBits::fromBuffer(version, &buf); // advances the buf
370367
if (typeBits.isAllZeros()) {
371368
newBuf.appendChar(0);
372369
} else {
373370
newBuf.appendBuf(typeBits.getBuffer(), typeBits.getSize());
374371
}
375-
return {settings.keyStringVersion, sizeOfKeystring, newBuf.len(), newBuf.release()};
372+
return {version, sizeOfKeystring, newBuf.len(), newBuf.release()};
373+
}
374+
375+
/// Members for Sorter
376+
struct SorterDeserializeSettings {
377+
SorterDeserializeSettings(Version version) : keyStringVersion(version) {}
378+
Version keyStringVersion;
379+
};
380+
381+
void serializeForSorter(BufBuilder& buf) const {
382+
serialize(buf);
383+
}
384+
385+
static Value deserializeForSorter(BufReader& buf, const SorterDeserializeSettings& settings) {
386+
return deserialize(buf, settings.keyStringVersion);
376387
}
377388

378389
int memUsageForSorter() const {

0 commit comments

Comments
 (0)