timely_bytes/
lib.rs

1//! A simplified implementation of the `bytes` crate, with different features, less safety.
2//!
3//! The crate is currently minimalist rather than maximalist, and for example does not support
4//! methods on `BytesMut` that seem like they should be safe, because they are not yet needed.
5//! For example, `BytesMut` should be able to implement `Send`, and `BytesMut::extract_to` could
6//! return a `BytesMut` rather than a `Bytes`.
7//!
8//! # Examples
9//!
10//! ```
11//! use timely_bytes::arc::BytesMut;
12//!
13//! let bytes = vec![0u8; 1024];
14//! let mut shared1 = BytesMut::from(bytes);
15//! let mut shared2 = shared1.extract_to(100);
16//! let mut shared3 = shared1.extract_to(100);
17//! let mut shared4 = shared2.extract_to(60);
18//!
19//! assert_eq!(shared1.len(), 824);
20//! assert_eq!(shared2.len(), 40);
21//! assert_eq!(shared3.len(), 100);
22//! assert_eq!(shared4.len(), 60);
23//!
24//! for byte in shared1.iter_mut() { *byte = 1u8; }
25//!
26//! // memory in slabs [4, 2, 3, 1]: merge back in arbitrary order.
27//! shared2.try_merge(shared3).ok().expect("Failed to merge 2 and 3");
28//! shared2.try_merge(shared1.freeze()).ok().expect("Failed to merge 23 and 1");
29//! shared4.try_merge(shared2).ok().expect("Failed to merge 4 and 231");
30//!
31//! assert_eq!(shared4.len(), 1024);
32//! ```
33#![forbid(missing_docs)]
34
35/// An `Arc`-backed mutable byte slice backed by a common allocation.
36pub mod arc {
37
38    use std::ops::{Deref, DerefMut};
39    use std::sync::Arc;
40    use std::any::Any;
41
42    /// A thread-safe byte buffer backed by a shared allocation.
43    ///
44    /// An instance of this type contends that `ptr` is valid for `len` bytes,
45    /// and that no other reference to these bytes exists, other than through
46    /// the type currently held in `sequestered`.
47    pub struct BytesMut {
48        /// Pointer to the start of this slice (not the allocation).
49        ptr: *mut u8,
50        /// Length of this slice.
51        len: usize,
52        /// Shared access to underlying resources.
53        ///
54        /// Importantly, this is unavailable for as long as the struct exists, which may
55        /// prevent shared access to ptr[0 .. len]. I'm not sure I understand Rust's rules
56        /// enough to make a stronger statement about this.
57        sequestered: Arc<dyn Any>,
58    }
59
60    impl BytesMut {
61
62        /// Create a new instance from a byte allocation.
63        pub fn from<B>(bytes: B) -> BytesMut where B : DerefMut<Target=[u8]>+'static {
64
65            // Sequester allocation behind an `Arc`, which *should* keep the address
66            // stable for the lifetime of `sequestered`. The `Arc` also serves as our
67            // source of truth for the allocation, which we use to re-connect slices
68            // of the same allocation.
69            let mut sequestered = Arc::new(bytes) as Arc<dyn Any>;
70            let (ptr, len) =
71            Arc::get_mut(&mut sequestered)
72                .unwrap()
73                .downcast_mut::<B>()
74                .map(|a| (a.as_mut_ptr(), a.len()))
75                .unwrap();
76
77            BytesMut {
78                ptr,
79                len,
80                sequestered,
81            }
82        }
83
84        /// Extracts [0, index) into a new `Bytes` which is returned, updating `self`.
85        ///
86        /// # Safety
87        ///
88        /// This method first tests `index` against `self.len`, which should ensure that both
89        /// the returned `Bytes` contains valid memory, and that `self` can no longer access it.
90        pub fn extract_to(&mut self, index: usize) -> Bytes {
91
92            assert!(index <= self.len);
93
94            let result = BytesMut {
95                ptr: self.ptr,
96                len: index,
97                sequestered: Arc::clone(&self.sequestered),
98            };
99
100            self.ptr = self.ptr.wrapping_add(index);
101            self.len -= index;
102
103            result.freeze()
104        }
105
106        /// Regenerates the BytesMut if it is uniquely held.
107        ///
108        /// If uniquely held, this method recovers the initial pointer and length
109        /// of the sequestered allocation and re-initializes the BytesMut. The return
110        /// value indicates whether this occurred.
111        ///
112        /// # Examples
113        ///
114        /// ```
115        /// use timely_bytes::arc::BytesMut;
116        ///
117        /// let bytes = vec![0u8; 1024];
118        /// let mut shared1 = BytesMut::from(bytes);
119        /// let mut shared2 = shared1.extract_to(100);
120        /// let mut shared3 = shared1.extract_to(100);
121        /// let mut shared4 = shared2.extract_to(60);
122        ///
123        /// drop(shared3);
124        /// drop(shared2);
125        /// drop(shared4);
126        /// assert!(shared1.try_regenerate::<Vec<u8>>());
127        /// assert!(shared1.len() == 1024);
128        /// ```
129        pub fn try_regenerate<B>(&mut self) -> bool where B: DerefMut<Target=[u8]>+'static {
130            // Only possible if this is the only reference to the sequestered allocation.
131            if let Some(boxed) = Arc::get_mut(&mut self.sequestered) {
132                let downcast = boxed.downcast_mut::<B>().expect("Downcast failed");
133                self.ptr = downcast.as_mut_ptr();
134                self.len = downcast.len();
135                true
136            }
137            else {
138                false
139            }
140        }
141
142        /// Converts a writeable byte slice to a shareable byte slice.
143        #[inline(always)]
144        pub fn freeze(self) -> Bytes {
145            Bytes {
146                ptr: self.ptr,
147                len: self.len,
148                sequestered: self.sequestered,
149            }
150        }
151    }
152
153    impl Deref for BytesMut {
154        type Target = [u8];
155        #[inline(always)]
156        fn deref(&self) -> &[u8] {
157            unsafe { ::std::slice::from_raw_parts(self.ptr, self.len) }
158        }
159    }
160
161    impl DerefMut for BytesMut {
162        #[inline(always)]
163        fn deref_mut(&mut self) -> &mut [u8] {
164            unsafe { ::std::slice::from_raw_parts_mut(self.ptr, self.len) }
165        }
166    }
167
168
169    /// A thread-safe shared byte buffer backed by a shared allocation.
170    ///
171    /// An instance of this type contends that `ptr` is valid for `len` bytes,
172    /// and that no other mutable reference to these bytes exists, other than
173    /// through the type currently held in `sequestered`.
174    #[derive(Clone)]
175    pub struct Bytes {
176        /// Pointer to the start of this slice (not the allocation).
177        ptr: *const u8,
178        /// Length of this slice.
179        len: usize,
180        /// Shared access to underlying resources.
181        ///
182        /// Importantly, this is unavailable for as long as the struct exists, which may
183        /// prevent shared access to ptr[0 .. len]. I'm not sure I understand Rust's rules
184        /// enough to make a stronger statement about this.
185        sequestered: Arc<dyn Any>,
186    }
187
188    // Synchronization happens through `self.sequestered`, which means to ensure that even
189    // across multiple threads the referenced range of bytes remain valid.
190    unsafe impl Send for Bytes { }
191
192    impl Bytes {
193
194        /// Extracts [0, index) into a new `Bytes` which is returned, updating `self`.
195        ///
196        /// # Safety
197        ///
198        /// This method first tests `index` against `self.len`, which should ensure that both
199        /// the returned `Bytes` contains valid memory, and that `self` can no longer access it.
200        pub fn extract_to(&mut self, index: usize) -> Bytes {
201
202            assert!(index <= self.len);
203
204            let result = Bytes {
205                ptr: self.ptr,
206                len: index,
207                sequestered: Arc::clone(&self.sequestered),
208            };
209
210            self.ptr = self.ptr.wrapping_add(index);
211            self.len -= index;
212
213            result
214        }
215
216        /// Attempts to merge adjacent slices from the same allocation.
217        ///
218        /// If the merge succeeds then `other.len` is added to `self` and the result is `Ok(())`.
219        /// If the merge fails self is unmodified and the result is `Err(other)`, returning the
220        /// bytes supplied as input.
221        ///
222        /// # Examples
223        ///
224        /// ```
225        /// use timely_bytes::arc::BytesMut;
226        ///
227        /// let bytes = vec![0u8; 1024];
228        /// let mut shared1 = BytesMut::from(bytes).freeze();
229        /// let mut shared2 = shared1.extract_to(100);
230        /// let mut shared3 = shared1.extract_to(100);
231        /// let mut shared4 = shared2.extract_to(60);
232        ///
233        /// // memory in slabs [4, 2, 3, 1]: merge back in arbitrary order.
234        /// shared2.try_merge(shared3).ok().expect("Failed to merge 2 and 3");
235        /// shared2.try_merge(shared1).ok().expect("Failed to merge 23 and 1");
236        /// shared4.try_merge(shared2).ok().expect("Failed to merge 4 and 231");
237        /// ```
238        pub fn try_merge(&mut self, other: Bytes) -> Result<(), Bytes> {
239            if Arc::ptr_eq(&self.sequestered, &other.sequestered) && ::std::ptr::eq(self.ptr.wrapping_add(self.len), other.ptr) {
240                self.len += other.len;
241                Ok(())
242            }
243            else {
244                Err(other)
245            }
246        }
247    }
248
249    impl Deref for Bytes {
250        type Target = [u8];
251        #[inline(always)]
252        fn deref(&self) -> &[u8] {
253            unsafe { ::std::slice::from_raw_parts(self.ptr, self.len) }
254        }
255    }
256}