questdb-rs 7.0.0

QuestDB Client Library for Rust
Documentation
# QWP/WebSocket Java Store-and-Forward fixtures

These fixtures are committed compatibility data for the Rust QWP/WebSocket
Store-and-Forward on-disk formats: the `.sfa` segment codec and the
`.symbol-dict` side-file. Every one of them holds bytes the **Java reference
client actually wrote**, so the Rust tests that load them prove cross-client
parity rather than re-asserting this client's own round-trip. Normal Rust tests
load these hex files and do not need a Java checkout.

## `.sfa` segment fixtures

The fixtures model one Java `MmapSegment` file:

- file size: 64 bytes
- `baseSeq`: 42
- `createdMicros`: normalized to `1234567890123` after Java generation so the
  fixture is deterministic
- payloads: `one`, `two-two`
- frame format: `[u32 crc32c][u32 payloadLen][payload]`
- CRC32C covers `payloadLen || payload`

Files:

- `java-two-frame.sfa.hex` - segment with two valid frames and a zero-filled
  tail.
- `java-two-frame-torn-tail.sfa.hex` - same segment, but the second payload has
  one byte flipped. Recovery must keep the first frame, set append offset to
  `35`, and report `29` torn-tail bytes.

## `.symbol-dict` side-file fixtures

The fixtures model one Java `PersistedSymbolDict` file (34 bytes), written with
the two append shapes a Java producer uses -- `appendSymbol` for a frame that
introduces one symbol, `appendSymbols(dict, from, to)` for one that introduces
several:

- chunk 0: `["one"]`
- chunk 1: `["two", "three"]`
- layout: `[u32 magic 'SYD1'][u8 version 1][3 reserved]` then chunks of
  `[entryCount varint][entryBytes varint][entries][u32 crc32c]`, where entries
  are `[len varint][utf8]` and the CRC32C covers both header varints and the
  entry region
- no timestamp field, and Java truncates its mmap reserve to the logical length
  on close, so the bytes need no normalization

A multi-entry chunk is deliberately included: it is the case per-chunk (rather
than per-entry) checksumming exists for, and the case a single-symbol fixture
would not exercise at all.

Files:

- `java-two-chunk.symbol-dict.hex` - the two chunks above.
- `java-two-chunk-torn-tail.symbol-dict.hex` - the same bytes with offset `21`
  (the `t` of `two`, inside chunk 1) flipped to `u`. Same length, so only that
  chunk's stored CRC goes stale: recovery must keep chunk 0, recover `["one"]`
  alone, and truncate the file back to `18` bytes.

## Proving and regenerating the fixtures

Point `QDB_JAVA_CLIENT_CORE` at the Java client's `core` directory (the one
holding `pom.xml` and `target/classes`; run `mvn -f <core>/pom.xml test-compile`
first if `target/classes` is missing). Then, to prove the fixtures against the
Java source:

```sh
QDB_JAVA_CLIENT_CORE=<core> cargo test --manifest-path questdb-rs/Cargo.toml \
  java_and_rust_read_each_others_segments -- --ignored --nocapture

QDB_JAVA_CLIENT_CORE=<core> cargo test --manifest-path questdb-rs/Cargo.toml \
  java_and_rust_read_each_others_symbol_dicts -- --ignored --nocapture
```

Each test compiles a small Java helper into a temp dir, drives Java's real
`MmapSegment` / `PersistedSymbolDict`, and verifies both directions:
Java-written file read by Rust, Rust-written file read by Java, and torn-tail
recovery agreement.

To print regenerated fixture hex from Java-generated bytes:

```sh
QDB_JAVA_CLIENT_CORE=<core> cargo test --manifest-path questdb-rs/Cargo.toml \
  print_java_sfa_fixture_hex -- --ignored --nocapture

QDB_JAVA_CLIENT_CORE=<core> cargo test --manifest-path questdb-rs/Cargo.toml \
  print_java_symbol_dict_fixture_hex -- --ignored --nocapture
```