io_engine/buffer/
mod.rs

1mod large;
2mod utils;
3use large::{BufferLarge, MIN_ALIGN};
4pub mod lz4;
5pub use utils::*;
6
7#[cfg(test)]
8mod test;
9
10use nix::errno::Errno;
11use std::{
12    fmt,
13    ops::{Deref, DerefMut},
14};
15
16use fail::fail_point;
17
18/// The Buffer enum, can obtain from alloc, wrap a raw c buffer, or convert from Vec.
19///
20/// When Clone, will copy the contain into a new Buffer.
21#[derive(Clone)]
22pub enum Buffer {
23    Large(BufferLarge),
24    Vec(Vec<u8>),
25}
26
27impl fmt::Debug for Buffer {
28    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29        write!(f, "buffer {:p} size {}", self.get_raw(), self.len())
30    }
31}
32
33impl Buffer {
34    /// Allocate aligned buffer for aio.
35    ///
36    /// NOTE: Be aware that buffer allocated will not necessarily be zeroed
37    #[inline]
38    pub fn aligned(size: usize) -> Result<Buffer, Errno> {
39        let mut _buf = BufferLarge::alloc(MIN_ALIGN, size)?;
40        fail_point!("alloc_buf", |_| {
41            rand_buffer(&mut _buf);
42            return Ok(Buffer::Large(_buf));
43        });
44        return Ok(Buffer::Large(_buf));
45    }
46
47    /// Allocate non-aligned Buffer
48    /// NOTE: Be aware that buffer allocated will not necessarily be zeroed
49    #[inline]
50    pub fn alloc(size: usize) -> Result<Buffer, Errno> {
51        let mut _buf = BufferLarge::alloc(0, size)?;
52        fail_point!("alloc_buf", |_| {
53            rand_buffer(&mut _buf);
54            return Ok(Buffer::Large(_buf));
55        });
56        return Ok(Buffer::Large(_buf));
57    }
58
59    /// Wrap a mutable buffer passed from c code without owner ship, as a fake 'static lifetime struct.
60    ///
61    /// NOTE: will not free on drop. You have to ensure the buffer valid throughout the lifecycle
62    #[inline]
63    pub fn from_c_ref_mut(ptr: *mut libc::c_void, size: usize) -> Self {
64        Self::Large(BufferLarge::from_c_ref_mut(ptr, size))
65    }
66
67    /// Wrap a const buffer passed from c code, without owner ship, as a fake 'static lifetime struct.
68    ///
69    /// NOTE: will not free on drop. You have to ensure the buffer valid throughout the lifecycle
70    #[inline]
71    pub fn from_c_ref_const(ptr: *const libc::c_void, size: usize) -> Self {
72        Self::Large(BufferLarge::from_c_ref_const(ptr, size))
73    }
74
75    #[inline(always)]
76    pub fn len(&self) -> usize {
77        match self {
78            Buffer::Large(buf) => buf.size as usize,
79            Buffer::Vec(buf) => buf.len(),
80        }
81    }
82
83    /// Get buffer raw pointer
84    #[inline]
85    pub fn get_raw(&self) -> *const u8 {
86        match self {
87            Buffer::Large(buf) => buf.buf_ptr as *const u8,
88            Buffer::Vec(buf) => buf.as_ptr(),
89        }
90    }
91
92    /// Get buffer raw mut pointer
93    #[inline]
94    pub fn get_raw_mut(&mut self) -> *mut u8 {
95        match self {
96            Buffer::Large(buf) => buf.buf_ptr as *mut u8,
97            Buffer::Vec(v) => v.as_mut_ptr(),
98        }
99    }
100
101    /// Copy from another u8 slice into self[offset..].
102    ///
103    /// NOTE: will not do memset.
104    ///
105    /// Argument:
106    ///
107    ///   offset: Address of this buffer to start filling.
108    #[inline]
109    pub fn copy_from(&mut self, offset: usize, other: &[u8]) {
110        let size = self.len();
111        let dst = self.as_mut();
112        if offset > 0 {
113            assert!(offset < size);
114            safe_copy(&mut dst[offset..], other);
115        } else {
116            safe_copy(dst, other);
117        }
118    }
119
120    /// Copy from another u8 slice into self[offset..], and memset the rest part.
121    ///
122    /// Argument:
123    ///
124    ///   offset: Address of this buffer to start filling.
125    #[inline]
126    pub fn copy_and_clean(&mut self, offset: usize, other: &[u8]) {
127        let end: usize;
128        let size = self.len();
129        let dst = self.as_mut();
130        assert!(offset < size);
131        if offset > 0 {
132            set_zero(&mut dst[0..offset]);
133            end = offset + safe_copy(&mut dst[offset..], other);
134        } else {
135            end = safe_copy(dst, other);
136        }
137        if size > end {
138            set_zero(&mut dst[end..]);
139        }
140    }
141
142    /// Fill this buffer with zero
143    #[inline]
144    pub fn zero(&mut self) {
145        set_zero(self);
146    }
147
148    /// Fill this buffer[offset..(offset+len)] with zero
149    #[inline]
150    pub fn set_zero(&mut self, offset: usize, len: usize) {
151        let _len = self.len();
152        let mut end = offset + len;
153        if end > _len {
154            end = _len;
155        }
156        let buf = self.as_mut();
157        if offset > 0 || end < _len {
158            set_zero(&mut buf[offset..end]);
159        } else {
160            set_zero(buf);
161        }
162    }
163
164    #[inline]
165    pub fn is_aligned(&self) -> bool {
166        match self {
167            Buffer::Large(buf) => buf.is_aligned(),
168            Buffer::Vec(_) => false,
169        }
170    }
171}
172
173impl Into<Vec<u8>> for Buffer {
174    fn into(self) -> Vec<u8> {
175        if let Buffer::Vec(v) = self {
176            v
177        } else {
178            unimplemented!()
179        }
180    }
181}
182
183impl From<Vec<u8>> for Buffer {
184    fn from(buf: Vec<u8>) -> Self {
185        Buffer::Vec(buf)
186    }
187}
188
189impl Deref for Buffer {
190    type Target = [u8];
191
192    #[inline]
193    fn deref(&self) -> &[u8] {
194        match self {
195            Self::Large(buf) => buf.as_ref(),
196            Self::Vec(v) => &v,
197        }
198    }
199}
200
201impl AsRef<[u8]> for Buffer {
202    #[inline]
203    fn as_ref(&self) -> &[u8] {
204        match self {
205            Self::Large(buf) => buf.as_ref(),
206            Self::Vec(v) => v.as_ref(),
207        }
208    }
209}
210
211impl AsMut<[u8]> for Buffer {
212    #[inline]
213    fn as_mut(&mut self) -> &mut [u8] {
214        match self {
215            Self::Large(buf) => buf.as_mut(),
216            Self::Vec(v) => v.as_mut(),
217        }
218    }
219}
220
221impl DerefMut for Buffer {
222    #[inline]
223    fn deref_mut(&mut self) -> &mut [u8] {
224        match self {
225            Self::Large(buf) => buf.as_mut(),
226            Self::Vec(v) => v.as_mut(),
227        }
228    }
229}