11use std:: any:: type_name;
2+ use std:: cmp:: Ordering ;
23use std:: collections:: Bound ;
34use std:: fmt:: { Debug , Formatter } ;
5+ use std:: hash:: { Hash , Hasher } ;
46use std:: ops:: { Deref , RangeBounds } ;
57
68use bytes:: { Buf , Bytes } ;
@@ -10,14 +12,40 @@ use crate::debug::TruncatedDebug;
1012use crate :: { Alignment , BufferMut , ByteBuffer } ;
1113
1214/// An immutable buffer of items of `T`.
13- #[ derive( Clone , PartialEq , Eq , PartialOrd , Hash ) ]
15+ #[ derive( Clone ) ]
1416pub struct Buffer < T > {
1517 pub ( crate ) bytes : Bytes ,
1618 pub ( crate ) length : usize ,
1719 pub ( crate ) alignment : Alignment ,
1820 pub ( crate ) _marker : std:: marker:: PhantomData < T > ,
1921}
2022
23+ impl < T > PartialEq for Buffer < T > {
24+ fn eq ( & self , other : & Self ) -> bool {
25+ self . bytes == other. bytes
26+ }
27+ }
28+
29+ impl < T > Eq for Buffer < T > { }
30+
31+ impl < T > Ord for Buffer < T > {
32+ fn cmp ( & self , other : & Self ) -> Ordering {
33+ self . bytes . cmp ( & other. bytes )
34+ }
35+ }
36+
37+ impl < T > PartialOrd for Buffer < T > {
38+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
39+ Some ( self . bytes . cmp ( & other. bytes ) )
40+ }
41+ }
42+
43+ impl < T > Hash for Buffer < T > {
44+ fn hash < H : Hasher > ( & self , state : & mut H ) {
45+ self . bytes . as_ref ( ) . hash ( state)
46+ }
47+ }
48+
2149impl < T > Buffer < T > {
2250 /// Returns a new `Buffer<T>` copied from the provided `Vec<T>`, `&[T]`, etc.
2351 ///
@@ -234,6 +262,52 @@ impl<T> Buffer<T> {
234262 }
235263 }
236264
265+ /// Returns a slice of self that is equivalent to the given subset.
266+ ///
267+ /// When processing the buffer you will often end up with &\[T\] that is a subset
268+ /// of the underlying buffer. This function turns the slice into a slice of the buffer
269+ /// it has been taken from.
270+ ///
271+ /// # Panics:
272+ /// Requires that the given sub slice is in fact contained within the Bytes buffer; otherwise this function will panic.
273+ #[ inline( always) ]
274+ pub fn slice_ref ( & self , subset : & [ T ] ) -> Self {
275+ self . slice_ref_with_alignment ( subset, Alignment :: of :: < T > ( ) )
276+ }
277+
278+ /// Returns a slice of self that is equivalent to the given subset.
279+ ///
280+ /// When processing the buffer you will often end up with &\[T\] that is a subset
281+ /// of the underlying buffer. This function turns the slice into a slice of the buffer
282+ /// it has been taken from.
283+ ///
284+ /// # Panics:
285+ /// Requires that the given sub slice is in fact contained within the Bytes buffer; otherwise this function will panic.
286+ /// Also requires that the given alignment aligns to the type of slice and is smaller or equal to the buffers alignment
287+ pub fn slice_ref_with_alignment ( & self , subset : & [ T ] , alignment : Alignment ) -> Self {
288+ if !alignment. is_aligned_to ( Alignment :: of :: < T > ( ) ) {
289+ vortex_panic ! ( "slice_ref alignment must at least align to type T" )
290+ }
291+
292+ if !self . alignment . is_aligned_to ( alignment) {
293+ vortex_panic ! ( "slice_ref subset alignment must at least align to the buffer alignment" )
294+ }
295+
296+ if subset. as_ptr ( ) . align_offset ( * alignment) != 0 {
297+ vortex_panic ! ( "slice_ref subset must be aligned to {:?}" , alignment) ;
298+ }
299+
300+ let subset_u8 =
301+ unsafe { std:: slice:: from_raw_parts ( subset. as_ptr ( ) . cast ( ) , size_of_val ( subset) ) } ;
302+
303+ Self {
304+ bytes : self . bytes . slice_ref ( subset_u8) ,
305+ length : subset. len ( ) ,
306+ alignment,
307+ _marker : Default :: default ( ) ,
308+ }
309+ }
310+
237311 /// Returns the underlying aligned buffer.
238312 pub fn into_inner ( self ) -> Bytes {
239313 self . bytes
0 commit comments