io_engine/buffer/
mod.rs

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