1use crate::rstd::{cmp::*, fmt};
18use super::{nibble_ops, NibbleSlice, NibbleSliceIterator, BackingByteVec};
19use crate::node::NodeKey;
20use crate::node_codec::Partial;
21use tetsy_hash_db::Prefix;
22
23impl<'a> Iterator for NibbleSliceIterator<'a> {
24 type Item = u8;
25 fn next(&mut self) -> Option<u8> {
26 self.i += 1;
27 match self.i <= self.p.len() {
28 true => Some(self.p.at(self.i - 1)),
29 false => None,
30 }
31 }
32}
33
34impl<'a> NibbleSlice<'a> {
35 pub fn new(data: &'a [u8]) -> Self { NibbleSlice::new_slice(data, 0) }
37
38 pub fn new_offset(data: &'a [u8], offset: usize) -> Self {
40 Self::new_slice(data, offset)
41 }
42
43 fn new_slice(data: &'a [u8], offset: usize) -> Self {
44 NibbleSlice {
45 data,
46 offset,
47 }
48 }
49
50 pub fn iter(&'a self) -> NibbleSliceIterator<'a> {
52 NibbleSliceIterator { p: self, i: 0 }
53 }
54
55 pub fn from_stored(i: &NodeKey) -> NibbleSlice {
57 NibbleSlice::new_offset(&i.1[..], i.0)
58 }
59
60 pub fn to_stored(&self) -> NodeKey {
62 let split = self.offset / nibble_ops::NIBBLE_PER_BYTE;
63 let offset = self.offset % nibble_ops::NIBBLE_PER_BYTE;
64 (offset, self.data[split..].into())
65 }
66
67 pub fn to_stored_range(&self, nb: usize) -> NodeKey {
72 if nb >= self.len() { return self.to_stored() }
73 if (self.offset + nb) % nibble_ops::NIBBLE_PER_BYTE == 0 {
74 let start = self.offset / nibble_ops::NIBBLE_PER_BYTE;
76 let end = (self.offset + nb) / nibble_ops::NIBBLE_PER_BYTE;
77 (
78 self.offset % nibble_ops::NIBBLE_PER_BYTE,
79 BackingByteVec::from_slice(&self.data[start..end]),
80 )
81 } else {
82 let start = self.offset / nibble_ops::NIBBLE_PER_BYTE;
84 let end = (self.offset + nb) / nibble_ops::NIBBLE_PER_BYTE;
85 let ea = BackingByteVec::from_slice(&self.data[start..=end]);
86 let ea_offset = self.offset % nibble_ops::NIBBLE_PER_BYTE;
87 let n_offset = nibble_ops::number_padding(nb);
88 let mut result = (ea_offset, ea);
89 nibble_ops::shift_key(&mut result, n_offset);
90 result.1.pop();
91 result
92 }
93 }
94
95 pub fn is_empty(&self) -> bool { self.len() == 0 }
97
98 #[inline]
100 pub fn len(&self) -> usize { self.data.len() * nibble_ops::NIBBLE_PER_BYTE - self.offset }
101
102 #[inline(always)]
104 pub fn at(&self, i: usize) -> u8 {
105 nibble_ops::at(&self, i)
106 }
107
108 pub fn mid(&self, i: usize) -> NibbleSlice<'a> {
110 NibbleSlice {
111 data: self.data,
112 offset: self.offset + i,
113 }
114 }
115
116 pub fn advance(&mut self, i: usize) {
118 debug_assert!(self.len() >= i);
119 self.offset += i;
120 }
121
122 pub fn back(&self, i: usize) -> NibbleSlice<'a> {
124 NibbleSlice {
125 data: self.data,
126 offset: i,
127 }
128 }
129
130 pub fn starts_with(&self, them: &Self) -> bool { self.common_prefix(them) == them.len() }
132
133 pub fn common_prefix(&self, them: &Self) -> usize {
135 let s = min(self.len(), them.len());
136 let mut i = 0usize;
137 while i < s {
138 if self.at(i) != them.at(i) { break; }
139 i += 1;
140 }
141 i
142 }
143
144 pub fn right(&'a self) -> Partial {
147 let split = self.offset / nibble_ops::NIBBLE_PER_BYTE;
148 let nb = (self.len() % nibble_ops::NIBBLE_PER_BYTE) as u8;
149 if nb > 0 {
150 ((nb, nibble_ops::pad_right(self.data[split])), &self.data[split + 1 ..])
151 } else {
152 ((0, 0), &self.data[split..])
153 }
154 }
155
156 pub fn right_iter(&'a self) -> impl Iterator<Item = u8> + 'a {
158 let (mut first, sl) = self.right();
159 let mut ix = 0;
160 crate::rstd::iter::from_fn(move || {
161 if first.0 > 0 {
162 first.0 = 0;
163 Some(nibble_ops::pad_right(first.1))
164 } else if ix < sl.len() {
165 ix += 1;
166 Some(sl[ix - 1])
167 } else {
168 None
169 }
170 })
171 }
172
173 pub fn right_range_iter(&'a self, to: usize) -> impl Iterator<Item = u8> + 'a {
176 let mut nib_res = to % nibble_ops::NIBBLE_PER_BYTE;
177 let aligned_i = (self.offset + to) % nibble_ops::NIBBLE_PER_BYTE;
178 let aligned = aligned_i == 0;
179 let mut ix = self.offset / nibble_ops::NIBBLE_PER_BYTE;
180 let ix_lim = (self.offset + to) / nibble_ops::NIBBLE_PER_BYTE;
181 crate::rstd::iter::from_fn( move || {
182 if aligned {
183 if nib_res > 0 {
184 let v = nibble_ops::pad_right(self.data[ix]);
185 nib_res = 0;
186 ix += 1;
187 Some(v)
188 } else if ix < ix_lim {
189 ix += 1;
190 Some(self.data[ix - 1])
191 } else {
192 None
193 }
194 } else {
195 let (s1, s2) = nibble_ops::SPLIT_SHIFTS;
196 if nib_res > 0 {
198 let v = self.data[ix] >> s1;
199 let v = nibble_ops::pad_right(v);
200 nib_res = 0;
201 Some(v)
202 } else if ix < ix_lim {
203 ix += 1;
204 let b1 = self.data[ix - 1] << s2;
205 let b2 = self.data[ix] >> s1;
206 Some(b1 | b2)
207 } else {
208 None
209 }
210 }
211 })
212 }
213
214 pub fn left(&'a self) -> Prefix {
218 let split = self.offset / nibble_ops::NIBBLE_PER_BYTE;
219 let ix = (self.offset % nibble_ops::NIBBLE_PER_BYTE) as u8;
220 if ix == 0 {
221 (&self.data[..split], None)
222 } else {
223 (&self.data[..split], Some(nibble_ops::pad_left(self.data[split])))
224 }
225 }
226
227 pub fn left_owned(&'a self) -> (BackingByteVec, Option<u8>) {
229 let (a, b) = self.left();
230 (a.into(), b)
231 }
232}
233
234impl<'a> Into<NodeKey> for NibbleSlice<'a> {
235 fn into(self) -> NodeKey {
236 (self.offset, self.data.into())
237 }
238}
239
240impl<'a> PartialEq for NibbleSlice<'a> {
241 fn eq(&self, them: &Self) -> bool {
242 self.len() == them.len() && self.starts_with(them)
243 }
244}
245
246impl<'a> Eq for NibbleSlice<'a> { }
247
248impl<'a> PartialOrd for NibbleSlice<'a> {
249 fn partial_cmp(&self, them: &Self) -> Option<Ordering> {
250 Some(self.cmp(them))
251 }
252}
253
254impl<'a> Ord for NibbleSlice<'a> {
255 fn cmp(&self, them: &Self) -> Ordering {
256 let s = min(self.len(), them.len());
257 let mut i = 0usize;
258 while i < s {
259 match self.at(i).partial_cmp(&them.at(i)).unwrap() {
260 Ordering::Less => return Ordering::Less,
261 Ordering::Greater => return Ordering::Greater,
262 _ => i += 1,
263 }
264 }
265 self.len().cmp(&them.len())
266 }
267}
268
269#[cfg(feature = "std")]
270impl<'a> fmt::Debug for NibbleSlice<'a> {
271 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
272 for i in 0..self.len() {
273 match i {
274 0 => write!(f, "{:01x}", self.at(i))?,
275 _ => write!(f, "'{:01x}", self.at(i))?,
276 }
277 }
278 Ok(())
279 }
280}
281
282#[cfg(test)]
283mod tests {
284 use crate::nibble::{NibbleSlice, BackingByteVec};
285 static D: &'static [u8;3] = &[0x01u8, 0x23, 0x45];
286
287 #[test]
288 fn basics() {
289 let n = NibbleSlice::new(D);
290 assert_eq!(n.len(), 6);
291 assert!(!n.is_empty());
292
293 let n = NibbleSlice::new_offset(D, 6);
294 assert!(n.is_empty());
295
296 let n = NibbleSlice::new_offset(D, 3);
297 assert_eq!(n.len(), 3);
298 for i in 0..3 {
299 assert_eq!(n.at(i), i as u8 + 3);
300 }
301 }
302
303 #[test]
304 fn iterator() {
305 let n = NibbleSlice::new(D);
306 let mut nibbles: Vec<u8> = vec![];
307 nibbles.extend(n.iter());
308 assert_eq!(nibbles, (0u8..6).collect::<Vec<_>>())
309 }
310
311 #[test]
312 fn mid() {
313 let n = NibbleSlice::new(D);
314 let m = n.mid(2);
315 for i in 0..4 {
316 assert_eq!(m.at(i), i as u8 + 2);
317 }
318 let m = n.mid(3);
319 for i in 0..3 {
320 assert_eq!(m.at(i), i as u8 + 3);
321 }
322 }
323
324 #[test]
325 fn encoded_pre() {
326 let n = NibbleSlice::new(D);
327 assert_eq!(n.to_stored(), (0, BackingByteVec::from_slice(&[0x01, 0x23, 0x45])));
328 assert_eq!(n.mid(1).to_stored(), (1, BackingByteVec::from_slice(&[0x01, 0x23, 0x45])));
329 assert_eq!(n.mid(2).to_stored(), (0, BackingByteVec::from_slice(&[0x23, 0x45])));
330 assert_eq!(n.mid(3).to_stored(), (1, BackingByteVec::from_slice(&[0x23, 0x45])));
331 }
332
333 #[test]
334 fn from_encoded_pre() {
335 let n = NibbleSlice::new(D);
336 let stored: BackingByteVec = [0x01, 0x23, 0x45][..].into();
337 assert_eq!(n, NibbleSlice::from_stored(&(0, stored.clone())));
338 assert_eq!(n.mid(1), NibbleSlice::from_stored(&(1, stored)));
339 }
340
341 #[test]
342 fn range_iter() {
343 let n = NibbleSlice::new(D);
344 for i in [
345 vec![],
346 vec![0x00],
347 vec![0x01],
348 vec![0x00, 0x12],
349 vec![0x01, 0x23],
350 vec![0x00, 0x12, 0x34],
351 vec![0x01, 0x23, 0x45],
352 ].iter().enumerate() {
353 range_iter_test(n, i.0, None, &i.1[..]);
354 }
355 for i in [
356 vec![],
357 vec![0x01],
358 vec![0x12],
359 vec![0x01, 0x23],
360 vec![0x12, 0x34],
361 vec![0x01, 0x23, 0x45],
362 ].iter().enumerate() {
363 range_iter_test(n, i.0, Some(1), &i.1[..]);
364 }
365 for i in [
366 vec![],
367 vec![0x02],
368 vec![0x23],
369 vec![0x02, 0x34],
370 vec![0x23, 0x45],
371 ].iter().enumerate() {
372 range_iter_test(n, i.0, Some(2), &i.1[..]);
373 }
374 for i in [
375 vec![],
376 vec![0x03],
377 vec![0x34],
378 vec![0x03, 0x45],
379 ].iter().enumerate() {
380 range_iter_test(n, i.0, Some(3), &i.1[..]);
381 }
382 }
383
384 fn range_iter_test(n: NibbleSlice, nb: usize, mid: Option<usize>, res: &[u8]) {
385 let n = if let Some(i) = mid {
386 n.mid(i)
387 } else { n };
388 assert_eq!(&n.right_range_iter(nb).collect::<Vec<_>>()[..], res);
389 }
390
391 #[test]
392 fn shared() {
393 let n = NibbleSlice::new(D);
394
395 let other = &[0x01u8, 0x23, 0x01, 0x23, 0x45, 0x67];
396 let m = NibbleSlice::new(other);
397
398 assert_eq!(n.common_prefix(&m), 4);
399 assert_eq!(m.common_prefix(&n), 4);
400 assert_eq!(n.mid(1).common_prefix(&m.mid(1)), 3);
401 assert_eq!(n.mid(1).common_prefix(&m.mid(2)), 0);
402 assert_eq!(n.common_prefix(&m.mid(4)), 6);
403 assert!(!n.starts_with(&m.mid(4)));
404 assert!(m.mid(4).starts_with(&n));
405 }
406
407 #[test]
408 fn compare() {
409 let other = &[0x01u8, 0x23, 0x01, 0x23, 0x45];
410 let n = NibbleSlice::new(D);
411 let m = NibbleSlice::new(other);
412
413 assert!(n != m);
414 assert!(n > m);
415 assert!(m < n);
416
417 assert!(n == m.mid(4));
418 assert!(n >= m.mid(4));
419 assert!(n <= m.mid(4));
420 }
421}