@@ -10,7 +10,7 @@ import std._vec;
10
10
11
11
12
12
type hashfn [ K ] = fn ( & K ) -> uint;
13
- type eqfn [ K ] = fn ( & K ) -> bool;
13
+ type eqfn [ K ] = fn ( & K , & K ) -> bool;
14
14
15
15
type hashmap [ K , V ] = obj {
16
16
fn insert( & K key, & V val) ;
@@ -46,49 +46,55 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
46
46
// is always a power of 2), so that all buckets are probed for a
47
47
// fixed key.
48
48
49
- fn hashl[ K ] ( hashfn[ K ] hasher, uint nbkts, & K key) -> uint {
49
+ fn hashl[ K ] ( & hashfn[ K ] hasher, uint nbkts, & K key) -> uint {
50
50
ret ( hasher ( key) >>> ( sys. rustrt . size_of [ uint] ( ) * 8 u / 2 u) )
51
51
% nbkts;
52
52
}
53
53
54
- fn hashr[ K ] ( hashfn[ K ] hasher, uint nbkts, & K key) -> uint {
54
+ fn hashr[ K ] ( & hashfn[ K ] hasher, uint nbkts, & K key) -> uint {
55
55
ret ( ( ( ( ~ 0 u) >>> ( sys. rustrt . size_of [ uint] ( ) * 8 u / 2 u) )
56
56
& hasher ( key) ) * 2 u + 1 u)
57
57
% nbkts;
58
58
}
59
59
60
- fn hash[ K ] ( hashfn[ K ] hasher, uint nbkts, & K key, uint i) -> uint {
60
+ fn hash[ K ] ( & hashfn[ K ] hasher, uint nbkts, & K key, uint i) -> uint {
61
61
ret hashl[ K ] ( hasher, nbkts, key) + i * hashr[ K ] ( hasher, nbkts, key) ;
62
62
}
63
63
64
64
/**
65
65
* We attempt to never call this with a full table. If we do, it
66
66
* will fail.
67
67
*/
68
- fn insert_common[ K , V ] ( hashfn[ K ] hasher,
68
+ fn insert_common[ K , V ] ( & hashfn[ K ] hasher,
69
+ & eqfn[ K ] eqer,
69
70
vec[ mutable bucket[ K , V ] ] bkts,
70
71
uint nbkts,
71
72
& K key,
72
73
& V val)
74
+ -> bool
73
75
{
74
76
let uint i = 0 u;
75
77
while ( i < nbkts) {
76
78
// FIXME (issue #94): as in find_common()
77
79
let int j = ( hash[ K ] ( hasher, nbkts, key, i) ) as int ;
78
80
alt ( bkts. ( j) ) {
79
- case ( some[ K , V ] ( _, _) ) {
81
+ case ( some[ K , V ] ( k, _) ) {
82
+ if ( eqer ( key, k) ) {
83
+ ret false ;
84
+ }
80
85
i += 1 u;
81
86
}
82
87
case ( _) {
83
88
bkts. ( j) = some[ K , V ] ( key, val) ;
84
- ret;
89
+ ret true ;
85
90
}
86
91
}
87
92
}
88
93
fail; // full table
89
94
}
90
95
91
- fn find_common[ K , V ] ( hashfn[ K ] hasher,
96
+ fn find_common[ K , V ] ( & hashfn[ K ] hasher,
97
+ & eqfn[ K ] eqer,
92
98
vec[ mutable bucket[ K , V ] ] bkts,
93
99
uint nbkts,
94
100
& K key)
@@ -99,29 +105,31 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
99
105
// FIXME (issue #94): Pending bugfix, remove uint coercion.
100
106
let int j = ( hash[ K ] ( hasher, nbkts, key, i) ) as int ;
101
107
alt ( bkts. ( j) ) {
102
- case ( some[ K , V ] ( _, val) ) {
103
- ret util. some [ V ] ( val) ;
108
+ case ( some[ K , V ] ( k, v) ) {
109
+ if ( eqer ( key, k) ) {
110
+ ret util. some [ V ] ( v) ;
111
+ }
104
112
}
105
113
case ( nil[ K , V ] ( ) ) {
106
114
ret util. none [ V ] ( ) ;
107
115
}
108
- case ( deleted[ K , V ] ( ) ) {
109
- i += 1 u;
110
- }
116
+ case ( deleted[ K , V ] ( ) ) { }
111
117
}
118
+ i += 1 u;
112
119
}
113
120
ret util. none [ V ] ( ) ;
114
121
}
115
122
116
123
117
- fn rehash[ K , V ] ( hashfn[ K ] hasher,
124
+ fn rehash[ K , V ] ( & hashfn[ K ] hasher,
125
+ & eqfn[ K ] eqer,
118
126
vec[ mutable bucket[ K , V ] ] oldbkts, uint noldbkts,
119
127
vec[ mutable bucket[ K , V ] ] newbkts, uint nnewbkts)
120
128
{
121
129
for ( bucket[ K , V ] b in oldbkts) {
122
130
alt ( b) {
123
131
case ( some[ K , V ] ( k, v) ) {
124
- insert_common[ K , V ] ( hasher, newbkts, nnewbkts, k, v) ;
132
+ insert_common[ K , V ] ( hasher, eqer , newbkts, nnewbkts, k, v) ;
125
133
}
126
134
case ( _) { }
127
135
}
@@ -144,28 +152,28 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
144
152
check ( ( nnewbkts as int ) > 0 ) ;
145
153
146
154
let vec[ mutable bucket[ K , V ] ] newbkts = make_buckets[ K , V ] ( nnewbkts) ;
147
- rehash[ K , V ] ( hasher, bkts, nbkts, newbkts, nnewbkts) ;
155
+ rehash[ K , V ] ( hasher, eqer , bkts, nbkts, newbkts, nnewbkts) ;
148
156
}
149
- insert_common[ K , V ] ( hasher, bkts, nbkts, key, val) ;
157
+ insert_common[ K , V ] ( hasher, eqer , bkts, nbkts, key, val) ;
150
158
nelts += 1 u;
151
159
}
152
160
153
161
fn contains_key ( & K key ) -> bool {
154
- alt ( find_common[ K , V ] ( hasher, bkts, nbkts, key) ) {
162
+ alt ( find_common[ K , V ] ( hasher, eqer , bkts, nbkts, key) ) {
155
163
case ( util. some [ V ] ( _) ) { ret true ; }
156
164
case ( _) { ret false ; }
157
165
}
158
166
}
159
167
160
168
fn get ( & K key ) -> V {
161
- alt ( find_common[ K , V ] ( hasher, bkts, nbkts, key) ) {
169
+ alt ( find_common[ K , V ] ( hasher, eqer , bkts, nbkts, key) ) {
162
170
case ( util. some [ V ] ( val) ) { ret val; }
163
171
case ( _) { fail; }
164
172
}
165
173
}
166
174
167
175
fn find ( & K key ) -> util. option[ V ] {
168
- be find_common[ K , V ] ( hasher, bkts, nbkts, key) ;
176
+ be find_common[ K , V ] ( hasher, eqer , bkts, nbkts, key) ;
169
177
}
170
178
171
179
fn remove ( & K key ) -> util. option[ V ] {
@@ -191,7 +199,7 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
191
199
192
200
fn rehash ( ) {
193
201
let vec[ mutable bucket[ K , V ] ] newbkts = make_buckets[ K , V ] ( nbkts) ;
194
- rehash[ K , V ] ( hasher, bkts, nbkts, newbkts, nbkts) ;
202
+ rehash[ K , V ] ( hasher, eqer , bkts, nbkts, newbkts, nbkts) ;
195
203
bkts = newbkts;
196
204
}
197
205
}
0 commit comments