Skip to main content

mmdb_writer/
record_size.rs

1//! Tree record width — the number of bits used to encode each child pointer in a
2//! binary-search-tree node.
3
4/// Width, in bits, of a single child record inside a search-tree node.
5///
6/// Each node holds two records (a left and a right child). Wider records address larger
7/// trees at the cost of bytes on disk. The [MMDB format] defines exactly these three widths;
8/// any other width produces a file no reader will accept, so it is modeled as an enum rather
9/// than a raw integer.
10///
11/// A [`Writer`] picks the smallest size that fits by default — see
12/// [`WriterBuilder::record_size`] to pin one explicitly.
13///
14/// [MMDB format]: https://maxmind.github.io/MaxMind-DB/
15/// [`Writer`]: crate::Writer
16/// [`WriterBuilder::record_size`]: crate::WriterBuilder::record_size
17#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
18#[non_exhaustive]
19pub enum RecordSize {
20    /// 24-bit records, 6-byte nodes. Capacity: ~16.7 million nodes.
21    Bits24,
22    /// 28-bit records, 7-byte nodes. Capacity: ~268 million nodes. **Default.**
23    #[default]
24    Bits28,
25    /// 32-bit records, 8-byte nodes. Capacity: ~4.3 billion nodes.
26    Bits32,
27}
28
29impl RecordSize {
30    /// Width of the record in bits (24, 28, or 32).
31    #[must_use]
32    pub const fn bits(self) -> u8 {
33        match self {
34            Self::Bits24 => 24,
35            Self::Bits28 => 28,
36            Self::Bits32 => 32,
37        }
38    }
39
40    /// Number of bytes a single tree node (two records) occupies on disk.
41    #[must_use]
42    pub const fn node_bytes(self) -> usize {
43        match self {
44            Self::Bits24 => 6,
45            Self::Bits28 => 7,
46            Self::Bits32 => 8,
47        }
48    }
49
50    /// Maximum addressable record value, exclusive. Values at or above this limit cannot be
51    /// encoded and are caught before serialization.
52    #[must_use]
53    pub const fn max_value(self) -> u64 {
54        match self {
55            Self::Bits24 => 1 << 24,
56            Self::Bits28 => 1 << 28,
57            Self::Bits32 => 1 << 32,
58        }
59    }
60
61    /// Width encoded as a `u16` for the metadata section's `record_size` field.
62    #[must_use]
63    pub const fn as_metadata(self) -> u16 {
64        self.bits() as u16
65    }
66
67    /// The record sizes in ascending order of capacity, for auto-selection.
68    pub(crate) const ASCENDING: [Self; 3] = [Self::Bits24, Self::Bits28, Self::Bits32];
69}