Skip to content

Commit bb5bb05

Browse files
refactor: use Vec<u8> underneath, removing the need for unsafe
1 parent 9c9a800 commit bb5bb05

File tree

2 files changed

+18
-96
lines changed

2 files changed

+18
-96
lines changed

Cargo.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ maintenance = { status = "actively-developed" }
1212
is-it-maintained-issue-resolution = { repository = "dignifiedquire/byte-pool" }
1313
is-it-maintained-open-issues = { repository = "dignifiedquire/byte-pool" }
1414

15-
[dependencies]
16-
stable_deref_trait = { version = "1.1.1", optional = true }
1715

1816
[features]
19-
default = ["stable_deref"]
20-
stable_deref = ["stable_deref_trait"]
17+
default = []

src/lib.rs

Lines changed: 17 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,22 @@
2525
//! drop(pool);
2626
//! ```
2727
28-
use std::alloc::{alloc, dealloc, handle_alloc_error, realloc, Layout};
2928
use std::fmt;
3029
use std::mem;
3130
use std::ops::{Deref, DerefMut};
32-
use std::ptr::{self, NonNull};
31+
use std::ptr;
3332
use std::sync::Mutex;
3433

3534
/// A pool of byte slices, that reuses memory.
3635
#[derive(Debug)]
3736
pub struct BytePool {
38-
list: Mutex<Vec<RawBlock>>,
37+
list: Mutex<Vec<Vec<u8>>>,
3938
}
4039

41-
pub struct RawBlock {
42-
ptr: NonNull<u8>,
43-
layout: Layout,
44-
}
45-
46-
unsafe impl Sync for RawBlock {}
47-
unsafe impl Send for RawBlock {}
48-
49-
#[cfg(feature = "stable_deref")]
50-
unsafe impl stable_deref_trait::StableDeref for RawBlock {}
40+
pub type RawBlock = Vec<u8>;
5141

5242
pub struct Block<'a> {
53-
data: mem::ManuallyDrop<RawBlock>,
43+
data: mem::ManuallyDrop<Vec<u8>>,
5444
pool: &'a BytePool,
5545
}
5646

@@ -60,12 +50,6 @@ impl fmt::Debug for Block<'_> {
6050
}
6151
}
6252

63-
impl fmt::Debug for RawBlock {
64-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65-
write!(f, "RawBlock({:?})", self.deref())
66-
}
67-
}
68-
6953
impl Default for BytePool {
7054
fn default() -> Self {
7155
BytePool {
@@ -74,13 +58,6 @@ impl Default for BytePool {
7458
}
7559
}
7660

77-
fn layout_for_size(size: usize) -> Layout {
78-
let elem_size = mem::size_of::<u8>();
79-
let alloc_size = size.checked_mul(elem_size).unwrap();
80-
let align = mem::align_of::<u8>();
81-
Layout::from_size_align(alloc_size, align).unwrap()
82-
}
83-
8461
impl BytePool {
8562
/// Constructs a new pool.
8663
pub fn new() -> Self {
@@ -98,19 +75,19 @@ impl BytePool {
9875
let start = if end > 4 { end - 4 } else { 0 };
9976

10077
for i in start..end {
101-
if lock[i].layout.size() == size {
78+
if lock[i].len() == size {
10279
// found one, reuse it
10380
return Block::new(lock.remove(i), self);
10481
}
10582
}
10683
drop(lock);
10784

10885
// allocate a new block
109-
let data = RawBlock::alloc(size);
86+
let data = vec![0u8; size];
11087
Block::new(data, self)
11188
}
11289

113-
fn push_raw_block(&self, block: RawBlock) {
90+
fn push_raw_block(&self, block: Vec<u8>) {
11491
self.list.lock().unwrap().push(block);
11592
}
11693
}
@@ -122,89 +99,34 @@ impl<'a> Drop for Block<'a> {
12299
}
123100
}
124101

125-
impl RawBlock {
126-
fn alloc(size: usize) -> Self {
127-
// TODO: consider caching the layout
128-
let layout = layout_for_size(size);
129-
debug_assert!(layout.size() > 0);
130-
131-
let ptr = unsafe { alloc(layout) };
132-
RawBlock {
133-
ptr: NonNull::new(ptr).unwrap_or_else(|| handle_alloc_error(layout)),
134-
layout,
135-
}
136-
}
137-
138-
fn grow(&mut self, new_size: usize) {
139-
// TODO: use grow_in_place once it stablizies and possibly via a flag.
140-
assert!(new_size > 0);
141-
let new_layout = Layout::from_size_align(new_size, self.layout.align()).unwrap();
142-
let new_ptr = unsafe { realloc(self.ptr.as_mut(), self.layout, new_layout.size()) };
143-
self.ptr = NonNull::new(new_ptr).unwrap_or_else(|| handle_alloc_error(self.layout));
144-
self.layout = new_layout;
145-
}
146-
147-
fn shrink(&mut self, new_size: usize) {
148-
// TODO: use shrink_in_place once it stablizies and possibly via a flag.
149-
assert!(new_size > 0);
150-
let new_layout = Layout::from_size_align(new_size, self.layout.align()).unwrap();
151-
let new_ptr = unsafe { realloc(self.ptr.as_mut(), self.layout, new_layout.size()) };
152-
self.ptr = NonNull::new(new_ptr).unwrap_or_else(|| handle_alloc_error(self.layout));
153-
self.layout = new_layout;
154-
}
155-
}
156-
157-
impl Drop for RawBlock {
158-
fn drop(&mut self) {
159-
unsafe {
160-
dealloc(self.ptr.as_mut(), self.layout);
161-
}
162-
}
163-
}
164-
165-
impl Deref for RawBlock {
166-
type Target = [u8];
167-
168-
#[inline]
169-
fn deref(&self) -> &Self::Target {
170-
unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.layout.size()) }
171-
}
172-
}
173-
174-
impl DerefMut for RawBlock {
175-
#[inline]
176-
fn deref_mut(&mut self) -> &mut Self::Target {
177-
unsafe { std::slice::from_raw_parts_mut(self.ptr.as_mut(), self.layout.size()) }
178-
}
179-
}
180-
181102
impl<'a> Block<'a> {
182-
fn new(data: RawBlock, pool: &'a BytePool) -> Self {
103+
fn new(data: Vec<u8>, pool: &'a BytePool) -> Self {
183104
Block {
184105
data: mem::ManuallyDrop::new(data),
185106
pool,
186107
}
187108
}
188109

189-
/// Resizes a block to a new size
110+
/// Resizes a block to a new size.
190111
pub fn realloc(&mut self, new_size: usize) {
191112
use std::cmp::Ordering::*;
192113

114+
assert!(new_size > 0);
193115
match new_size.cmp(&self.size()) {
194-
Greater => self.data.grow(new_size),
195-
Less => self.data.shrink(new_size),
116+
Greater => self.data.resize(new_size, 0u8),
117+
Less => self.data.truncate(new_size),
196118
Equal => {}
197119
}
198120
}
199121

200122
/// Returns the amount of bytes this block has.
201123
pub fn size(&self) -> usize {
202-
self.data.layout.size()
124+
self.data.capacity()
203125
}
204126
}
205127

206128
impl<'a> Deref for Block<'a> {
207-
type Target = [u8];
129+
type Target = Vec<u8>;
208130

209131
#[inline]
210132
fn deref(&self) -> &Self::Target {
@@ -254,6 +176,9 @@ mod tests {
254176
let pool = BytePool::new();
255177

256178
let mut buf = pool.alloc(10);
179+
180+
let _slice: &[u8] = &buf;
181+
257182
assert_eq!(buf.len(), 10);
258183
for el in buf.iter_mut() {
259184
*el = 1;

0 commit comments

Comments
 (0)