atlas/config.rs
1/// Compression codec applied when writing new array blocks.
2///
3/// The codec is stored per-variable in `atlas.json` so that each array
4/// can be reopened with the correct codec regardless of the store-level default.
5/// Existing blocks are always decompressed using whatever codec they were
6/// originally written with, so the choice only affects the write path.
7///
8/// Also reused for metadata compression via
9/// [`StoreConfig::meta_compression`] — the same three options apply.
10#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
11pub enum Codec {
12 /// Zstd compression (default). Best compression ratio at moderate speed.
13 #[default]
14 Zstd,
15 /// LZ4 compression. Faster than Zstd, larger files.
16 Lz4,
17 /// No compression. Fastest write path, no size reduction.
18 Uncompressed,
19}
20
21/// On-disk encoding for the store's metadata file.
22///
23/// The format choice lives in the filename (`atlas.json` vs `atlas.msgpack`,
24/// with optional `.zst` / `.lz4` suffix) rather than inside the file, so
25/// [`crate::Atlas::open`] can detect it without a caller-supplied hint.
26#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
27pub enum MetaFormat {
28 /// Pretty-printed JSON (`atlas.json`). Human-readable, default for
29 /// backwards compatibility with stores created before this option existed.
30 #[default]
31 Json,
32 /// MessagePack (`atlas.msgpack`). Compact binary encoding — typically
33 /// 30–50% smaller than JSON and faster to parse, but not human-readable.
34 MsgPack,
35}
36
37impl MetaFormat {
38 /// Filename used for this format / compression pair. All six combinations
39 /// resolve to a `&'static str` so the result can be passed straight to
40 /// [`object_store::path::Path::from`].
41 pub(crate) const fn filename(self, compression: Codec) -> &'static str {
42 match (self, compression) {
43 (MetaFormat::Json, Codec::Uncompressed) => "atlas.json",
44 (MetaFormat::Json, Codec::Zstd) => "atlas.json.zst",
45 (MetaFormat::Json, Codec::Lz4) => "atlas.json.lz4",
46 (MetaFormat::MsgPack, Codec::Uncompressed) => "atlas.msgpack",
47 (MetaFormat::MsgPack, Codec::Zstd) => "atlas.msgpack.zst",
48 (MetaFormat::MsgPack, Codec::Lz4) => "atlas.msgpack.lz4",
49 }
50 }
51}
52
53/// The six (format, compression) pairs in priority order — used by `open`
54/// to disambiguate when multiple metadata files happen to coexist.
55/// Uncompressed comes before compressed within each format, and JSON comes
56/// before MsgPack overall (preserving the existing "JSON wins if both
57/// exist" precedent from the format-detection logic).
58pub(crate) const META_VARIANTS: [(MetaFormat, Codec); 6] = [
59 (MetaFormat::Json, Codec::Uncompressed),
60 (MetaFormat::Json, Codec::Zstd),
61 (MetaFormat::Json, Codec::Lz4),
62 (MetaFormat::MsgPack, Codec::Uncompressed),
63 (MetaFormat::MsgPack, Codec::Zstd),
64 (MetaFormat::MsgPack, Codec::Lz4),
65];
66
67/// Configuration for opening or creating an [`Atlas`](crate::Atlas).
68#[derive(Debug, Clone)]
69pub struct StoreConfig {
70 /// Compression codec used when writing array blocks. Defaults to [`Codec::Zstd`].
71 pub codec: Codec,
72 /// On-disk encoding for the metadata file. Defaults to [`MetaFormat::Json`].
73 /// Only consulted by `create`; `open` detects the format from the filename
74 /// present on disk.
75 pub meta_format: MetaFormat,
76 /// Compression applied to the encoded metadata bytes. Defaults to
77 /// [`Codec::Uncompressed`] so the on-disk filename matches the format
78 /// (`atlas.json` / `atlas.msgpack`). Only consulted by `create`; `open`
79 /// detects compression from the filename suffix on disk.
80 pub meta_compression: Codec,
81}
82
83// Manual Default — `meta_compression` defaults to `Uncompressed`, not
84// `Codec::default()` (which is `Zstd`), so new stores keep the legacy
85// `atlas.json` / `atlas.msgpack` filenames unless the caller opts in.
86impl Default for StoreConfig {
87 fn default() -> Self {
88 Self {
89 codec: Codec::default(),
90 meta_format: MetaFormat::default(),
91 meta_compression: Codec::Uncompressed,
92 }
93 }
94}