@@ -26,7 +26,11 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
26
26
let uint initial_capacity = 32 u; // 2^5
27
27
let util. rational load_factor = rec ( num=3 , den=4 ) ;
28
28
29
- type bucket [ V ] = tag ( nil ( ) , deleted ( ) , some ( V ) ) ;
29
+ type bucket [ K , V ] = tag ( nil ( ) , deleted ( ) , some ( K , V ) ) ;
30
+
31
+ fn make_buckets[ K , V ] ( uint nbkts) -> vec[ mutable bucket[ K , V ] ] {
32
+ ret _vec. init_elt [ mutable bucket[ K , V ] ] ( nil[ K , V ] ( ) , nbkts) ;
33
+ }
30
34
31
35
// Derive two hash functions from the one given by taking the upper
32
36
// half and lower half of the uint bits. Our bucket probing
@@ -57,57 +61,93 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
57
61
ret hashl[ K ] ( hasher, nbkts, key) + i * hashr[ K ] ( hasher, nbkts, key) ;
58
62
}
59
63
64
+ /**
65
+ * We attempt to never call this with a full table. If we do, it
66
+ * will fail.
67
+ */
68
+ fn insert_common[ K , V ] ( hashfn[ K ] hasher,
69
+ vec[ mutable bucket[ K , V ] ] bkts,
70
+ uint nbkts,
71
+ & K key,
72
+ & V val)
73
+ {
74
+ let uint i = 0 u;
75
+ while ( i < nbkts) {
76
+ // FIXME (issue #94): as in find_common()
77
+ let int j = ( hash[ K ] ( hasher, nbkts, key, i) ) as int ;
78
+ alt ( bkts. ( j) ) {
79
+ case ( some[ K , V ] ( _, _) ) {
80
+ i += 1 u;
81
+ }
82
+ case ( _) {
83
+ bkts. ( j) = some[ K , V ] ( key, val) ;
84
+ ret;
85
+ }
86
+ }
87
+ }
88
+ fail; // full table
89
+ }
90
+
60
91
fn find_common[ K , V ] ( hashfn[ K ] hasher,
61
- vec[ mutable bucket[ V ] ] bkts,
92
+ vec[ mutable bucket[ K , V ] ] bkts,
62
93
uint nbkts,
63
94
& K key)
64
95
-> util. option [ V ]
65
96
{
66
97
let uint i = 0 u;
67
98
while ( i < nbkts) {
68
- // Pending fix to issue #94, remove uint coercion.
99
+ // FIXME ( issue #94): Pending bugfix , remove uint coercion.
69
100
let int j = ( hash[ K ] ( hasher, nbkts, key, i) ) as int ;
70
101
alt ( bkts. ( j) ) {
71
- case ( some[ V ] ( val) ) {
102
+ case ( some[ K , V ] ( _ , val) ) {
72
103
ret util. some [ V ] ( val) ;
73
104
}
74
- case ( nil[ V ] ( ) ) {
105
+ case ( nil[ K , V ] ( ) ) {
75
106
ret util. none [ V ] ( ) ;
76
107
}
77
- case ( deleted[ V ] ( ) ) {
108
+ case ( deleted[ K , V ] ( ) ) {
78
109
i += 1 u;
79
110
}
80
111
}
81
112
}
82
113
ret util. none [ V ] ( ) ;
83
114
}
84
115
116
+
117
+ fn rehash[ K , V ] ( hashfn[ K ] hasher,
118
+ vec[ mutable bucket[ K , V ] ] oldbkts, uint noldbkts,
119
+ vec[ mutable bucket[ K , V ] ] newbkts, uint nnewbkts)
120
+ {
121
+ for ( bucket[ K , V ] b in oldbkts) {
122
+ alt ( b) {
123
+ case ( some[ K , V ] ( k, v) ) {
124
+ insert_common[ K , V ] ( hasher, newbkts, nnewbkts, k, v) ;
125
+ }
126
+ case ( _) { }
127
+ }
128
+ }
129
+ }
130
+
85
131
obj hashmap[ K , V ] ( hashfn[ K ] hasher,
86
132
eqfn[ K ] eqer,
87
- mutable vec[ mutable bucket[ V ] ] bkts,
133
+ mutable vec[ mutable bucket[ K , V ] ] bkts,
88
134
mutable uint nbkts,
89
135
mutable uint nelts,
90
136
util. rational lf)
91
137
{
92
138
fn insert ( & K key , & V val ) {
93
- // FIXME grow the table and rehash if we ought to.
94
- let uint i = 0 u;
95
- while ( i < nbkts) {
96
- // Issue #94, as in find_common()
97
- let int j = ( hash[ K ] ( hasher, nbkts, key, i) ) as int ;
98
- alt ( bkts. ( j) ) {
99
- case ( some[ V ] ( _) ) {
100
- i += 1 u;
101
- }
102
- case ( _) {
103
- bkts. ( j) = some[ V ] ( val) ;
104
- nelts += 1 u;
105
- ret;
106
- }
107
- }
139
+ let util. rational load = rec ( num=( nelts + 1 u) as int , den=nbkts as int ) ;
140
+ if ( !util. rational_leq ( load, lf) ) {
141
+ let uint nnewbkts = _int. next_power_of_two ( nbkts + 1 u) ;
142
+
143
+ // FIXME (issue #94): Enforce our workaround to issue #94.
144
+ check ( ( nnewbkts as int ) > 0 ) ;
145
+
146
+ let vec[ mutable bucket[ K , V ] ] newbkts = make_buckets[ K , V ] ( nnewbkts) ;
147
+ rehash[ K , V ] ( hasher, bkts, nbkts, newbkts, nnewbkts) ;
108
148
}
109
- // full table, impossible unless growth is broken. remove after testing.
110
- fail ;
149
+ insert_common [ K , V ] ( hasher , bkts , nbkts , key , val ) ;
150
+ nelts += 1 u ;
111
151
}
112
152
113
153
fn contains_key ( & K key ) -> bool {
@@ -131,29 +171,32 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
131
171
fn remove ( & K key ) -> util. option[ V ] {
132
172
let uint i = 0 u;
133
173
while ( i < nbkts) {
134
- // Issue #94, as in find_common()
174
+ // FIXME (issue #94): as in find_common()
135
175
let int j = ( hash[ K ] ( hasher, nbkts, key, i) ) as int ;
136
176
alt ( bkts. ( j) ) {
137
- case ( some[ V ] ( val) ) {
138
- bkts. ( j) = deleted[ V ] ( ) ;
177
+ case ( some[ K , V ] ( _ , val) ) {
178
+ bkts. ( j) = deleted[ K , V ] ( ) ;
139
179
ret util. some [ V ] ( val) ;
140
180
}
141
- case ( deleted[ V ] ( ) ) {
181
+ case ( deleted[ K , V ] ( ) ) {
142
182
nelts += 1 u;
143
183
}
144
- case ( nil[ V ] ( ) ) {
184
+ case ( nil[ K , V ] ( ) ) {
145
185
ret util. none [ V ] ( ) ;
146
186
}
147
187
}
148
188
}
149
189
ret util. none [ V ] ( ) ;
150
190
}
151
191
152
- fn rehash ( ) { }
192
+ fn rehash ( ) {
193
+ let vec[ mutable bucket[ K , V ] ] newbkts = make_buckets[ K , V ] ( nbkts) ;
194
+ rehash[ K , V ] ( hasher, bkts, nbkts, newbkts, nbkts) ;
195
+ bkts = newbkts;
196
+ }
153
197
}
154
198
155
- let vec[ mutable bucket[ V ] ] bkts =
156
- _vec. init_elt [ mutable bucket[ V ] ] ( nil[ V ] ( ) , initial_capacity) ;
199
+ let vec[ mutable bucket[ K , V ] ] bkts = make_buckets[ K , V ] ( initial_capacity) ;
157
200
158
- ret hashmap[ K , V ] ( hasher, eqer, bkts, 0 u , 0 u, load_factor) ;
201
+ ret hashmap[ K , V ] ( hasher, eqer, bkts, initial_capacity , 0 u, load_factor) ;
159
202
}
0 commit comments