Skip to content

Commit 003bfee

Browse files
committed
V2 serialization format for wide columns with blob references
Introduce a new V2 serialization format for wide column entities that supports storing individual column values in blob files. The V2 format adds a column type section that marks each column as either inline or blob-index, enabling per-column blob storage for large values. Key additions: - SerializeWithBlobIndices(): serialize entities with blob column references - DeserializeColumns(): deserialize V2 entities extracting blob column metadata - HasBlobColumns(): lightweight check for V2 blob references - GetVersion(): return the format version of a serialized entity - ResolveEntityBlobColumns(): resolve all blob references in an entity - Updated Deserialize() and GetValueOfDefaultColumn() for V2 compatibility
1 parent 6ac0da3 commit 003bfee

File tree

6 files changed

+1403
-41
lines changed

6 files changed

+1403
-41
lines changed

CLAUDE.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,31 @@ This document provides guidance for generating and reviewing code in the RocksDB
2424

2525
### Performance Considerations
2626

27+
**⚠️ PERFORMANCE IS CRITICAL:** RocksDB is a high-performance storage engine where every CPU cycle and memory access matters. When writing code, always evaluate from a performance perspective. This is not optional—performance-aware coding is a fundamental requirement for all contributions.
28+
2729
**Benchmarking and Profiling:** Performance claims should be backed by empirical evidence. Use RocksDB's benchmarking tools (e.g., `db_bench`) to validate improvements. Reviewers will request benchmark results for changes that could impact performance.
2830

29-
**Avoid Premature Optimization:** Focus on correctness first, then optimize based on profiling data. Reviewers are skeptical of optimizations that add complexity without measurable benefit.
31+
**Memory Allocation:** Minimize dynamic memory allocations, especially in hot paths. Prefer stack allocation over heap allocation. Reuse buffers when possible. Consider using arena allocators or memory pools for frequent small allocations. Every `new`, `malloc`, or container resize has a cost.
32+
33+
**Memory Copy:** Avoid unnecessary memory copies. Use move semantics, `std::string_view`, `Slice`, and pass-by-reference where appropriate. Be aware of implicit copies in STL containers and function returns. Prefer in-place operations over copy-and-modify patterns.
34+
35+
**CPU Cache Efficiency:** Design data structures and access patterns to be cache-friendly. Keep frequently accessed data together (data locality). Prefer sequential memory access over random access. Be mindful of cache line sizes (typically 64 bytes) and avoid false sharing in concurrent code. Consider struct packing and field ordering to improve cache utilization.
36+
37+
**Loop Optimization:** Look for opportunities to collapse nested loops, reduce loop overhead, and minimize branch mispredictions. Hoist invariant computations out of loops. Consider loop unrolling for tight inner loops. Batch operations when possible to amortize per-operation overhead.
38+
39+
**SIMD and Vectorization:** Leverage SIMD instructions (SSE, AVX) for data-parallel operations when appropriate. Structure data to enable auto-vectorization by the compiler. Consider explicit SIMD intrinsics for critical hot paths like checksum computation, encoding/decoding, and bulk data processing.
40+
41+
**Branch Prediction:** Minimize unpredictable branches in hot paths. Use `LIKELY`/`UNLIKELY` macros to hint branch prediction. Consider branchless alternatives for simple conditionals. Order switch cases and if-else chains by frequency.
3042

3143
**Memory and Resource Management:** Be mindful of memory allocations, especially in hot paths. Use RAII patterns, smart pointers, and RocksDB's memory management utilities appropriately.
3244

45+
**Hot Path Analysis:** When deciding how aggressively to optimize code, consider whether it's on a hot path:
46+
- **Hot path** (executed thousands+ times, e.g., data access, iteration, compaction loops): Performance is paramount. Apply all optimization techniques—loop collapsing, SIMD, cache optimization, pre-allocation, etc. The cost of each operation is multiplied by execution frequency.
47+
- **Cold path** (executed rarely, e.g., DB open, configuration parsing, error handling): Maintainability and clarity are more important. Prefer readable code over micro-optimizations. Complex optimizations here add maintenance burden with negligible performance benefit.
48+
- **Warm path** (moderate frequency): Balance both concerns. Use profiling data to guide optimization decisions.
49+
50+
**Avoid Premature Optimization:** While performance is critical, focus on correctness first, then optimize based on profiling data. However, be performance-aware from the start—choosing the right algorithm and data structure upfront is not premature optimization. Use the hot path analysis above to decide how much optimization effort is warranted.
51+
3352
### API Design and Compatibility
3453

3554
**Backwards Compatibility:** RocksDB maintains strong backwards compatibility guarantees. Breaking changes are rare and require extensive justification. When deprecating features, follow the project's deprecation policy (typically spanning multiple releases).
@@ -209,6 +228,22 @@ The following patterns emerged as frequent sources of review feedback:
209228
gtest_parallel.py if available. E.g.
210229
python3 ${GTEST_PARALLEL}/gtest_parallel.py ./table_test
211230

231+
### Unit test dedup guidelines
232+
* Extract helper functions for repeated patterns such as object
233+
construction, round-trip (encode → decode → verify), and common
234+
assertion sequences.
235+
* Use table-driven tests (struct array + loop) when multiple test cases
236+
share the same logic but differ only in input/expected data.
237+
* Prefer randomized tests over exhaustive parameter permutations. Use
238+
`Random` from `util/random.h` (not `std::mt19937`). Use a time-based
239+
seed with `SCOPED_TRACE("seed=" + std::to_string(seed))` so failures
240+
are reproducible.
241+
* Keep deterministic edge-case tests separate from randomized tests
242+
(error paths, boundary conditions, format verification).
243+
* Methods only used in tests should be private with `friend class` +
244+
`TEST_F` fixture wrappers. In wrappers, always fully qualify the
245+
target method to avoid infinite recursion.
246+
212247
### Adding new public API
213248
Refer to claude_md/add_public_api.md
214249

db/blob/blob_index.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,18 @@ class BlobIndex {
137137
return oss.str();
138138
}
139139

140+
// Encode this blob index into dst based on its type.
141+
void EncodeTo(std::string* dst) const {
142+
if (IsInlined()) {
143+
EncodeInlinedTTL(dst, expiration_, value_);
144+
} else if (HasTTL()) {
145+
EncodeBlobTTL(dst, expiration_, file_number_, offset_, size_,
146+
compression_);
147+
} else {
148+
EncodeBlob(dst, file_number_, offset_, size_, compression_);
149+
}
150+
}
151+
140152
static void EncodeInlinedTTL(std::string* dst, uint64_t expiration,
141153
const Slice& value) {
142154
assert(dst != nullptr);

0 commit comments

Comments
 (0)