Cassandra SSTable Format Parsing
Cassandra SSTable Format Parsing
This skill helps with parsing and understanding Cassandra 5.0+ SSTable file formats.
When to Use This Skill
- Parsing Data.db, Index.db, Statistics.db files
- Debugging binary format mismatches
- Analyzing hex dumps of SSTable data
- Working with compression (LZ4, Snappy, Deflate)
- Investigating offset calculation errors
- Understanding BTI (Big Table Index) format
- Validating partition boundaries
Key SSTable Components
Data.db
Contains the actual row data with:
- Partition headers
- Row data (clustering + cells)
- Compression blocks
- Checksums
Index.db
Contains partition index entries with:
- BTI (Big Table Index) format in Cassandra 5.0+
- Partition key → file offset mapping
- Promoted index entries
Statistics.db
Contains serialization metadata:
- Encoding stats (min/max timestamps, TTLs)
- Column definitions
- Schema information
- Compression parameters
Summary.db
Contains sampling of index entries for faster lookups
Format References
Primary Source of Truth: docs/sstables-definitive-guide/
Key chapters:
- Ch.5: Data.db Format - Row layout, flags, V5CompressedLegacy
- Ch.6: Index.db and Summary.db - Partition lookups
- Ch.9: CompressionInfo.db - Compression metadata, chunking
- Ch.17: BTI Formats - Trie-based indexes
- Appendix B: Encoding Cheat Sheet - VInt, cell flags
- Appendix F: Known Limitations - What doesn't work yet
Common Debugging Techniques
Hex Dump Analysis
When debugging parsing errors:
-
Extract hex at specific offset:
hexdump -C Data.db -s <offset> -n 64 -
Compare with expected format:
- Check magic bytes (if applicable)
- Verify VInt encoding
- Validate flag bytes
-
Look for patterns:
- Repeated byte sequences may indicate arrays/collections
- All zeros may indicate padding
- Non-zero high bytes suggest multi-byte integers
Offset Validation
Track byte consumption at each parsing stage:
- Clustering prefix (may be 0 bytes)
- Row sizes (2 VInts)
- Liveness info (conditional)
- Deletion info (conditional)
- Column bitmap (conditional)
- Cell data
Zero-Copy Considerations
When implementing parsers:
- Use
Bytescrate for buffer sharing - Avoid copying large cell values
- Keep references to original buffer
- Use byte slices not owned Vecs
Integration with Rust Code
Current implementation in cqlite-core/src/storage/sstable/reader/parsing/:
v5_compressed_legacy.rs- Main V5 format parser (1997 lines)- Uses zero-copy patterns with
Bytes - Handles compression transparently
PRD Alignment
Supports Milestone M1 (Core Reading Library):
- 100% Cassandra 5 SSTable format support
- All compression formats (LZ4, Snappy, Deflate)
- Zero-copy deserialization
- Memory target: <128MB for large files
Quick Reference
Flag Bytes (Row)
0x01: HAS_IS_MARKER0x02: HAS_ALL_COLUMNS (inverted - 0x20 means all present)0x04: HAS_TIMESTAMP0x08: HAS_TTL0x10: HAS_DELETION0x20: HAS_ALL_COLUMNS (flag set = all columns present)0x40: IS_STATIC0x80: EXTENSION_FLAG
VInt Encoding
Variable-length integer encoding:
- First byte indicates length
- Subsequent bytes contain value
- Used for row sizes, timestamps, offsets
Next Steps
When parser encounters issues:
- Log byte offsets at each stage
- Compare against Java source (UnfilteredSerializer.java)
- Validate against sstabledump output
- Check compression block boundaries
- Verify delta encoding calculations
More from pmcfadin/cqlite
napi-rs-node-bindings
Node.js bindings for Rust libraries using napi-rs. Use when working on Node.js/JavaScript bindings to Rust code, including creating or modifying napi macros and structs, converting types between Rust and JavaScript, handling errors across the FFI boundary, async/Promise patterns, building native modules, publishing to npm, testing binding code, or debugging binding issues. Tuned for CQLite (Cassandra CQL bindings) with feature parity tracking.
14pyo3-maturin-bindings
Python bindings for Rust libraries using PyO3 and maturin. Use when working on Python bindings to Rust code, including creating or modifying pyfunction/pyclass definitions, converting types between Rust and Python, handling errors across the FFI boundary, managing the GIL and memory, building wheels with maturin, publishing to PyPI, testing binding code, or debugging binding issues. Tuned for CQLite (Cassandra CQL bindings) with feature parity tracking.
1rust performance & safety patterns
Zero-copy deserialization, async I/O patterns, lifetime management, memory-efficient parsing, and safe handling of unsafe code for SSTable parsing. Use when working with performance optimization, memory efficiency, async/await, borrowing/lifetimes, zero-copy patterns, or memory usage under 128MB target.
1cql type system & schema handling
Implement and deserialize all CQL types including primitives (int, text, timestamp, uuid, varint, decimal), collections (list, set, map), tuples, UDTs (user-defined types), and frozen types. Use when working with CQL type deserialization, schema validation, collection parsing, UDT handling, or type-correct data generation.
1test data generation & validation
Generate real Cassandra 5.0 test data using Docker containers, export SSTables with proper directory structure, validate parsing against sstabledump, and manage test datasets. Use when working with test data generation, dataset creation, SSTable export, validation, fixture management, or sstabledump comparison.
1ci/cd validation & merge workflow
Pre-push validation checklist (cargo fmt, clippy with zero warnings, feature flag testing, test suite), CI monitoring, merge process, and release quality gates. Use when preparing to push code, validating changes before PR, running CI checks, merging PRs, or preparing releases.
1