@@ -56,6 +56,14 @@ impl<T: Poolable> BytePool<T> {
5656 /// The returned `Block` contains arbitrary data, and must be zeroed or overwritten,
5757 /// in cases this is needed.
5858 pub fn alloc ( & self , size : usize ) -> Block < ' _ , T > {
59+ self . alloc_internal ( size, false )
60+ }
61+
62+ pub fn alloc_and_fill ( & self , size : usize ) -> Block < ' _ , T > {
63+ self . alloc_internal ( size, true )
64+ }
65+
66+ pub fn alloc_internal ( & self , size : usize , fill : bool ) -> Block < ' _ , T > {
5967 assert ! ( size > 0 , "Can not allocate empty blocks" ) ;
6068
6169 // check the last 4 blocks
@@ -64,9 +72,12 @@ impl<T: Poolable> BytePool<T> {
6472 } else {
6573 & self . list_large
6674 } ;
67- if let Some ( el) = list. pop ( ) {
68- if el. capacity ( ) == size {
75+ if let Some ( mut el) = list. pop ( ) {
76+ if el. capacity ( ) >= size && el . capacity ( ) < size + 1024 {
6977 // found one, reuse it
78+ if fill {
79+ el. resize ( size)
80+ }
7081 return Block :: new ( el, self ) ;
7182 } else {
7283 // put it back
@@ -75,7 +86,11 @@ impl<T: Poolable> BytePool<T> {
7586 }
7687
7788 // allocate a new block
78- let data = T :: alloc ( size) ;
89+ let data = if fill {
90+ T :: alloc_and_fill ( size)
91+ } else {
92+ T :: alloc ( size)
93+ } ;
7994 Block :: new ( data, self )
8095 }
8196
@@ -90,7 +105,8 @@ impl<T: Poolable> BytePool<T> {
90105
91106impl < ' a , T : Poolable > Drop for Block < ' a , T > {
92107 fn drop ( & mut self ) {
93- let data = mem:: ManuallyDrop :: into_inner ( unsafe { ptr:: read ( & self . data ) } ) ;
108+ let mut data = mem:: ManuallyDrop :: into_inner ( unsafe { ptr:: read ( & self . data ) } ) ;
109+ data. reset ( ) ;
94110 self . pool . push_raw_block ( data) ;
95111 }
96112}
@@ -138,6 +154,41 @@ unsafe impl<'a, T: StableDeref + Poolable> StableDeref for Block<'a, T> {}
138154#[ cfg( test) ]
139155mod tests {
140156 use super :: * ;
157+ #[ test]
158+ fn append ( ) {
159+ let pool = BytePool :: < Vec < u8 > > :: new ( ) ;
160+ let mut buf = pool. alloc ( 4 ) ;
161+ assert_eq ! ( 0 , buf. len( ) ) ;
162+ assert_eq ! ( 4 , buf. capacity( ) ) ;
163+ buf. push ( 12u8 ) ;
164+ assert_eq ! ( 1 , buf. len( ) ) ;
165+ buf. extend_from_slice ( "hello" . as_bytes ( ) ) ;
166+ assert_eq ! ( 6 , buf. len( ) ) ;
167+ buf. clear ( ) ;
168+ assert_eq ! ( 0 , buf. len( ) ) ;
169+ assert ! ( buf. capacity( ) > 0 ) ;
170+ }
171+
172+ #[ test]
173+ fn len_and_capacity ( ) {
174+ let pool = BytePool :: < Vec < u8 > > :: new ( ) ;
175+ for i in 1 ..10 {
176+ let buf = pool. alloc_and_fill ( i) ;
177+ assert_eq ! ( buf. len( ) , i)
178+ }
179+ for i in 1 ..10 {
180+ let buf = pool. alloc ( i) ;
181+ assert_eq ! ( buf. len( ) , 0 )
182+ }
183+ for i in 1 ..10 {
184+ let buf = pool. alloc_and_fill ( i * 10000 ) ;
185+ assert_eq ! ( buf. len( ) , i * 10000 )
186+ }
187+ for i in 1 ..10 {
188+ let buf = pool. alloc ( i * 10000 ) ;
189+ assert_eq ! ( buf. len( ) , 0 )
190+ }
191+ }
141192
142193 #[ test]
143194 fn basics_vec_u8 ( ) {
@@ -174,6 +225,7 @@ mod tests {
174225 let _slice: & [ u8 ] = & buf;
175226
176227 assert_eq ! ( buf. capacity( ) , 10 ) ;
228+ buf. resize ( 10 , 0 ) ;
177229 for i in 0 ..10 {
178230 buf[ i] = 1 ;
179231 }
@@ -198,15 +250,15 @@ mod tests {
198250 let pool1 = pool. clone ( ) ;
199251 let h1 = std:: thread:: spawn ( move || {
200252 for _ in 0 ..100 {
201- let mut buf = pool1. alloc ( 64 ) ;
253+ let mut buf = pool1. alloc_and_fill ( 64 ) ;
202254 buf[ 10 ] = 10 ;
203255 }
204256 } ) ;
205257
206258 let pool2 = pool. clone ( ) ;
207259 let h2 = std:: thread:: spawn ( move || {
208260 for _ in 0 ..100 {
209- let mut buf = pool2. alloc ( 64 ) ;
261+ let mut buf = pool2. alloc_and_fill ( 64 ) ;
210262 buf[ 10 ] = 10 ;
211263 }
212264 } ) ;
0 commit comments