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
//! Core traits for the [`variable`] module.
//!
//! This module defines the [`Storable`] trait, a generic abstraction that allows
//! different integer types to be stored in an [`VarVec`]. It handles the necessary
//! conversions to the [`u64`] word representation required by the underlying
//! variable-length compression codecs.
//!
//! [`VarVec`]: crate::variable::VarVec
//! [`variable`]: crate::variable
use ;
/// A trait for types that can be stored in a variable-length compressed vector.
///
/// This trait provides a bidirectional, lossless conversion between a user-facing
/// element type (e.g., [`i32`], [`u16`]) and a [`u64`] representation. This abstraction
/// is essential for [`VarVec`] to support a variety of integer types while using
/// a common set of compression algorithms that operate on [`u64`].
///
/// # Portability and [`usize`]/[`isize`]
///
/// By default, this trait is implemented only for fixed-size integer types
/// (e.g., [`u8`], [`i16`], [`u32`], [`i64`]). This design choice guarantees that data
/// compressed on one machine architecture (e.g., 64-bit) can be safely
/// decompressed on another (e.g., 32-bit) without data loss or corruption.
///
/// Support for the architecture-dependent types [`usize`] and [`isize`] can be
/// enabled via the `arch-dependent-storable` feature flag.
///
/// ## Feature Flag: `arch-dependent-storable`
///
/// Activating this feature provides [`Storable`] implementations for [`usize`] and
/// [`isize`]. However, this breaks the portability guarantee. An `VarVec<usize>`
/// created on a 64-bit system with values greater than [`u32::MAX`] will cause a
/// panic if it is read on a 32-bit system.
///
/// **Enable this feature only if you are certain that the data will never be
/// shared across platforms with different pointer widths.**
///
/// # Zig-Zag Encoding for Signed Integers
///
/// For signed integer types, the implementation of this trait automatically
/// applies **Zig-Zag encoding**. This is a reversible transformation that maps
/// signed integers to unsigned integers, such that values close to zero (both
/// positive and negative) are mapped to small unsigned integers. This is highly
/// effective for variable-length codes, which use fewer bits to represent smaller
/// numbers.
///
/// | Original Signed | Zig-Zag Unsigned |
/// |-----------------|------------------|
/// | 0 | 0 |
/// | -1 | 1 |
/// | 1 | 2 |
/// | -2 | 3 |
/// | 2 | 4 |
/// | ... | ... |
///
/// [`VarVec`]: crate::variable::VarVec
// Implement `Storable` for all primitive, fixed-size integer types.
impl_storable_for_unsigned!;
impl_storable_for_signed!;
/// Contains `Storable` implementations for architecture-dependent types.
/// This module is only compiled when the `arch-dependent-storable` feature is enabled.