diff --git a/fdbclient/include/fdbclient/FDBTypes.h b/fdbclient/include/fdbclient/FDBTypes.h index ea728b8f724..c8792a6b857 100644 --- a/fdbclient/include/fdbclient/FDBTypes.h +++ b/fdbclient/include/fdbclient/FDBTypes.h @@ -455,10 +455,23 @@ struct KeyValueRef { KeyRef key; ValueRef value; KeyValueRef() {} + KeyValueRef(const KeyRef& key, const ValueRef& value) : key(key), value(value) {} - KeyValueRef(Arena& a, const KeyValueRef& copyFrom) : key(a, copyFrom.key), value(a, copyFrom.value) {} + + KeyValueRef(Arena& a, const KeyRef& key, const ValueRef& value) { + StringRef storage = makeString(key.size() + value.size(), a); + uint8_t* dst = mutateString(storage); + + key.copyTo(dst); + value.copyTo(dst + key.size()); + + this->key = KeyRef(storage.begin(), key.size()); + this->value = ValueRef(storage.begin() + key.size(), value.size()); + } + + KeyValueRef(Arena& a, const KeyValueRef& copyFrom) : KeyValueRef(a, copyFrom.key, copyFrom.value) {} + bool operator==(const KeyValueRef& r) const { return key == r.key && value == r.value; } - bool operator!=(const KeyValueRef& r) const { return key != r.key || value != r.value; } int expectedSize() const { return key.expectedSize() + value.expectedSize(); } diff --git a/fdbserver/kvstore/KeyValueStoreRocksDB.actor.cpp b/fdbserver/kvstore/KeyValueStoreRocksDB.actor.cpp index 43619e1f456..da6b9c06160 100644 --- a/fdbserver/kvstore/KeyValueStoreRocksDB.actor.cpp +++ b/fdbserver/kvstore/KeyValueStoreRocksDB.actor.cpp @@ -1916,9 +1916,11 @@ struct RocksDBKeyValueStore : IKeyValueStore { auto cursor = readIter.iter; cursor->Seek(toSlice(a.keys.begin)); while (cursor->Valid() && toStringRef(cursor->key()) < a.keys.end) { - KeyValueRef kv(toStringRef(cursor->key()), toStringRef(cursor->value())); - accumulatedBytes += sizeof(KeyValueRef) + kv.expectedSize(); - result.push_back_deep(result.arena(), kv); + KeyRef key = toStringRef(cursor->key()); + ValueRef value = toStringRef(cursor->value()); + + accumulatedBytes += sizeof(KeyValueRef) + key.expectedSize() + value.expectedSize(); + result.emplace_back_deep(result.arena(), key, value); // Calling `cursor->Next()` is potentially expensive, so short-circut here just in case. if (result.size() >= a.rowLimit || accumulatedBytes >= a.byteLimit) { break; @@ -1949,9 +1951,11 @@ struct RocksDBKeyValueStore : IKeyValueStore { cursor->Prev(); } while (cursor->Valid() && toStringRef(cursor->key()) >= a.keys.begin) { - KeyValueRef kv(toStringRef(cursor->key()), toStringRef(cursor->value())); - accumulatedBytes += sizeof(KeyValueRef) + kv.expectedSize(); - result.push_back_deep(result.arena(), kv); + KeyRef key = toStringRef(cursor->key()); + ValueRef value = toStringRef(cursor->value()); + + accumulatedBytes += sizeof(KeyValueRef) + key.expectedSize() + value.expectedSize(); + result.emplace_back_deep(result.arena(), key, value); // Calling `cursor->Prev()` is potentially expensive, so short-circut here just in case. if (result.size() >= -a.rowLimit || accumulatedBytes >= a.byteLimit) { break; diff --git a/fdbserver/kvstore/KeyValueStoreShardedRocksDB.actor.cpp b/fdbserver/kvstore/KeyValueStoreShardedRocksDB.actor.cpp index 4e0e98fdaf2..890d71351c3 100644 --- a/fdbserver/kvstore/KeyValueStoreShardedRocksDB.actor.cpp +++ b/fdbserver/kvstore/KeyValueStoreShardedRocksDB.actor.cpp @@ -1111,9 +1111,11 @@ int readRangeInDb(PhysicalShard* shard, auto* cursor = readIter->iter.get(); cursor->Seek(toSlice(range.begin)); while (cursor->Valid() && toStringRef(cursor->key()) < range.end) { - KeyValueRef kv(toStringRef(cursor->key()), toStringRef(cursor->value())); - accumulatedBytes += sizeof(KeyValueRef) + kv.expectedSize(); - result->push_back_deep(result->arena(), kv); + KeyRef key = toStringRef(cursor->key()); + ValueRef value = toStringRef(cursor->value()); + + accumulatedBytes += sizeof(KeyValueRef) + key.expectedSize() + value.expectedSize(); + result->emplace_back_deep(result->arena(), key, value); // Calling `cursor->Next()` is potentially expensive, so short-circut here just in case. if (result->size() >= rowLimit || accumulatedBytes >= byteLimit) { break; @@ -1128,9 +1130,11 @@ int readRangeInDb(PhysicalShard* shard, cursor->Prev(); } while (cursor->Valid() && toStringRef(cursor->key()) >= range.begin) { - KeyValueRef kv(toStringRef(cursor->key()), toStringRef(cursor->value())); - accumulatedBytes += sizeof(KeyValueRef) + kv.expectedSize(); - result->push_back_deep(result->arena(), kv); + KeyRef key = toStringRef(cursor->key()); + ValueRef value = toStringRef(cursor->value()); + + accumulatedBytes += sizeof(KeyValueRef) + key.expectedSize() + value.expectedSize(); + result->emplace_back_deep(result->arena(), key, value); // Calling `cursor->Prev()` is potentially expensive, so short-circuit here just in case. if (result->size() >= -rowLimit || accumulatedBytes >= byteLimit) { break;