@@ -29,13 +29,14 @@ use std::fmt;
29
29
use std:: mem;
30
30
use std:: ops:: { Deref , DerefMut } ;
31
31
use std:: ptr;
32
- use std:: sync:: Mutex ;
32
+
33
+ use crossbeam_queue:: SegQueue ;
33
34
34
35
/// A pool of byte slices, that reuses memory.
35
36
#[ derive( Debug ) ]
36
37
pub struct BytePool {
37
- list_large : Mutex < Vec < Vec < u8 > > > ,
38
- list_small : Mutex < Vec < Vec < u8 > > > ,
38
+ list_large : SegQueue < Vec < u8 > > ,
39
+ list_small : SegQueue < Vec < u8 > > ,
39
40
}
40
41
41
42
/// The size at which point values are allocated in the small list, rather than the big.
@@ -58,8 +59,8 @@ impl fmt::Debug for Block<'_> {
58
59
impl Default for BytePool {
59
60
fn default ( ) -> Self {
60
61
BytePool {
61
- list_large : Mutex :: new ( Vec :: new ( ) ) ,
62
- list_small : Mutex :: new ( Vec :: new ( ) ) ,
62
+ list_large : SegQueue :: new ( ) ,
63
+ list_small : SegQueue :: new ( ) ,
63
64
}
64
65
}
65
66
}
@@ -78,22 +79,20 @@ impl BytePool {
78
79
assert ! ( size > 0 , "Can not allocate empty blocks" ) ;
79
80
80
81
// check the last 4 blocks
81
- let mut lock = if size < SPLIT_SIZE {
82
- self . list_small . lock ( ) . unwrap ( )
82
+ let list = if size < SPLIT_SIZE {
83
+ & self . list_small
83
84
} else {
84
- self . list_large . lock ( ) . unwrap ( )
85
+ & self . list_large
85
86
} ;
86
- let end = lock. len ( ) ;
87
- let start = if end > 4 { end - 4 } else { 0 } ;
88
-
89
- for i in start..end {
90
- if lock[ i] . capacity ( ) == size {
87
+ if let Ok ( el) = list. pop ( ) {
88
+ if el. capacity ( ) == size {
91
89
// found one, reuse it
92
- let data = lock. remove ( i) ;
93
- return Block :: new ( data, self ) ;
90
+ return Block :: new ( el, self ) ;
91
+ } else {
92
+ // put it back
93
+ list. push ( el) ;
94
94
}
95
95
}
96
- drop ( lock) ;
97
96
98
97
// allocate a new block
99
98
let data = vec ! [ 0u8 ; size] ;
@@ -102,9 +101,9 @@ impl BytePool {
102
101
103
102
fn push_raw_block ( & self , block : Vec < u8 > ) {
104
103
if block. capacity ( ) < SPLIT_SIZE {
105
- self . list_small . lock ( ) . unwrap ( ) . push ( block) ;
104
+ self . list_small . push ( block) ;
106
105
} else {
107
- self . list_large . lock ( ) . unwrap ( ) . push ( block) ;
106
+ self . list_large . push ( block) ;
108
107
}
109
108
}
110
109
}
@@ -241,6 +240,6 @@ mod tests {
241
240
h2. join ( ) . unwrap ( ) ;
242
241
243
242
// two threads allocating in parallel will need 2 buffers
244
- assert_eq ! ( pool. list_small. lock ( ) . unwrap ( ) . len( ) , 2 ) ;
243
+ assert ! ( pool. list_small. len( ) <= 2 ) ;
245
244
}
246
245
}
0 commit comments