1use sucds::mii_sequences::EliasFanoBuilder;
8
9use cacheline_ef::{CachelineEf, CachelineEfVec};
10
11pub trait Packed: Sync {
13 fn index(&self, index: usize) -> u64;
15 fn prefetch(&self, _index: usize) {}
17 fn size_in_bytes(&self) -> usize;
19}
20
21pub trait MutPacked: Packed + Sized {
23 fn default() -> Self;
24 fn try_new(vals: Vec<u64>) -> Option<Self>;
25 fn name() -> String;
26}
27
28macro_rules! vec_impl {
29 ($t:ty) => {
30 impl MutPacked for Vec<$t> {
31 fn default() -> Self {
32 Default::default()
33 }
34 fn try_new(vals: Vec<u64>) -> Option<Self> {
35 Some(
36 vals.into_iter()
37 .map(|x| {
38 x.try_into()
39 .expect(&format!("Value {x} is larger than backing type can hold."))
40 })
41 .collect(),
42 )
43 }
44 fn name() -> String {
45 stringify!(Vec<$t>).to_string()
46 }
47 }
48 impl Packed for Vec<$t> {
49 fn index(&self, index: usize) -> u64 {
50 unsafe { (*self.get_unchecked(index)) as u64 }
51 }
52 fn prefetch(&self, index: usize) {
53 crate::util::prefetch_index(self, index);
54 }
55 fn size_in_bytes(&self) -> usize {
56 std::mem::size_of_val(self.as_slice())
57 }
58 }
59 };
60}
61
62vec_impl!(u8);
63vec_impl!(u16);
64vec_impl!(u32);
65vec_impl!(u64);
66
67macro_rules! slice_impl {
68 ($t:ty) => {
69 impl Packed for [$t] {
70 fn index(&self, index: usize) -> u64 {
71 unsafe { (*self.get_unchecked(index)) as u64 }
72 }
73 fn prefetch(&self, index: usize) {
74 crate::util::prefetch_index(self, index);
75 }
76 fn size_in_bytes(&self) -> usize {
77 std::mem::size_of_val(self)
78 }
79 }
80 };
81}
82
83slice_impl!(u8);
84slice_impl!(u16);
85slice_impl!(u32);
86slice_impl!(u64);
87
88impl MutPacked for CachelineEfVec<Vec<CachelineEf>> {
89 fn default() -> Self {
90 Default::default()
91 }
92 fn try_new(vals: Vec<u64>) -> Option<Self> {
93 Self::try_new(&vals)
94 }
95 fn name() -> String {
96 "CacheLineEF".to_string()
97 }
98}
99
100impl<T: AsRef<[CachelineEf]> + Sync> Packed for CachelineEfVec<T> {
101 fn index(&self, index: usize) -> u64 {
102 unsafe { self.index_unchecked(index) }
103 }
104 fn prefetch(&self, index: usize) {
105 self.prefetch(index)
106 }
107 fn size_in_bytes(&self) -> usize {
108 self.size_in_bytes()
109 }
110}
111
112pub struct EliasFano(sucds::mii_sequences::EliasFano);
114
115impl MutPacked for EliasFano {
116 fn default() -> Self {
117 EliasFano(Default::default())
118 }
119
120 fn try_new(vals: Vec<u64>) -> Option<Self> {
121 if vals.is_empty() {
122 Some(Self::default())
123 } else {
124 let mut builder =
125 EliasFanoBuilder::new(*vals.last().unwrap() as usize + 1, vals.len()).unwrap();
126 builder.extend(vals.iter().map(|&x| x as usize)).unwrap();
127 Some(EliasFano(builder.build()))
128 }
129 }
130 fn name() -> String {
131 "EF".to_string()
132 }
133}
134
135impl Packed for EliasFano {
136 fn index(&self, index: usize) -> u64 {
137 self.0.select(index as _).unwrap() as u64
138 }
139
140 fn size_in_bytes(&self) -> usize {
141 sucds::Serializable::size_in_bytes(&self.0)
142 }
143}