Skip to content

Commit ddfe82a

Browse files
committed
make rehashing more efficient by not re-allocating entries
1 parent 729345c commit ddfe82a

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

src/libstd/map.rs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,20 @@ mod chained {
125125
};
126126

127127
tag search_result<copy K, copy V> {
128-
not_found(uint);
128+
not_found;
129129
found_first(uint, @entry<K,V>);
130130
found_after(@entry<K,V>, @entry<K,V>);
131131
}
132132

133133
fn search_rem<copy K, copy V>(tbl: t<K,V>,
134134
k: K,
135135
h: uint,
136-
idx: uint,
137136
e_root: @entry<K,V>) -> search_result<K,V> {
138137
let e0 = e_root;
139138
while true {
140139
alt e0.next {
141140
absent. {
142-
ret not_found(idx);
141+
ret not_found;
143142
}
144143
present(e1) {
145144
let e1_key = e1.key; // Satisfy alias checker.
@@ -161,23 +160,25 @@ mod chained {
161160

162161
alt tbl.chains[idx] {
163162
absent. {
164-
ret not_found(idx);
163+
ret not_found;
165164
}
166165
present(e) {
167166
let e_key = e.key; // Satisfy alias checker.
168167
if e.hash == h && tbl.eqer(e_key, k) {
169168
ret found_first(idx, e);
170169
} else {
171-
ret search_rem(tbl, k, h, idx, e);
170+
ret search_rem(tbl, k, h, e);
172171
}
173172
}
174173
}
175174
}
176175

177-
fn insert_h<copy K, copy V>(tbl: t<K,V>, k: K, v: V, hash: uint) -> bool {
178-
// internal routine: does not update size
176+
fn insert<copy K, copy V>(tbl: t<K,V>, k: K, v: V) -> bool {
177+
let hash = tbl.hasher(k);
179178
alt search_tbl(tbl, k, hash) {
180-
not_found(idx) {
179+
not_found. {
180+
tbl.size += 1u;
181+
let idx = hash % vec::len(tbl.chains);
181182
let old_chain = tbl.chains[idx];
182183
tbl.chains[idx] = present(@{
183184
hash: hash,
@@ -197,14 +198,9 @@ mod chained {
197198
}
198199
}
199200

200-
fn insert<copy K, copy V>(tbl: t<K,V>, k: K, v: V) -> bool {
201-
tbl.size += 1u;
202-
ret insert_h(tbl, k, v, tbl.hasher(k));
203-
}
204-
205201
fn get<copy K, copy V>(tbl: t<K,V>, k: K) -> option::t<V> {
206202
alt search_tbl(tbl, k, tbl.hasher(k)) {
207-
not_found(_) {
203+
not_found. {
208204
ret option::none;
209205
}
210206

@@ -220,7 +216,7 @@ mod chained {
220216

221217
fn remove<copy K, copy V>(tbl: t<K,V>, k: K) -> option::t<V> {
222218
alt search_tbl(tbl, k, tbl.hasher(k)) {
223-
not_found(_) {
219+
not_found. {
224220
ret option::none;
225221
}
226222

@@ -247,8 +243,9 @@ mod chained {
247243
alt chain {
248244
absent. { ret; }
249245
present(entry) {
250-
blk(entry);
251-
chain = entry.next;
246+
let next = entry.next;
247+
blk(entry); // may modify entry.next!
248+
chain = next;
252249
}
253250
}
254251
}
@@ -269,7 +266,9 @@ mod chained {
269266
let n_new_chains: uint = uint::next_power_of_two(n_old_chains + 1u);
270267
tbl.chains = chains(n_new_chains);
271268
foreach_chain(old_chains) { |entry|
272-
insert_h(tbl, entry.key, entry.value, entry.hash);
269+
let idx = entry.hash % n_new_chains;
270+
entry.next = tbl.chains[idx];
271+
tbl.chains[idx] = present(entry);
273272
}
274273
}
275274

0 commit comments

Comments
 (0)