1use std::ops::Deref;
2
3pub const fn optimal_bundle_size(max_value: u64) -> BundleSize {
19 let naive_bits = if max_value == 0 {
20 return BundleSize(0);
21 } else {
22 max_value.ilog2() + 1
23 };
24
25 let mut best_size = 1u8;
26 let mut best_bits_per_val = naive_bits as f64;
27
28 let mut bundle_size = 1;
30 while bundle_size <= 40u8 {
31 let Some(max_bundle) = max_value.checked_pow(bundle_size as u32) else {
33 break;
34 };
35
36 let bits_needed = (64 - (max_bundle - 1).leading_zeros()) as u8;
37 let bits_per_val = bits_needed as f64 / bundle_size as f64;
38
39 if bits_per_val < best_bits_per_val {
40 best_bits_per_val = bits_per_val;
41 best_size = bundle_size;
42 }
43
44 bundle_size += 1;
45 }
46
47 BundleSize(best_size)
48}
49
50pub const fn bits_per_bundle(max_value: u64, bundle_size: BundleSize) -> BitsPerBundle {
51 let max_bundle = max_value.pow(bundle_size.0 as u32);
52 BitsPerBundle((64 - (max_bundle - 1).leading_zeros()) as u8)
53}
54
55#[derive(Copy, Clone, Debug)]
56pub struct BundleSize(pub u8);
57impl Deref for BundleSize {
58 type Target = u8;
59 fn deref(&self) -> &Self::Target {
60 &self.0
61 }
62}
63
64#[derive(Copy, Clone, Debug)]
65pub struct BitsPerBundle(pub u8);
66impl Deref for BitsPerBundle {
67 type Target = u8;
68 fn deref(&self) -> &Self::Target {
69 &self.0
70 }
71}
72
73pub fn theoretical_bits(max_value: u64) -> f64 {
75 (max_value as f64).log2()
76}
77
78pub fn naive_bits(max_value: u64) -> u8 {
80 (64 - (max_value - 1).leading_zeros()) as u8
81}
82
83pub fn encode(bundle_size: BundleSize, max_value: u64, values: &[u64]) -> u64 {
84 assert_eq!(values.len(), *bundle_size as usize);
85
86 let mut bundle: u64 = 0;
87 for &val in values {
88 assert!(val < max_value);
89 bundle = bundle * max_value + val;
90 }
91 bundle
92}
93
94pub fn decode(bundle_size: BundleSize, max_value: u64, mut bundle: u64) -> Vec<u64> {
95 let mut values = vec![0u64; *bundle_size as usize];
96
97 for i in (0..*bundle_size as usize).rev() {
98 values[i] = bundle % max_value;
99 bundle /= max_value;
100 }
101
102 values
103}