Description
KeyValueRef deep-copy construction currently performs two independent arena allocations for every returned key-value pair during RocksDB range iteration.
This occurs in the storage-server range read path, where every returned RocksDB key/value slice is materialized into a RangeResultRef using push_back_deep / emplace_back_deep.
For large range scans, this introduces unnecessary allocator overhead and additional allocation metadata traffic in the hot read path.
Root Cause
File paths:
fdbserver/kvstore/KeyValueStoreRocksDB.actor.cpp
fdbserver/kvstore/KeyValueStoreShardedRocksDB.actor.cpp
fdbclient/include/fdbclient/FDBTypes.h
Current range materialization path:
KeyValueRef kv(toStringRef(cursor->key()), toStringRef(cursor->value()));
result.push_back_deep(result.arena(), kv);
push_back_deep constructs:
KeyValueRef(Arena& a, const KeyValueRef& copyFrom)
: key(a, copyFrom.key), value(a, copyFrom.value) {}
which in turn performs two separate StringRef(Arena&, ...) allocations:
StringRef(Arena& p, const StringRef& toCopy)
: data(new(p) uint8_t[toCopy.size()]), length(toCopy.size()) {
memcpy((void*)data, toCopy.data, length);
}
As a result, every returned KV pair performs:
- one allocation for the key payload,
- one allocation for the value payload,
even though both payloads are always materialized together as part of the same KeyValueRef.
Proposed Solution
Reduce allocation overhead during range-result materialization by storing key and value payload bytes more efficiently during KeyValueRef deep-copy construction, while preserving existing:
StringRef behavior,
RangeResultRef layout,
- RocksDB iterator lifetime guarantees.
Description
KeyValueRefdeep-copy construction currently performs two independent arena allocations for every returned key-value pair during RocksDB range iteration.This occurs in the storage-server range read path, where every returned RocksDB key/value slice is materialized into a
RangeResultRefusingpush_back_deep/emplace_back_deep.For large range scans, this introduces unnecessary allocator overhead and additional allocation metadata traffic in the hot read path.
Root Cause
File paths:
Current range materialization path:
push_back_deepconstructs:which in turn performs two separate
StringRef(Arena&, ...)allocations:As a result, every returned KV pair performs:
even though both payloads are always materialized together as part of the same
KeyValueRef.Proposed Solution
Reduce allocation overhead during range-result materialization by storing key and value payload bytes more efficiently during
KeyValueRefdeep-copy construction, while preserving existing:StringRefbehavior,RangeResultReflayout,