33
44use std:: mem:: size_of;
55use std:: cell:: Cell ;
6+ use std:: borrow:: Cow ;
67
78const ARENA_BLOCK : usize = 64 * 1024 ;
89
@@ -16,7 +17,7 @@ const ARENA_BLOCK: usize = 64 * 1024;
1617pub struct Arena {
1718 store : Cell < Vec < Vec < u8 > > > ,
1819 ptr : Cell < * mut u8 > ,
19- offset : Cell < usize >
20+ offset : Cell < usize > ,
2021}
2122
2223/// A pointer to an uninitialized region of memory.
@@ -77,7 +78,51 @@ impl Arena {
7778 Arena {
7879 store : Cell :: new ( store) ,
7980 ptr : Cell :: new ( ptr) ,
80- offset : Cell :: new ( 0 )
81+ offset : Cell :: new ( 0 ) ,
82+ }
83+ }
84+
85+ /// Allocate many items at once, without reallocating
86+ #[ inline]
87+ pub fn alloc_many < ' input , ' output , T : Sized + Copy + ' input , V : Into < Cow < ' input , [ T ] > > > (
88+ & ' output self ,
89+ vals : V ,
90+ ) -> & ' output [ T ] {
91+ use std:: { mem, ptr, slice} ;
92+
93+ let vals = vals. into ( ) ;
94+
95+ if vals. as_ref ( ) . is_empty ( ) {
96+ return & [ ] ;
97+ }
98+
99+ let len = vals. as_ref ( ) . len ( ) ;
100+ let bytes = len * mem:: size_of :: < T > ( ) ;
101+
102+ match vals {
103+ Cow :: Owned ( mut vec) => {
104+ let p = vec. as_mut_ptr ( ) ;
105+ let cap = vec. capacity ( ) ;
106+
107+ mem:: forget ( vec) ;
108+
109+ let out = self . alloc_vec ( unsafe {
110+ Vec :: from_raw_parts (
111+ p as _ ,
112+ len * mem:: size_of :: < T > ( ) ,
113+ cap * mem:: size_of :: < T > ( ) ,
114+ )
115+ } ) ;
116+
117+ unsafe { slice:: from_raw_parts ( out as _ , len) }
118+ }
119+ Cow :: Borrowed ( slice) => {
120+ let ptr = self . require ( bytes) ;
121+
122+ unsafe { ptr:: copy_nonoverlapping ( slice. as_ptr ( ) as _ , ptr, bytes) } ;
123+
124+ unsafe { slice:: from_raw_parts ( ptr as _ , len) }
125+ }
81126 }
82127 }
83128
@@ -251,6 +296,17 @@ mod test {
251296 assert_eq ! ( arena. store. get_mut( ) . len( ) , 1 ) ;
252297 }
253298
299+ #[ test]
300+ fn allocate_some_vecs ( ) {
301+ let arena = Arena :: new ( ) ;
302+
303+ let vecs = vec ! [ vec![ 1u64 , 2 , 3 , 4 ] , vec![ 7 ; ARENA_BLOCK * 2 ] , vec![ ] ] ;
304+
305+ for vec in vecs {
306+ assert_eq ! ( arena. alloc_many( vec. clone( ) ) , & vec[ ..] ) ;
307+ }
308+ }
309+
254310 #[ test]
255311 fn allocate_huge_heap ( ) {
256312 let arena = Arena :: new ( ) ;
@@ -272,7 +328,10 @@ mod test {
272328 assert_eq ! ( arena. store. get_mut( ) . len( ) , 2 ) ;
273329
274330 // Second page is appropriately large
275- assert_eq ! ( arena. store. get_mut( ) [ 1 ] . capacity( ) , size_of:: <usize >( ) * 1024 * 1024 ) ;
331+ assert_eq ! (
332+ arena. store. get_mut( ) [ 1 ] . capacity( ) ,
333+ size_of:: <usize >( ) * 1024 * 1024
334+ ) ;
276335 }
277336
278337 #[ test]
@@ -312,6 +371,11 @@ mod test {
312371 let allocated = unsafe { :: std:: slice:: from_raw_parts ( ptr, 12 ) } ;
313372
314373 assert_eq ! ( arena. offset. get( ) , 16 ) ;
315- assert_eq ! ( allocated, & [ b'a' , b'b' , b'c' , b'd' , b'e' , b'f' , b'g' , b'h' , b'i' , b'j' , b'k' , 0 ] ) ;
374+ assert_eq ! (
375+ allocated,
376+ & [
377+ b'a' , b'b' , b'c' , b'd' , b'e' , b'f' , b'g' , b'h' , b'i' , b'j' , b'k' , 0
378+ ]
379+ ) ;
316380 }
317381}
0 commit comments