@@ -17,122 +17,45 @@ use ast::Name;
17
17
use std:: borrow:: Borrow ;
18
18
use std:: cell:: RefCell ;
19
19
use std:: collections:: HashMap ;
20
- use std:: hash:: Hash ;
21
20
use std:: rc:: Rc ;
22
21
23
- pub struct Interner < T > {
24
- map : RefCell < HashMap < T , Name > > ,
25
- vect : RefCell < Vec < T > > ,
26
- }
27
-
28
- // when traits can extend traits, we should extend index<Name,T> to get []
29
- impl < T : Eq + Hash + Clone + ' static > Interner < T > {
30
- pub fn new ( ) -> Interner < T > {
31
- Interner {
32
- map : RefCell :: new ( HashMap :: new ( ) ) ,
33
- vect : RefCell :: new ( Vec :: new ( ) ) ,
34
- }
35
- }
36
-
37
- pub fn prefill ( init : & [ T ] ) -> Interner < T > {
38
- let rv = Interner :: new ( ) ;
39
- for v in init {
40
- rv. intern ( ( * v) . clone ( ) ) ;
41
- }
42
- rv
43
- }
44
-
45
- pub fn intern ( & self , val : T ) -> Name {
46
- let mut map = self . map . borrow_mut ( ) ;
47
- if let Some ( & idx) = ( * map) . get ( & val) {
48
- return idx;
49
- }
50
-
51
- let mut vect = self . vect . borrow_mut ( ) ;
52
- let new_idx = Name ( ( * vect) . len ( ) as u32 ) ;
53
- ( * map) . insert ( val. clone ( ) , new_idx) ;
54
- ( * vect) . push ( val) ;
55
- new_idx
56
- }
57
-
58
- pub fn gensym ( & self , val : T ) -> Name {
59
- let mut vect = self . vect . borrow_mut ( ) ;
60
- let new_idx = Name ( ( * vect) . len ( ) as u32 ) ;
61
- // leave out of .map to avoid colliding
62
- ( * vect) . push ( val) ;
63
- new_idx
64
- }
65
-
66
- pub fn get ( & self , idx : Name ) -> T {
67
- let vect = self . vect . borrow ( ) ;
68
- ( * vect) [ idx. 0 as usize ] . clone ( )
69
- }
70
-
71
- pub fn len ( & self ) -> usize {
72
- let vect = self . vect . borrow ( ) ;
73
- ( * vect) . len ( )
74
- }
75
-
76
- pub fn find < Q : ?Sized > ( & self , val : & Q ) -> Option < Name >
77
- where T : Borrow < Q > , Q : Eq + Hash {
78
- let map = self . map . borrow ( ) ;
79
- match ( * map) . get ( val) {
80
- Some ( v) => Some ( * v) ,
81
- None => None ,
82
- }
83
- }
84
-
85
- pub fn clear ( & self ) {
86
- * self . map . borrow_mut ( ) = HashMap :: new ( ) ;
87
- * self . vect . borrow_mut ( ) = Vec :: new ( ) ;
88
- }
89
- }
90
-
91
- #[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
22
+ #[ derive( PartialEq , Eq , Hash ) ]
92
23
struct RcStr ( Rc < String > ) ;
93
24
94
- impl RcStr {
95
- fn new ( string : & str ) -> Self {
96
- RcStr ( Rc :: new ( string. to_owned ( ) ) )
97
- }
98
- }
99
-
100
25
impl Borrow < str > for RcStr {
101
26
fn borrow ( & self ) -> & str {
102
27
& self . 0
103
28
}
104
29
}
105
30
106
- /// A StrInterner differs from Interner<String> in that it accepts
107
- /// &str rather than RcStr, resulting in less allocation.
108
- pub struct StrInterner {
31
+ pub struct Interner {
109
32
map : RefCell < HashMap < RcStr , Name > > ,
110
33
vect : RefCell < Vec < Rc < String > > > ,
111
34
}
112
35
113
36
/// When traits can extend traits, we should extend index<Name,T> to get []
114
- impl StrInterner {
115
- pub fn new ( ) -> StrInterner {
116
- StrInterner {
37
+ impl Interner {
38
+ pub fn new ( ) -> Self {
39
+ Interner {
117
40
map : RefCell :: new ( HashMap :: new ( ) ) ,
118
41
vect : RefCell :: new ( Vec :: new ( ) ) ,
119
42
}
120
43
}
121
44
122
- pub fn prefill ( init : & [ & str ] ) -> StrInterner {
123
- let rv = StrInterner :: new ( ) ;
45
+ pub fn prefill ( init : & [ & str ] ) -> Self {
46
+ let rv = Interner :: new ( ) ;
124
47
for & v in init { rv. intern ( v) ; }
125
48
rv
126
49
}
127
50
128
- pub fn intern ( & self , val : & str ) -> Name {
51
+ pub fn intern < T : Borrow < str > + Into < String > > ( & self , val : T ) -> Name {
129
52
let mut map = self . map . borrow_mut ( ) ;
130
- if let Some ( & idx) = map. get ( val) {
53
+ if let Some ( & idx) = map. get ( val. borrow ( ) ) {
131
54
return idx;
132
55
}
133
56
134
57
let new_idx = Name ( self . len ( ) as u32 ) ;
135
- let val = Rc :: new ( val. to_owned ( ) ) ;
58
+ let val = Rc :: new ( val. into ( ) ) ;
136
59
map. insert ( RcStr ( val. clone ( ) ) , new_idx) ;
137
60
self . vect . borrow_mut ( ) . push ( val) ;
138
61
new_idx
@@ -181,7 +104,7 @@ impl StrInterner {
181
104
* self . vect . borrow_mut ( ) = Vec :: new ( ) ;
182
105
}
183
106
184
- pub fn reset ( & self , other : StrInterner ) {
107
+ pub fn reset ( & self , other : Interner ) {
185
108
* self . map . borrow_mut ( ) = other. map . into_inner ( ) ;
186
109
* self . vect . borrow_mut ( ) = other. vect . into_inner ( ) ;
187
110
}
@@ -190,57 +113,11 @@ impl StrInterner {
190
113
#[ cfg( test) ]
191
114
mod tests {
192
115
use super :: * ;
193
- use super :: RcStr ;
194
116
use ast:: Name ;
195
117
196
118
#[ test]
197
- #[ should_panic]
198
- fn i1 ( ) {
199
- let i : Interner < RcStr > = Interner :: new ( ) ;
200
- i. get ( Name ( 13 ) ) ;
201
- }
202
-
203
- #[ test]
204
- fn interner_tests ( ) {
205
- let i : Interner < RcStr > = Interner :: new ( ) ;
206
- // first one is zero:
207
- assert_eq ! ( i. intern( RcStr :: new( "dog" ) ) , Name ( 0 ) ) ;
208
- // re-use gets the same entry:
209
- assert_eq ! ( i. intern( RcStr :: new( "dog" ) ) , Name ( 0 ) ) ;
210
- // different string gets a different #:
211
- assert_eq ! ( i. intern( RcStr :: new( "cat" ) ) , Name ( 1 ) ) ;
212
- assert_eq ! ( i. intern( RcStr :: new( "cat" ) ) , Name ( 1 ) ) ;
213
- // dog is still at zero
214
- assert_eq ! ( i. intern( RcStr :: new( "dog" ) ) , Name ( 0 ) ) ;
215
- // gensym gets 3
216
- assert_eq ! ( i. gensym( RcStr :: new( "zebra" ) ) , Name ( 2 ) ) ;
217
- // gensym of same string gets new number :
218
- assert_eq ! ( i. gensym ( RcStr :: new( "zebra" ) ) , Name ( 3 ) ) ;
219
- // gensym of *existing* string gets new number:
220
- assert_eq ! ( i. gensym( RcStr :: new( "dog" ) ) , Name ( 4 ) ) ;
221
- assert_eq ! ( i. get( Name ( 0 ) ) , RcStr :: new( "dog" ) ) ;
222
- assert_eq ! ( i. get( Name ( 1 ) ) , RcStr :: new( "cat" ) ) ;
223
- assert_eq ! ( i. get( Name ( 2 ) ) , RcStr :: new( "zebra" ) ) ;
224
- assert_eq ! ( i. get( Name ( 3 ) ) , RcStr :: new( "zebra" ) ) ;
225
- assert_eq ! ( i. get( Name ( 4 ) ) , RcStr :: new( "dog" ) ) ;
226
- }
227
-
228
- #[ test]
229
- fn i3 ( ) {
230
- let i : Interner < RcStr > = Interner :: prefill ( & [
231
- RcStr :: new ( "Alan" ) ,
232
- RcStr :: new ( "Bob" ) ,
233
- RcStr :: new ( "Carol" )
234
- ] ) ;
235
- assert_eq ! ( i. get( Name ( 0 ) ) , RcStr :: new( "Alan" ) ) ;
236
- assert_eq ! ( i. get( Name ( 1 ) ) , RcStr :: new( "Bob" ) ) ;
237
- assert_eq ! ( i. get( Name ( 2 ) ) , RcStr :: new( "Carol" ) ) ;
238
- assert_eq ! ( i. intern( RcStr :: new( "Bob" ) ) , Name ( 1 ) ) ;
239
- }
240
-
241
- #[ test]
242
- fn string_interner_tests ( ) {
243
- let i : StrInterner = StrInterner :: new ( ) ;
119
+ fn interner_tests ( ) {
120
+ let i : Interner = Interner :: new ( ) ;
244
121
// first one is zero:
245
122
assert_eq ! ( i. intern( "dog" ) , Name ( 0 ) ) ;
246
123
// re-use gets the same entry:
0 commit comments