1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
use std::{ cmp::Ordering, ops::{Deref, DerefMut}, }; #[derive(Copy, Clone, Debug, Hash)] pub struct Segment<Inner = sled::IVec> { inner: Inner, start: usize, end: usize, } impl PartialEq for Segment { fn eq(&self, other: &Self) -> bool { self.as_ref().eq(other.as_ref()) } } impl Eq for Segment {} impl PartialOrd for Segment { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } } impl Ord for Segment { fn cmp(&self, other: &Self) -> Ordering { self.as_ref().cmp(other.as_ref()) } } impl<Inner: AsRef<[u8]>> From<Inner> for Segment<Inner> { #[inline(always)] fn from(inner: Inner) -> Self { Segment::new(inner) } } impl<Inner: AsRef<[u8]>> AsRef<[u8]> for Segment<Inner> { #[inline(always)] fn as_ref(&self) -> &[u8] { self.guard_validate(); unsafe { self.inner.as_ref().get_unchecked(self.start..self.end) } } } impl<Inner: AsRef<[u8]>> Deref for Segment<Inner> { type Target = [u8]; #[inline(always)] fn deref(&self) -> &[u8] { self.as_ref() } } impl<Inner: AsRef<[u8]> + DerefMut<Target = [u8]>> DerefMut for Segment<Inner> { #[inline(always)] fn deref_mut(&mut self) -> &mut [u8] { self.guard_validate(); unsafe { self.inner .deref_mut() .get_unchecked_mut(self.start..self.end) } } } impl<Inner: AsRef<[u8]>> Segment<Inner> { #[inline(always)] pub fn new(inner: Inner) -> Self { let end = inner.as_ref().len(); Self { inner, start: 0, end, } } #[inline(always)] fn guard_validate(&self) { debug_assert!(self.start <= self.inner.as_ref().len()); debug_assert!(self.end <= self.inner.as_ref().len()); } } impl<Inner: AsRef<[u8]> + Clone> Segment<Inner> { #[inline(always)] pub fn split_off(&mut self, at: usize) -> Self { assert!(at <= self.len()); let new = Segment { inner: self.inner.clone(), start: self.start + at, end: self.end, }; self.end = self.start + at; new } }