14
14
15
15
use ast:: Name ;
16
16
17
+ use std:: cell:: RefCell ;
17
18
use std:: cmp:: Equiv ;
18
19
use std:: hashmap:: HashMap ;
19
20
20
21
pub struct Interner < T > {
21
- priv map: @mut HashMap < T , Name > ,
22
+ priv map: @RefCell < HashMap < T , Name > > ,
22
23
priv vect : @mut ~[ T ] ,
23
24
}
24
25
25
26
// when traits can extend traits, we should extend index<Name,T> to get []
26
27
impl < T : Eq + IterBytes + Hash + Freeze + Clone + ' static > Interner < T > {
27
28
pub fn new ( ) -> Interner < T > {
28
29
Interner {
29
- map : @mut HashMap :: new ( ) ,
30
+ map : @RefCell :: new ( HashMap :: new ( ) ) ,
30
31
vect : @mut ~[ ] ,
31
32
}
32
33
}
@@ -40,14 +41,15 @@ impl<T:Eq + IterBytes + Hash + Freeze + Clone + 'static> Interner<T> {
40
41
}
41
42
42
43
pub fn intern ( & self , val : T ) -> Name {
43
- match self . map . find ( & val) {
44
+ let mut map = self . map . borrow_mut ( ) ;
45
+ match map. get ( ) . find ( & val) {
44
46
Some ( & idx) => return idx,
45
47
None => ( ) ,
46
48
}
47
49
48
50
let vect = & mut * self . vect ;
49
51
let new_idx = vect. len ( ) as Name ;
50
- self . map . insert ( val. clone ( ) , new_idx) ;
52
+ map. get ( ) . insert ( val. clone ( ) , new_idx) ;
51
53
vect. push ( val) ;
52
54
new_idx
53
55
}
@@ -70,7 +72,8 @@ impl<T:Eq + IterBytes + Hash + Freeze + Clone + 'static> Interner<T> {
70
72
71
73
pub fn find_equiv < Q : Hash + IterBytes + Equiv < T > > ( & self , val : & Q )
72
74
-> Option < Name > {
73
- match self . map . find_equiv ( val) {
75
+ let map = self . map . borrow ( ) ;
76
+ match map. get ( ) . find_equiv ( val) {
74
77
Some ( v) => Some ( * v) ,
75
78
None => None ,
76
79
}
@@ -80,15 +83,15 @@ impl<T:Eq + IterBytes + Hash + Freeze + Clone + 'static> Interner<T> {
80
83
// A StrInterner differs from Interner<String> in that it accepts
81
84
// borrowed pointers rather than @ ones, resulting in less allocation.
82
85
pub struct StrInterner {
83
- priv map: @mut HashMap < @str , Name > ,
86
+ priv map: @RefCell < HashMap < @str , Name > > ,
84
87
priv vect : @mut ~[ @str ] ,
85
88
}
86
89
87
90
// when traits can extend traits, we should extend index<Name,T> to get []
88
91
impl StrInterner {
89
92
pub fn new ( ) -> StrInterner {
90
93
StrInterner {
91
- map : @mut HashMap :: new ( ) ,
94
+ map : @RefCell :: new ( HashMap :: new ( ) ) ,
92
95
vect : @mut ~[ ] ,
93
96
}
94
97
}
@@ -100,14 +103,15 @@ impl StrInterner {
100
103
}
101
104
102
105
pub fn intern ( & self , val : & str ) -> Name {
103
- match self . map . find_equiv ( & val) {
106
+ let mut map = self . map . borrow_mut ( ) ;
107
+ match map. get ( ) . find_equiv ( & val) {
104
108
Some ( & idx) => return idx,
105
109
None => ( ) ,
106
110
}
107
111
108
112
let new_idx = self . len ( ) as Name ;
109
113
let val = val. to_managed ( ) ;
110
- self . map . insert ( val, new_idx) ;
114
+ map. get ( ) . insert ( val, new_idx) ;
111
115
self . vect . push ( val) ;
112
116
new_idx
113
117
}
@@ -142,7 +146,8 @@ impl StrInterner {
142
146
143
147
pub fn find_equiv < Q : Hash + IterBytes + Equiv < @str > > ( & self , val : & Q )
144
148
-> Option < Name > {
145
- match self . map . find_equiv ( val) {
149
+ let map = self . map . borrow ( ) ;
150
+ match map. get ( ) . find_equiv ( val) {
146
151
Some ( v) => Some ( * v) ,
147
152
None => None ,
148
153
}
0 commit comments