elias_fano_rust/
builders.rs1use super::*;
2
3impl EliasFano {
4
5 #[inline]
6 pub fn new(universe: u64, number_of_elements: usize) -> Result<EliasFano, String> {
7 if number_of_elements == 0 {
8 return Ok(EliasFano{
9 universe: universe,
10 low_bit_count: 0,
11 low_bit_mask: 0,
12 number_of_elements: 0,
13 high_bits: SimpleSelect::new(),
14 low_bits: vec![],
15 last_high_value: 0,
16 last_value: 0,
17 last_index: 0,
18 current_number_of_elements: 0,
19 });
20 }
21 let low_bit_count = if universe >= number_of_elements as u64 {
23 (universe as f64 / number_of_elements as f64).log2().floor() as u64
24 } else {
25 0
26 };
27
28 if low_bit_count > 64 {
30 return Err(format!(concat!(
31 "The lowbits are too big, we only support 64 bits for the low parts.",
32 "The value were universe {} number_of_elements {}"
33 ),
34 universe, number_of_elements
35 ));
36 }
37
38 let low_size = get_vec_size(low_bit_count, number_of_elements);
40
41 Ok(EliasFano {
42 universe,
43 low_bit_count,
44 low_bit_mask: shr(0xffffffffffffffff, 64 - low_bit_count),
46 high_bits: SimpleSelect::with_capacity(2 * number_of_elements),
47 number_of_elements: number_of_elements as u64,
48 low_bits: vec![0; low_size as usize],
49 last_high_value: 0,
50 last_value: 0,
51 last_index: 0,
52 current_number_of_elements: 0,
53 })
54 }
55
56 #[inline]
69 pub fn from_iter(
70 values: impl Iterator<Item = u64>,
71 universe: u64,
72 number_of_elements: usize,
73 ) -> Result<EliasFano, String> {
74 let mut result = EliasFano::new(universe, number_of_elements)?;
75
76 result.build_low_high_bits(values)?;
77
78 Ok(result)
79 }
80
81 #[inline]
94 pub fn from_vec(values: &[u64]) -> Result<EliasFano, String> {
95 EliasFano::from_iter(
96 values.iter().cloned(),
97 *values.last().unwrap_or(&0),
98 values.len(),
99 )
100 }
101
102 #[inline]
103 pub fn unchecked_push(&mut self, value: u64) {
104 self.last_value = value;
105 self.current_number_of_elements += 1;
106
107 let (high, low) = self.extract_high_low_bits(value);
109
110 for _ in self.last_high_value..high {
114 self.high_bits.push(false);
115 }
116 self.high_bits.push(true);
117
118 #[cfg(not(feature = "unsafe"))]
119 safe_write(&mut self.low_bits, self.last_index, low, self.low_bit_count);
120 #[cfg(feature = "unsafe")]
121 unsafe_write(&mut self.low_bits, self.last_index, low, self.low_bit_count);
122
123 self.last_high_value = high;
124 self.last_index += 1;
125 }
126
127 #[inline]
128 pub fn push(&mut self, value: u64) -> Result<(), String> {
129 if self.last_value > value {
130 return Err(format!(
131 concat!(
132 "Cannot initialize from an unsorted set of values! ",
133 "Previous value was {} but given value is {}.",
134 ),
135 self.last_value, value
136 ));
137 }
138 if self.current_number_of_elements >= self.number_of_elements {
139 return Err(format!(
140 concat!(
141 "Cannot push anymore values inside of the Elias-Fano ",
142 "because it already reached the maximum number of elements ",
143 "that was passed during the initialization {}."
144 ),
145 self.number_of_elements
146 ));
147 }
148 self.unchecked_push(value);
149 Ok(())
150 }
151}