1use crate::nibble::{NibbleSlice, BackingByteVec};
18use crate::nibble::nibble_ops;
19use tetsy_hash_db::Prefix;
20use crate::node_codec::Partial;
21use super::NibbleVec;
22
23impl Default for NibbleVec {
24 fn default() -> Self {
25 NibbleVec::new()
26 }
27}
28
29impl NibbleVec {
30 pub fn new() -> Self {
32 NibbleVec {
33 inner: BackingByteVec::new(),
34 len: 0,
35 }
36 }
37
38 #[inline(always)]
40 pub fn len(&self) -> usize { self.len }
41
42 pub fn is_empty(&self) -> bool { self.len == 0 }
44
45 #[inline]
47 pub fn at(&self, idx: usize) -> u8 {
48 let ix = idx / nibble_ops::NIBBLE_PER_BYTE;
49 let pad = idx % nibble_ops::NIBBLE_PER_BYTE;
50 nibble_ops::at_left(pad as u8, self.inner[ix])
51 }
52
53 pub fn push(&mut self, nibble: u8) {
55 let i = self.len % nibble_ops::NIBBLE_PER_BYTE;
56
57 if i == 0 {
58 self.inner.push(nibble_ops::push_at_left(0, nibble, 0));
59 } else {
60 let output = self.inner.last_mut()
61 .expect("len != 0 since len % 2 != 0; inner has a last element; qed");
62 *output = nibble_ops::push_at_left(i as u8, nibble, *output);
63 }
64 self.len += 1;
65 }
66
67 pub fn pop(&mut self) -> Option<u8> {
69 if self.is_empty() {
70 return None;
71 }
72 let byte = self.inner.pop().expect("len != 0; inner has last elem; qed");
73 self.len -= 1;
74 let i_new = self.len % nibble_ops::NIBBLE_PER_BYTE;
75 if i_new != 0 {
76 self.inner.push(nibble_ops::pad_left(byte));
77 }
78 Some(nibble_ops::at_left(i_new as u8, byte))
79 }
80
81 pub fn drop_lasts(&mut self, n: usize) {
83 if n == 0 { return; }
84 if n >= self.len {
85 self.clear();
86 return;
87 }
88 let end = self.len - n;
89 let end_index = end / nibble_ops::NIBBLE_PER_BYTE
90 + if end % nibble_ops::NIBBLE_PER_BYTE == 0 { 0 } else { 1 };
91 (end_index..self.inner.len()).for_each(|_| { self.inner.pop(); });
92 self.len = end;
93 let pos = self.len % nibble_ops::NIBBLE_PER_BYTE;
94 if pos != 0 {
95 let kl = self.inner.len() - 1;
96 self.inner[kl] = nibble_ops::pad_left(self.inner[kl]);
97 }
98 }
99
100 pub fn as_prefix(&self) -> Prefix {
102 let split = self.len / nibble_ops::NIBBLE_PER_BYTE;
103 let pos = (self.len % nibble_ops::NIBBLE_PER_BYTE) as u8;
104 if pos == 0 {
105 (&self.inner[..split], None)
106 } else {
107 (&self.inner[..split], Some(nibble_ops::pad_left(self.inner[split])))
108 }
109 }
110
111 pub fn append(&mut self, v: &NibbleVec) {
113
114 if v.len == 0 { return; }
115 let final_len = self.len + v.len;
116 let offset = self.len % nibble_ops::NIBBLE_PER_BYTE;
117 let final_offset = final_len % nibble_ops::NIBBLE_PER_BYTE;
118 let last_index = self.len / nibble_ops::NIBBLE_PER_BYTE;
119 if offset > 0 {
120 let (s1, s2) = nibble_ops::SPLIT_SHIFTS;
121 self.inner[last_index] = nibble_ops::pad_left(self.inner[last_index])
122 | (v.inner[0] >> s2);
123 (0..v.inner.len() - 1)
124 .for_each(|i| self.inner.push(v.inner[i] << s1 | v.inner[i+1] >> s2));
125 if final_offset > 0 {
126 self.inner.push(v.inner[v.inner.len() - 1] << s1);
127 }
128 } else {
129 (0..v.inner.len()).for_each(|i| self.inner.push(v.inner[i]));
130 }
131 self.len += v.len;
132 }
133
134 pub fn append_partial(&mut self, (start_byte, sl): Partial) {
136 if start_byte.0 == 1 {
137 self.push(nibble_ops::at_left(1, start_byte.1));
138 }
139 let pad = self.inner.len() * nibble_ops::NIBBLE_PER_BYTE - self.len;
140 if pad == 0 {
141 self.inner.extend_from_slice(&sl[..]);
142 } else {
143 let kend = self.inner.len() - 1;
144 if sl.len() > 0 {
145 self.inner[kend] = nibble_ops::pad_left(self.inner[kend]);
146 let (s1, s2) = nibble_ops::SPLIT_SHIFTS;
147 self.inner[kend] |= sl[0] >> s1;
148 (0..sl.len() - 1).for_each(|i| self.inner.push(sl[i] << s2 | sl[i+1] >> s1));
149 self.inner.push(sl[sl.len() - 1] << s2);
150 }
151 }
152 self.len += sl.len() * nibble_ops::NIBBLE_PER_BYTE;
153 }
154
155 pub(crate) fn append_optional_slice_and_nibble(
159 &mut self,
160 o_slice: Option<&NibbleSlice>,
161 o_index: Option<u8>,
162 ) -> usize {
163 let mut res = 0;
164 if let Some(slice) = o_slice {
165 self.append_partial(slice.right());
166 res += slice.len();
167 }
168 if let Some(ix) = o_index {
169 self.push(ix);
170 res += 1;
171 }
172 res
173 }
174
175 pub(crate) fn clone_append_optional_slice_and_nibble(
178 &self,
179 o_slice: Option<&NibbleSlice>,
180 o_index: Option<u8>,
181 ) -> Self {
182 let mut p = self.clone();
183 p.append_optional_slice_and_nibble(o_slice, o_index);
184 p
185 }
186
187 pub fn inner(&self) -> &[u8] {
189 &self.inner[..]
190 }
191
192 pub fn clear(&mut self) {
194 self.inner.clear();
195 self.len = 0;
196 }
197
198 pub fn as_nibbleslice(&self) -> Option<NibbleSlice> {
200 if self.len % nibble_ops::NIBBLE_PER_BYTE == 0 {
201 Some(NibbleSlice::new(self.inner()))
202 } else {
203 None
204 }
205 }
206
207 pub fn starts_with(&self, other: &Self) -> bool {
209 if self.len() < other.len() {
210 return false;
211 }
212 let byte_len = other.len() / nibble_ops::NIBBLE_PER_BYTE;
213 if &self.inner[..byte_len] != &other.inner[..byte_len] {
214 return false;
215 }
216 for pad in 0..(other.len() - byte_len * nibble_ops::NIBBLE_PER_BYTE) {
217 let self_nibble = nibble_ops::at_left(pad as u8, self.inner[byte_len]);
218 let other_nibble = nibble_ops::at_left(pad as u8, other.inner[byte_len]);
219 if self_nibble != other_nibble {
220 return false;
221 }
222 }
223 true
224 }
225}
226
227impl<'a> From<NibbleSlice<'a>> for NibbleVec {
228 fn from(s: NibbleSlice<'a>) -> Self {
229 let mut v = NibbleVec::new();
230 for i in 0..s.len() {
231 v.push(s.at(i));
232 }
233 v
234 }
235}
236
237#[cfg(test)]
238mod tests {
239 use crate::nibble::NibbleVec;
240 use crate::nibble::nibble_ops;
241
242 #[test]
243 fn push_pop() {
244 let mut v = NibbleVec::new();
245
246 for i in 0..(nibble_ops::NIBBLE_PER_BYTE * 3) {
247 let iu8 = (i % nibble_ops::NIBBLE_PER_BYTE) as u8;
248 v.push(iu8);
249 assert_eq!(v.len() - 1, i);
250 assert_eq!(v.at(i), iu8);
251 }
252
253 for i in (0..(nibble_ops::NIBBLE_PER_BYTE * 3)).rev() {
254 let iu8 = (i % nibble_ops::NIBBLE_PER_BYTE) as u8;
255 let a = v.pop();
256 assert_eq!(a, Some(iu8));
257 assert_eq!(v.len(), i);
258 }
259 }
260
261 #[test]
262 fn append_partial() {
263 append_partial_inner(&[1, 2, 3], &[], ((1, 1), &[0x23]));
264 append_partial_inner(&[1, 2, 3], &[1], ((0, 0), &[0x23]));
265 append_partial_inner(&[0, 1, 2, 3], &[0], ((1, 1), &[0x23]));
266 }
267
268 fn append_partial_inner(res: &[u8], init: &[u8], partial: ((u8, u8), &[u8])) {
269 let mut resv = NibbleVec::new();
270 res.iter().for_each(|r| resv.push(*r));
271 let mut initv = NibbleVec::new();
272 init.iter().for_each(|r| initv.push(*r));
273 initv.append_partial(partial);
274 assert_eq!(resv, initv);
275 }
276
277 #[test]
278 fn drop_lasts_test() {
279 let test_trun = |a: &[u8], b: usize, c: (&[u8], usize)| {
280 let mut k = NibbleVec::new();
281 for v in a {
282 k.push(*v);
283 }
284 k.drop_lasts(b);
285 assert_eq!((&k.inner[..], k.len), c);
286 };
287 test_trun(&[1, 2, 3, 4], 0, (&[0x12, 0x34], 4));
288 test_trun(&[1, 2, 3, 4], 1, (&[0x12, 0x30], 3));
289 test_trun(&[1, 2, 3, 4], 2, (&[0x12], 2));
290 test_trun(&[1, 2, 3, 4], 3, (&[0x10], 1));
291 test_trun(&[1, 2, 3, 4], 4, (&[], 0));
292 test_trun(&[1, 2, 3, 4], 5, (&[], 0));
293 test_trun(&[1, 2, 3], 0, (&[0x12, 0x30], 3));
294 test_trun(&[1, 2, 3], 1, (&[0x12], 2));
295 test_trun(&[1, 2, 3], 2, (&[0x10], 1));
296 test_trun(&[1, 2, 3], 3, (&[], 0));
297 test_trun(&[1, 2, 3], 4, (&[], 0));
298 }
299
300}