byte_buffer/
manager.rs

1#![allow(dead_code)]
2
3use crate::buffer::{BufferPool, PoolManagement};
4use crate::channel::{self as channel};
5use crate::utils::*;
6use std::io::ErrorKind;
7use std::str;
8use std::sync::Once;
9use std::thread;
10use std::vec;
11
12static ONCE: Once = Once::new();
13
14pub struct ByteBuffer;
15
16impl ByteBuffer {
17    pub fn init(size: usize, capacity: usize) {
18        ONCE.call_once(|| {
19            let mut store = Vec::with_capacity(size);
20            let mut pool = Vec::with_capacity(size);
21
22            (0..size).for_each(|id| {
23                store.push(vec::from_elem(0, capacity));
24                pool.push(id);
25            });
26
27            let (sender, receiver) = channel::bounded(8);
28            thread::spawn(move || {
29                BufferPool::handle_work(receiver);
30            });
31
32            BufferPool::make(store, capacity, sender);
33        });
34    }
35
36    pub fn slice() -> BufferSlice {
37        match BufferPool::exec(BufOp::Reserve(true)) {
38            Some(val) => BufferSlice {
39                id: val,
40                fallback: None,
41                dirty: false,
42            },
43            None => BufferSlice {
44                id: 0,
45                fallback: Some(vec::from_elem(0, BufferPool::default_capacity())),
46                dirty: false,
47            },
48        }
49    }
50
51    pub fn try_slice() -> Option<BufferSlice> {
52        BufferPool::exec(BufOp::Reserve(false))
53            .map(|id|
54                BufferSlice {
55                    id,
56                    fallback: None,
57                    dirty: false,
58                }
59            )
60    }
61
62    #[inline]
63    pub fn extend(additional: usize) {
64        BufferPool::exec(BufOp::Extend(additional));
65    }
66}
67
68pub struct BufferSlice {
69    id: usize,
70    fallback: Option<Vec<u8>>,
71    dirty: bool,
72}
73
74impl BufferSlice {
75    pub(crate) fn new(id: usize, fallback: Option<Vec<u8>>) -> Self {
76        BufferSlice {
77            id,
78            fallback,
79            dirty: false,
80        }
81    }
82
83    pub fn as_writable(&mut self) -> &mut [u8] {
84        self.dirty = true;
85
86        if let Some(ref mut vec) = self.fallback {
87            return vec.as_mut_slice();
88        }
89
90        match BufferPool::get_writable(self.id) {
91            Ok(vec) => vec.as_mut_slice(),
92            Err(_) => {
93                self.fallback = Some(vec::from_elem(0, BufferPool::default_capacity()));
94                if let Some(ref mut vec) = self.fallback {
95                    return vec.as_mut_slice();
96                }
97
98                unreachable!();
99            }
100        }
101    }
102
103    pub fn as_writable_vec(&mut self) -> &mut Vec<u8> {
104        self.dirty = true;
105
106        if let Some(ref mut vec) = self.fallback {
107            return vec;
108        }
109
110        match BufferPool::get_writable(self.id) {
111            Ok(vec) => vec,
112            Err(_) => {
113                self.fallback = Some(vec::from_elem(0, BufferPool::default_capacity()));
114                if let Some(vec) = self.fallback.as_mut() {
115                    return vec;
116                }
117
118                unreachable!();
119            }
120        }
121    }
122
123    pub fn read(&self) -> Option<&[u8]> {
124        if let Some(ref vec) = self.fallback {
125            return Some(vec.as_slice());
126        }
127
128        match BufferPool::get_readable(self.id) {
129            Ok(vec) => Some(vec.as_slice()),
130            Err(e) => {
131                eprintln!("Failed to read the buffer: {:?}...", e);
132                None
133            }
134        }
135    }
136
137    pub fn read_as_vec(&self) -> Option<&Vec<u8>> {
138        if let Some(ref vec) = self.fallback {
139            return Some(vec);
140        }
141
142        match BufferPool::get_readable(self.id) {
143            Ok(vec) => Some(vec),
144            Err(e) => {
145                eprintln!("Failed to read the buffer: {:?}...", e);
146                None
147            }
148        }
149    }
150
151    pub fn copy_to_vec(&self) -> Vec<u8> {
152        // this will hard-copy the vec content
153        match self.read() {
154            Some(slice) => slice.to_vec(),
155            None => Vec::new(),
156        }
157    }
158
159    pub fn reset(&mut self) {
160        if !self.dirty {
161            return;
162        }
163
164        BufferPool::reset_slice(self.id);
165
166        if let Some(fb) = self.fallback.as_mut() {
167            fb.iter_mut().for_each(|val| *val = 0);
168        }
169    }
170
171    pub fn try_into_string(&self) -> Result<&str, ErrorKind> {
172        if let Some(slice) = self.read() {
173            return match str::from_utf8(slice) {
174                Ok(raw) => Ok(raw),
175                Err(_) => Err(ErrorKind::InvalidData),
176            };
177        }
178
179        Err(ErrorKind::InvalidData)
180    }
181
182    fn len(&self) -> usize {
183        BufferPool::slice_stat(self.id, SliceStatusQuery::Length)
184    }
185
186    fn capacity(&self) -> usize {
187        BufferPool::slice_stat(self.id, SliceStatusQuery::Capacity)
188    }
189}
190
191impl Drop for BufferSlice {
192    fn drop(&mut self) {
193        if self.id == 0 && self.fallback.is_some() {
194            BufferPool::exec(BufOp::ReleaseAndExtend(
195                self.fallback.take().unwrap(),
196                self.dirty,
197            ));
198        } else {
199            BufferPool::reset_and_release(self.id, self.dirty);
200        }
201    }
202}