1use super::{nibble_ops, BackingByteVec, NibbleSlice, NibbleSliceIterator, NibbleVec};
18#[cfg(feature = "std")]
19use crate::rstd::fmt;
20use crate::{node::NodeKey, node_codec::Partial, rstd::cmp::*};
21use 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 {
37 NibbleSlice::new_slice(data, 0)
38 }
39
40 pub fn new_offset(data: &'a [u8], offset: usize) -> Self {
42 Self::new_slice(data, offset)
43 }
44
45 fn new_slice(data: &'a [u8], offset: usize) -> Self {
46 NibbleSlice { data, offset }
47 }
48
49 pub fn iter(&'a self) -> NibbleSliceIterator<'a> {
51 NibbleSliceIterator { p: self, i: 0 }
52 }
53
54 pub fn from_stored(i: &NodeKey) -> NibbleSlice {
56 NibbleSlice::new_offset(&i.1[..], i.0)
57 }
58
59 pub fn to_stored(&self) -> NodeKey {
61 let split = self.offset / nibble_ops::NIBBLE_PER_BYTE;
62 let offset = self.offset % nibble_ops::NIBBLE_PER_BYTE;
63 (offset, self.data[split..].into())
64 }
65
66 pub fn to_stored_range(&self, nb: usize) -> NodeKey {
71 if nb >= self.len() {
72 return self.to_stored()
73 }
74 if (self.offset + nb) % nibble_ops::NIBBLE_PER_BYTE == 0 {
75 let start = self.offset / nibble_ops::NIBBLE_PER_BYTE;
77 let end = (self.offset + nb) / nibble_ops::NIBBLE_PER_BYTE;
78 (
79 self.offset % nibble_ops::NIBBLE_PER_BYTE,
80 BackingByteVec::from_slice(&self.data[start..end]),
81 )
82 } else {
83 let start = self.offset / nibble_ops::NIBBLE_PER_BYTE;
85 let end = (self.offset + nb) / nibble_ops::NIBBLE_PER_BYTE;
86 let ea = BackingByteVec::from_slice(&self.data[start..=end]);
87 let ea_offset = self.offset % nibble_ops::NIBBLE_PER_BYTE;
88 let n_offset = nibble_ops::number_padding(nb);
89 let mut result = (ea_offset, ea);
90 nibble_ops::shift_key(&mut result, n_offset);
91 result.1.pop();
92 result
93 }
94 }
95
96 pub fn is_empty(&self) -> bool {
98 self.len() == 0
99 }
100
101 #[inline]
103 pub fn len(&self) -> usize {
104 self.data.len() * nibble_ops::NIBBLE_PER_BYTE - self.offset
105 }
106
107 #[inline(always)]
109 pub fn at(&self, i: usize) -> u8 {
110 nibble_ops::at(&self, i)
111 }
112
113 pub fn mid(&self, i: usize) -> NibbleSlice<'a> {
115 NibbleSlice { data: self.data, offset: self.offset + i }
116 }
117
118 pub fn advance(&mut self, i: usize) {
120 debug_assert!(self.len() >= i);
121 self.offset += i;
122 }
123
124 pub fn back(&self, i: usize) -> NibbleSlice<'a> {
126 NibbleSlice { data: self.data, offset: i }
127 }
128
129 pub fn starts_with(&self, them: &Self) -> bool {
131 self.common_prefix(them) == them.len()
132 }
133
134 pub fn common_prefix(&self, them: &Self) -> usize {
136 let self_align = self.offset % nibble_ops::NIBBLE_PER_BYTE;
137 let them_align = them.offset % nibble_ops::NIBBLE_PER_BYTE;
138 if self_align == them_align {
139 let mut self_start = self.offset / nibble_ops::NIBBLE_PER_BYTE;
140 let mut them_start = them.offset / nibble_ops::NIBBLE_PER_BYTE;
141 let mut first = 0;
142 if self_align != 0 {
143 if nibble_ops::pad_right(self.data[self_start]) !=
144 nibble_ops::pad_right(them.data[them_start])
145 {
146 return 0
148 }
149 self_start += 1;
150 them_start += 1;
151 first += 1;
152 }
153 nibble_ops::biggest_depth(&self.data[self_start..], &them.data[them_start..]) + first
154 } else {
155 let s = min(self.len(), them.len());
156 let mut i = 0usize;
157 while i < s {
158 if self.at(i) != them.at(i) {
159 break
160 }
161 i += 1;
162 }
163 i
164 }
165 }
166
167 pub fn right(&'a self) -> Partial {
170 let split = self.offset / nibble_ops::NIBBLE_PER_BYTE;
171 let nb = (self.len() % nibble_ops::NIBBLE_PER_BYTE) as u8;
172 if nb > 0 {
173 ((nb, nibble_ops::pad_right(self.data[split])), &self.data[split + 1..])
174 } else {
175 ((0, 0), &self.data[split..])
176 }
177 }
178
179 pub fn right_iter(&'a self) -> impl Iterator<Item = u8> + 'a {
181 let (mut first, sl) = self.right();
182 let mut ix = 0;
183 crate::rstd::iter::from_fn(move || {
184 if first.0 > 0 {
185 first.0 = 0;
186 Some(nibble_ops::pad_right(first.1))
187 } else if ix < sl.len() {
188 ix += 1;
189 Some(sl[ix - 1])
190 } else {
191 None
192 }
193 })
194 }
195
196 pub fn right_range_iter(&'a self, to: usize) -> impl Iterator<Item = u8> + 'a {
199 let mut nib_res = to % nibble_ops::NIBBLE_PER_BYTE;
200 let aligned_i = (self.offset + to) % nibble_ops::NIBBLE_PER_BYTE;
201 let aligned = aligned_i == 0;
202 let mut ix = self.offset / nibble_ops::NIBBLE_PER_BYTE;
203 let ix_lim = (self.offset + to) / nibble_ops::NIBBLE_PER_BYTE;
204 crate::rstd::iter::from_fn(move || {
205 if aligned {
206 if nib_res > 0 {
207 let v = nibble_ops::pad_right(self.data[ix]);
208 nib_res = 0;
209 ix += 1;
210 Some(v)
211 } else if ix < ix_lim {
212 ix += 1;
213 Some(self.data[ix - 1])
214 } else {
215 None
216 }
217 } else {
218 let (s1, s2) = nibble_ops::SPLIT_SHIFTS;
219 if nib_res > 0 {
221 let v = self.data[ix] >> s1;
222 let v = nibble_ops::pad_right(v);
223 nib_res = 0;
224 Some(v)
225 } else if ix < ix_lim {
226 ix += 1;
227 let b1 = self.data[ix - 1] << s2;
228 let b2 = self.data[ix] >> s1;
229 Some(b1 | b2)
230 } else {
231 None
232 }
233 }
234 })
235 }
236
237 pub fn left(&'a self) -> Prefix {
241 let split = self.offset / nibble_ops::NIBBLE_PER_BYTE;
242 let ix = (self.offset % nibble_ops::NIBBLE_PER_BYTE) as u8;
243 if ix == 0 {
244 (&self.data[..split], None)
245 } else {
246 (&self.data[..split], Some(nibble_ops::pad_left(self.data[split])))
247 }
248 }
249
250 pub fn original_data_as_prefix(&self) -> Prefix {
254 (&self.data, None)
255 }
256
257 pub fn left_owned(&'a self) -> (BackingByteVec, Option<u8>) {
259 let (a, b) = self.left();
260 (a.into(), b)
261 }
262
263 pub fn starts_with_vec(&self, other: &NibbleVec) -> bool {
265 if self.len() < other.len() {
266 return false
267 }
268
269 match other.as_nibbleslice() {
270 Some(other) => self.starts_with(&other),
271 None => {
272 for i in 0..other.len() {
273 if self.at(i) != other.at(i) {
274 return false
275 }
276 }
277 true
278 },
279 }
280 }
281}
282
283impl<'a> From<NibbleSlice<'a>> for NodeKey {
284 fn from(slice: NibbleSlice<'a>) -> NodeKey {
285 (slice.offset, slice.data.into())
286 }
287}
288
289impl<'a> PartialEq for NibbleSlice<'a> {
290 fn eq(&self, them: &Self) -> bool {
291 self.len() == them.len() && self.starts_with(them)
292 }
293}
294
295impl<'a> PartialEq<NibbleVec> for NibbleSlice<'a> {
296 fn eq(&self, other: &NibbleVec) -> bool {
297 if self.len() != other.len() {
298 return false
299 }
300
301 match other.as_nibbleslice() {
302 Some(other) => *self == other,
303 None => self.iter().enumerate().all(|(index, l)| l == other.at(index)),
304 }
305 }
306}
307
308impl<'a> Eq for NibbleSlice<'a> {}
309
310impl<'a> PartialOrd for NibbleSlice<'a> {
311 fn partial_cmp(&self, them: &Self) -> Option<Ordering> {
312 Some(self.cmp(them))
313 }
314}
315
316impl<'a> Ord for NibbleSlice<'a> {
317 fn cmp(&self, them: &Self) -> Ordering {
318 let s = min(self.len(), them.len());
319 let mut i = 0usize;
320 while i < s {
321 match self.at(i).partial_cmp(&them.at(i)).unwrap() {
322 Ordering::Less => return Ordering::Less,
323 Ordering::Greater => return Ordering::Greater,
324 _ => i += 1,
325 }
326 }
327 self.len().cmp(&them.len())
328 }
329}
330
331#[cfg(feature = "std")]
332impl<'a> fmt::Debug for NibbleSlice<'a> {
333 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
334 for i in 0..self.len() {
335 match i {
336 0 => write!(f, "{:01x}", self.at(i))?,
337 _ => write!(f, "'{:01x}", self.at(i))?,
338 }
339 }
340 Ok(())
341 }
342}
343
344#[cfg(test)]
345mod tests {
346 use crate::nibble::{BackingByteVec, NibbleSlice};
347 static D: &'static [u8; 3] = &[0x01u8, 0x23, 0x45];
348
349 #[test]
350 fn basics() {
351 let n = NibbleSlice::new(D);
352 assert_eq!(n.len(), 6);
353 assert!(!n.is_empty());
354
355 let n = NibbleSlice::new_offset(D, 6);
356 assert!(n.is_empty());
357
358 let n = NibbleSlice::new_offset(D, 3);
359 assert_eq!(n.len(), 3);
360 for i in 0..3 {
361 assert_eq!(n.at(i), i as u8 + 3);
362 }
363 }
364
365 #[test]
366 fn iterator() {
367 let n = NibbleSlice::new(D);
368 let mut nibbles: Vec<u8> = vec![];
369 nibbles.extend(n.iter());
370 assert_eq!(nibbles, (0u8..6).collect::<Vec<_>>())
371 }
372
373 #[test]
374 fn mid() {
375 let n = NibbleSlice::new(D);
376 let m = n.mid(2);
377 for i in 0..4 {
378 assert_eq!(m.at(i), i as u8 + 2);
379 }
380 let m = n.mid(3);
381 for i in 0..3 {
382 assert_eq!(m.at(i), i as u8 + 3);
383 }
384 }
385
386 #[test]
387 fn encoded_pre() {
388 let n = NibbleSlice::new(D);
389 assert_eq!(n.to_stored(), (0, BackingByteVec::from_slice(&[0x01, 0x23, 0x45])));
390 assert_eq!(n.mid(1).to_stored(), (1, BackingByteVec::from_slice(&[0x01, 0x23, 0x45])));
391 assert_eq!(n.mid(2).to_stored(), (0, BackingByteVec::from_slice(&[0x23, 0x45])));
392 assert_eq!(n.mid(3).to_stored(), (1, BackingByteVec::from_slice(&[0x23, 0x45])));
393 }
394
395 #[test]
396 fn from_encoded_pre() {
397 let n = NibbleSlice::new(D);
398 let stored: BackingByteVec = [0x01, 0x23, 0x45][..].into();
399 assert_eq!(n, NibbleSlice::from_stored(&(0, stored.clone())));
400 assert_eq!(n.mid(1), NibbleSlice::from_stored(&(1, stored)));
401 }
402
403 #[test]
404 fn range_iter() {
405 let n = NibbleSlice::new(D);
406 for i in [
407 vec![],
408 vec![0x00],
409 vec![0x01],
410 vec![0x00, 0x12],
411 vec![0x01, 0x23],
412 vec![0x00, 0x12, 0x34],
413 vec![0x01, 0x23, 0x45],
414 ]
415 .iter()
416 .enumerate()
417 {
418 range_iter_test(n, i.0, None, &i.1[..]);
419 }
420 for i in [
421 vec![],
422 vec![0x01],
423 vec![0x12],
424 vec![0x01, 0x23],
425 vec![0x12, 0x34],
426 vec![0x01, 0x23, 0x45],
427 ]
428 .iter()
429 .enumerate()
430 {
431 range_iter_test(n, i.0, Some(1), &i.1[..]);
432 }
433 for i in [vec![], vec![0x02], vec![0x23], vec![0x02, 0x34], vec![0x23, 0x45]]
434 .iter()
435 .enumerate()
436 {
437 range_iter_test(n, i.0, Some(2), &i.1[..]);
438 }
439 for i in [vec![], vec![0x03], vec![0x34], vec![0x03, 0x45]].iter().enumerate() {
440 range_iter_test(n, i.0, Some(3), &i.1[..]);
441 }
442 }
443
444 fn range_iter_test(n: NibbleSlice, nb: usize, mid: Option<usize>, res: &[u8]) {
445 let n = if let Some(i) = mid { n.mid(i) } else { n };
446 assert_eq!(&n.right_range_iter(nb).collect::<Vec<_>>()[..], res);
447 }
448
449 #[test]
450 fn shared() {
451 let n = NibbleSlice::new(D);
452
453 let other = &[0x01u8, 0x23, 0x01, 0x23, 0x45, 0x67];
454 let m = NibbleSlice::new(other);
455
456 assert_eq!(n.common_prefix(&m), 4);
457 assert_eq!(m.common_prefix(&n), 4);
458 assert_eq!(n.mid(1).common_prefix(&m.mid(1)), 3);
459 assert_eq!(n.mid(1).common_prefix(&m.mid(2)), 0);
460 assert_eq!(n.common_prefix(&m.mid(4)), 6);
461 assert!(!n.starts_with(&m.mid(4)));
462 assert!(m.mid(4).starts_with(&n));
463 }
464
465 #[test]
466 fn compare() {
467 let other = &[0x01u8, 0x23, 0x01, 0x23, 0x45];
468 let n = NibbleSlice::new(D);
469 let m = NibbleSlice::new(other);
470
471 assert!(n != m);
472 assert!(n > m);
473 assert!(m < n);
474
475 assert!(n == m.mid(4));
476 assert!(n >= m.mid(4));
477 assert!(n <= m.mid(4));
478 }
479}