14
14
15
15
use core:: prelude:: * ;
16
16
17
- use core:: dvec:: DVec ;
18
- use std:: oldmap:: HashMap ;
19
- use std:: oldmap;
17
+ use hashmap:: linear:: LinearMap ;
18
+ use dvec:: DVec ;
20
19
21
- pub type hash_interner < T > = { map : HashMap < T , uint > , vect : DVec < T > } ;
22
-
23
- pub fn mk < T : Eq IterBytes Hash Const Copy > ( ) -> Interner < T > {
24
- let m = oldmap:: HashMap :: < T , uint > ( ) ;
25
- let hi: hash_interner < T > =
26
- { map: m, vect: DVec ( ) } ;
27
- ( ( hi) as Interner :: < T > )
28
- }
29
-
30
- pub fn mk_prefill < T : Eq IterBytes Hash Const Copy > ( init : & [ T ] ) -> Interner < T > {
31
- let rv = mk ( ) ;
32
- for init. each( ) |v| { rv. intern ( * v) ; }
33
- return rv;
20
+ pub struct Interner < T > {
21
+ priv mut map: LinearMap < T , uint > ,
22
+ priv vect : DVec < T > ,
34
23
}
35
24
25
+ // when traits can extend traits, we should extend index<uint,T> to get []
26
+ pub impl < T : Eq IterBytes Hash Const Copy > Interner < T > {
27
+ static fn new( ) -> Interner <T > {
28
+ Interner {
29
+ map: LinearMap :: new( ) ,
30
+ vect: DVec ( ) ,
31
+ }
32
+ }
36
33
37
- /* when traits can extend traits, we should extend index<uint,T> to get [] */
38
- pub trait Interner < T : Eq IterBytes Hash Const Copy > {
39
- fn intern ( T ) -> uint ;
40
- fn gensym ( T ) -> uint ;
41
- pure fn get ( uint ) -> T ;
42
- fn len ( ) -> uint ;
43
- }
34
+ static fn prefill( init: & [ T ] ) -> Interner <T > {
35
+ let rv = Interner :: new ( ) ;
36
+ for init. each( ) |v| { rv. intern ( * v) ; }
37
+ rv
38
+ }
44
39
45
- pub impl < T : Eq IterBytes Hash Const Copy > Interner < T > for hash_interner < T > {
46
- fn intern ( val : T ) -> uint {
40
+ fn intern( & self , val: T ) -> uint {
47
41
match self. map . find ( & val) {
48
- Some ( idx) => return idx,
49
- None => {
50
- let new_idx = self . vect . len ( ) ;
51
- self . map . insert ( val, new_idx) ;
52
- self . vect . push ( val) ;
53
- return new_idx;
54
- }
42
+ Some ( & idx) => return idx,
43
+ None => ( ) ,
55
44
}
45
+
46
+ let new_idx = self . vect . len ( ) ;
47
+ self . map . insert ( val, new_idx) ;
48
+ self . vect . push ( val) ;
49
+ new_idx
56
50
}
57
- fn gensym ( val : T ) -> uint {
51
+
52
+ fn gensym ( & self , val : T ) -> uint {
58
53
let new_idx = self . vect . len ( ) ;
59
54
// leave out of .map to avoid colliding
60
55
self . vect . push ( val) ;
61
- return new_idx;
56
+ new_idx
62
57
}
63
58
64
59
// this isn't "pure" in the traditional sense, because it can go from
65
60
// failing to returning a value as items are interned. But for typestate,
66
61
// where we first check a pred and then rely on it, ceasing to fail is ok.
67
- pure fn get ( idx : uint ) -> T { self . vect . get_elt ( idx) }
62
+ pure fn get ( & self , idx : uint ) -> T { self . vect . get_elt ( idx) }
68
63
69
- fn len ( ) -> uint { return self . vect . len ( ) ; }
64
+ fn len ( & self ) -> uint { self . vect . len ( ) }
70
65
}
71
66
72
-
73
67
#[ test]
74
68
#[ should_fail]
75
69
pub fn i1 ( ) {
76
- let i : Interner < @~str > = mk ( ) ;
70
+ let i : Interner < @~str > = Interner :: new ( ) ;
77
71
i. get ( 13 ) ;
78
72
}
79
73
80
74
#[ test]
81
75
pub fn i2 ( ) {
82
- let i : Interner < @~str > = mk ( ) ;
76
+ let i : Interner < @~str > = Interner :: new ( ) ;
83
77
// first one is zero:
84
78
assert i. intern ( @~"dog") == 0 ;
85
79
// re-use gets the same entry:
@@ -104,7 +98,7 @@ pub fn i2 () {
104
98
105
99
#[ test]
106
100
pub fn i3 ( ) {
107
- let i : Interner < @~str > = mk_prefill ( [ @~"Alan ", @~"Bob ", @~"Carol "] ) ;
101
+ let i : Interner < @~str > = Interner :: prefill ( [ @~"Alan ", @~"Bob ", @~"Carol "] ) ;
108
102
assert i. get ( 0 ) == @~"Alan ";
109
103
assert i. get ( 1 ) == @~"Bob ";
110
104
assert i. get ( 2 ) == @~"Carol ";
0 commit comments