1
- use std:: vec;
2
-
3
1
use crate :: allocator:: { Allocator , SExp } ;
4
2
3
+ #[ derive( Clone , Copy ) ]
4
+ pub struct IntAtomBuf {
5
+ start : u32 ,
6
+ end : u32 ,
7
+ }
8
+
5
9
enum NodePtr {
6
- Atom ( u32 ) ,
10
+ Atom ( IntAtomBuf ) ,
7
11
Pair ( u32 , u32 ) ,
8
12
}
9
13
10
14
pub struct IntAllocator {
11
- u8_vec : Vec < Vec < u8 > > ,
15
+ // this is effectively a grow-only stack where atoms are allocated. Atoms
16
+ // are immutable, so once they are created, they will stay around until the
17
+ // program completes
18
+ u8_vec : Vec < u8 > ,
12
19
node_vec : Vec < NodePtr > ,
13
20
}
14
21
@@ -24,23 +31,28 @@ impl IntAllocator {
24
31
u8_vec : Vec :: new ( ) ,
25
32
node_vec : Vec :: new ( ) ,
26
33
} ;
27
- r. u8_vec . push ( vec ! [ ] ) ;
28
- r. u8_vec . push ( vec ! [ 1_u8 ] ) ;
29
- r. node_vec . push ( NodePtr :: Atom ( 0 ) ) ;
30
- r. node_vec . push ( NodePtr :: Atom ( 1 ) ) ;
34
+ r. u8_vec . reserve ( 1024 * 1024 ) ;
35
+ r. u8_vec . push ( 1_u8 ) ;
36
+ // Preallocated empty list
37
+ r. node_vec
38
+ . push ( NodePtr :: Atom ( IntAtomBuf { start : 0 , end : 0 } ) ) ;
39
+ // Preallocated 1
40
+ r. node_vec
41
+ . push ( NodePtr :: Atom ( IntAtomBuf { start : 0 , end : 1 } ) ) ;
31
42
r
32
43
}
33
44
}
34
45
35
46
impl Allocator for IntAllocator {
36
47
type Ptr = u32 ;
37
- type AtomBuf = u32 ;
48
+ type AtomBuf = IntAtomBuf ;
38
49
39
- fn new_atom ( & mut self , v : & [ u8 ] ) -> u32 {
40
- let index = self . u8_vec . len ( ) as u32 ;
41
- self . u8_vec . push ( v. into ( ) ) ;
42
- let r: u32 = self . node_vec . len ( ) as u32 ;
43
- self . node_vec . push ( NodePtr :: Atom ( index) ) ;
50
+ fn new_atom ( & mut self , v : & [ u8 ] ) -> Self :: Ptr {
51
+ let start = self . u8_vec . len ( ) as u32 ;
52
+ self . u8_vec . extend_from_slice ( v) ;
53
+ let end = self . u8_vec . len ( ) as u32 ;
54
+ let r = self . node_vec . len ( ) as u32 ;
55
+ self . node_vec . push ( NodePtr :: Atom ( IntAtomBuf { start, end } ) ) ;
44
56
r
45
57
}
46
58
@@ -52,27 +64,27 @@ impl Allocator for IntAllocator {
52
64
53
65
fn atom < ' a > ( & ' a self , node : & ' a Self :: Ptr ) -> & ' a [ u8 ] {
54
66
match self . node_vec [ * node as usize ] {
55
- NodePtr :: Atom ( index ) => & self . u8_vec [ index as usize ] ,
67
+ NodePtr :: Atom ( IntAtomBuf { start , end } ) => & self . u8_vec [ start as usize ..end as usize ] ,
56
68
_ => panic ! ( "expected atom, got pair" ) ,
57
69
}
58
70
}
59
71
60
72
fn buf < ' a > ( & ' a self , node : & ' a Self :: AtomBuf ) -> & ' a [ u8 ] {
61
- & self . u8_vec [ * node as usize ]
73
+ & self . u8_vec [ node. start as usize ..node . end as usize ]
62
74
}
63
75
64
76
fn sexp ( & self , node : & Self :: Ptr ) -> SExp < Self :: Ptr , Self :: AtomBuf > {
65
77
match self . node_vec [ * node as usize ] {
66
- NodePtr :: Atom ( index ) => SExp :: Atom ( index ) ,
78
+ NodePtr :: Atom ( atombuf ) => SExp :: Atom ( atombuf ) ,
67
79
NodePtr :: Pair ( left, right) => SExp :: Pair ( left, right) ,
68
80
}
69
81
}
70
82
71
- fn null ( & self ) -> u32 {
83
+ fn null ( & self ) -> Self :: Ptr {
72
84
0
73
85
}
74
86
75
- fn one ( & self ) -> u32 {
87
+ fn one ( & self ) -> Self :: Ptr {
76
88
1
77
89
}
78
90
}
0 commit comments