1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
[]
= "obj-core"
= "Storage engine internals for the obj embedded document database (pager, WAL, B-tree, codec, catalog)."
= true
= true
= true
= true
= true
= true
= "https://github.com/uname-n/obj"
= "https://docs.rs/obj-core"
= "README.md"
= ["database", "embedded", "storage", "wal", "btree"]
= ["database-implementations", "data-structures"]
[]
# `thiserror` keeps the public `Error` enum readable while still giving us
# the `Display` + `source()` chain the project plan requires. v1 is the
# stable mainline (Apache-2.0 OR MIT).
= "1"
# `crc32c` provides hardware-accelerated CRC32C (Castagnoli) on x86-64
# (SSE 4.2) and ARMv8 (CRC32C instructions), with a software fallback
# elsewhere. The on-disk format pins CRC32C as its integrity primitive;
# see `docs/format.md` § Checksum algorithm. Apache-2.0 OR MIT.
= "0.6"
# `rand` + `rand_chacha`: deterministic PRNG for the WAL generation
# salt and the fault-injection harness (M3 issues #14, #17). MIT OR
# Apache-2.0. We use the OS RNG at WAL open time for the initial salt
# (via `rand`) and ChaCha8 for reproducible fault sequences.
= "0.9"
= "0.9"
# `heapless`: fixed-capacity collections with no heap allocation. The
# B+tree (M4) uses `heapless::Vec<PageId, 32>` for its traversal stack,
# upholding power-of-ten Rule 3 (no heap allocation on the read /
# write hot path). MIT OR Apache-2.0.
= "0.8"
# `serde` + `postcard`: the M5 document codec (L4) is built around
# postcard's stable v1.x wire format wrapped in obj's per-document
# header (`docs/format.md` § Document records). serde is required for
# user `Document` types; both crates are MIT OR Apache-2.0. The
# postcard `experimental-derive` and `use-std` features are NOT
# enabled — we use the bare allocvec/from_bytes path.
#
# `default-features = false` disables postcard's ONLY default feature,
# `heapless-cas`. That feature pulls in `heapless 0.7`, whose `cas`
# path drags in `atomic-polyfill 1.x` (RUSTSEC-2023-0089, unmaintained
# — see issues #39/#68). obj-core only uses `postcard::to_allocvec` /
# `from_bytes` / the `experimental` derive (the alloc path); it never
# touches postcard's heapless-output APIs (`to_vec` / `to_slice`), so
# dropping `heapless-cas` removes heapless 0.7 + atomic-polyfill from
# the tree with ZERO impact on the on-disk wire format. heapless 0.8
# (already on portable-atomic) remains a direct obj-core dependency
# for the B+tree traversal stack; this only removes the stale 0.7.
= { = "1", = ["derive"] }
= { = "1", = false, = ["alloc", "experimental-derive"] }
# Phase 2B (issue #7): `tracing` is an opt-in feature on obj-core.
# When the `tracing` feature is enabled on the parent obj-db crate
# (which propagates via `obj-core/tracing`), the pager's checkpoint
# path emits a `pager.checkpoint` span. The dependency is optional
# so the default build adds zero new transitive deps. Apache-2.0 OR
# MIT.
= { = "0.1", = true }
# Phase 3 (issue #8): `lz4_flex` provides the LZ4 raw-block codec
# the page compression feature uses (`compress_into` /
# `decompress_into` — fixed-output-buffer APIs that avoid heap
# allocation on the hot read/write path, upholding power-of-ten
# Rule 3). The dependency is optional and only pulled in when the
# `compression` feature is enabled. MIT.
= { = "0.11", = true, = false, = ["std"] }
# Phase 4 (issue #9): `chacha20poly1305` is the RustCrypto AEAD
# used for at-rest page encryption. Pure-Rust, no `unsafe` on the
# library side (we forbid `unsafe` in `crypto.rs` ourselves). The
# `getrandom` feature on this crate is OFF; we surface
# `getrandom` directly below so the random-nonce generator
# returns a proper `Result` rather than panicking. Apache-2.0 OR
# MIT.
= { = "0.10", = true, = false, = ["alloc"] }
# Phase 4 (issue #9): HKDF-SHA256 KDF. Derives the per-file page
# key from a 32-byte user key + 32-byte `kdf_salt` carried in
# the page-0 header. The `info` string `obj-page-encryption-v1`
# is the versioning hook for future KDF migrations. MIT OR
# Apache-2.0.
= { = "0.12", = true }
= { = "0.10", = true, = false }
# Phase 4 (issue #9): direct CSPRNG bridge. The pager generates
# a fresh 12-byte nonce for every page write via
# `getrandom::getrandom`; returning a `Result` keeps the
# encryption path Rule-7-compliant (no `unwrap` / `expect` on a
# CSPRNG failure). MIT OR Apache-2.0.
= { = "0.2", = true }
# Issue #31: `zeroize` wipes in-memory key material on drop so the
# 32-byte master key (and the HKDF-derived per-file page key) does
# not linger in freed heap/stack after the owning `Config` / pager /
# WAL is dropped. RustCrypto crate, Apache-2.0 OR MIT, and ALREADY
# pulled into the `encryption` build transitively via
# `chacha20poly1305` (`cipher` -> `zeroize`), so naming it explicitly
# adds zero new dependencies to any build. Optional and gated on the
# `encryption` feature: the no-feature baseline build never sees it.
# The `serde` feature lets `Zeroizing<[u8; 32]>` round-trip through
# the existing derive-based pager `Config` serde impls unchanged.
= { = "1.8", = true, = false, = ["alloc", "serde"] }
# `libc` exposes the OFD lock constants and `flock`/`fcntl` ABI the
# M6 file-locking layer needs (`F_OFD_SETLK` / `F_OFD_SETLKW`). On
# POSIX targets the lock layer calls `fcntl(F_OFD_SETLK*, struct
# flock*)` directly; `rustix::fs::fcntl_lock` does not expose the
# OFD variants. MIT OR Apache-2.0.
#
# `rustix` provides safe wrappers around `fcntl(F_FULLFSYNC)` and
# `fdatasync` for the `Full` durability path so this crate does not
# have to maintain its own `unsafe` syscall layer. It is Unix-only
# here because `rustix::fs` is gated off on Windows; Windows uses
# `std::fs::File::sync_all` (`FlushFileBuffers`) instead.
# Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT.
[]
= "0.2"
= { = "1", = ["fs"] }
# `windows-sys` exposes `LockFileEx` / `UnlockFileEx` for the
# Windows lock path. MIT OR Apache-2.0. Feature flags pulled in are
# the smallest set that gives us the LockFileEx ABI plus the
# `OVERLAPPED` struct.
[]
= { = "0.59", = [
"Win32_Foundation",
"Win32_Storage_FileSystem",
"Win32_System_IO",
] }
[]
# Phase 2B (issue #7): default to no features so the baseline build
# stays dependency-clean. Listed explicitly for parity with
# `crates/obj/Cargo.toml`.
= []
# Opt-in build of the test-only fault-injection harness for callers
# outside `obj-core` (e.g. integration tests in this crate's
# `tests/` directory, sibling crates, and the crash-cycle harness).
# Inside `obj-core` `cfg(test)` ALSO enables it so unit tests can
# use the harness without the feature flag.
= []
# Phase 2B (issue #7): emit tracing spans around hot pager paths
# (checkpoint, today). Off by default — the feature only activates
# the optional `tracing` dependency.
= ["dep:tracing"]
# Phase 3 (issue #8): LZ4 per-page compression at the pager layer.
# Off by default — the feature only activates the optional
# `lz4_flex` dependency. Files written with `format_minor = 1`
# require this feature; older `format_minor = 0` files open
# without it.
= ["dep:lz4_flex"]
# Phase 4 (issue #9): ChaCha20-Poly1305 per-page at-rest
# encryption. Off by default — the feature pulls in the
# `chacha20poly1305`, `hkdf`, `sha2`, and `getrandom`
# dependencies and turns on the encrypted physical-page stride
# in the pager. Files written with `format_minor = 2` and
# `feature_flags` bit 1 set require this feature; older
# `format_minor < 2` files open without it.
= [
"dep:chacha20poly1305",
"dep:hkdf",
"dep:sha2",
"dep:getrandom",
# Issue #31: zeroize-on-drop for the master key, the derived
# page key (`PageEncryptionKey`), and the WAL key (`WalKey`).
"dep:zeroize",
]
[]
# `proptest` powers the 10k randomised alloc/free property tests
# required by issue #5. MIT OR Apache-2.0.
= "1"
# `tempfile` provides RAII temp directories for the file-backend tests.
# MIT OR Apache-2.0.
= "3"
# `criterion` powers the M4 collection-scan benchmark (#30). MIT OR
# Apache-2.0. We disable default features (`rayon`) — single-threaded
# measurement is sufficient for the storage-engine scan we care about.
= { = "0.5", = false, = ["cargo_bench_support"] }
[[]]
# The crash-cycle integration test imports `platform::fault`, which
# is gated behind the `fault-injection` feature (the harness must
# never compile into a release library build). Marking the test with
# `required-features` flips the feature on for `cargo test` runs of
# this target only.
= "crash_cycles"
= "tests/crash_cycles.rs"
= ["fault-injection"]
[[]]
# M4 exit criterion: range-scan benchmark within 2× of design.md's
# collection-scan target. `harness = false` lets criterion own the
# test main.
= "btree_range"
= false
[]
= true