Skip to content

Commit 7ca9c30

Browse files
committed
---
yaml --- r: 610 b: refs/heads/master c: 66b5b95 h: refs/heads/master v: v3
1 parent e6139ac commit 7ca9c30

File tree

3 files changed

+141
-14
lines changed

3 files changed

+141
-14
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: aa3030432862cf7694dc6b37c3fe8f8985741c86
2+
refs/heads/master: 66b5b9567c031aa5f23842a55a0b54c88fbe437b

trunk/src/lib/map.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type hashfn[K] = fn(&K) -> uint;
1313
type eqfn[K] = fn(&K, &K) -> bool;
1414

1515
type hashmap[K, V] = obj {
16+
fn size() -> uint;
1617
fn insert(&K key, &V val) -> bool;
1718
fn contains_key(&K key) -> bool;
1819
fn get(&K key) -> V;
@@ -141,6 +142,8 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
141142
mutable uint nelts,
142143
util.rational lf)
143144
{
145+
fn size() -> uint { ret nelts; }
146+
144147
fn insert(&K key, &V val) -> bool {
145148
let util.rational load = rec(num=(nelts + 1u) as int, den=nbkts as int);
146149
if (!util.rational_leq(load, lf)) {
@@ -181,17 +184,19 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
181184
while (i < nbkts) {
182185
let uint j = (hash[K](hasher, nbkts, key, i));
183186
alt (bkts.(j)) {
184-
case (some[K, V](_, val)) {
185-
bkts.(j) = deleted[K, V]();
186-
ret util.some[V](val);
187-
}
188-
case (deleted[K, V]()) {
189-
nelts += 1u;
187+
case (some[K, V](k, v)) {
188+
if (eqer(key, k)) {
189+
bkts.(j) = deleted[K, V]();
190+
nelts -= 1u;
191+
ret util.some[V](v);
192+
}
190193
}
194+
case (deleted[K, V]()) { }
191195
case (nil[K, V]()) {
192196
ret util.none[V]();
193197
}
194198
}
199+
i += 1u;
195200
}
196201
ret util.none[V]();
197202
}

trunk/src/test/run-pass/lib-map.rs

Lines changed: 129 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use std;
44
import std.map;
5+
import std.util;
56

67
fn test_simple() {
78
log "*** starting test_simple";
@@ -17,18 +18,18 @@ fn test_simple() {
1718
let map.eqfn[uint] eqer = eq;
1819
let map.hashmap[uint, uint] hm = map.mk_hashmap[uint, uint](hasher, eqer);
1920

20-
hm.insert(10u, 12u);
21-
hm.insert(11u, 13u);
22-
hm.insert(12u, 14u);
21+
check (hm.insert(10u, 12u));
22+
check (hm.insert(11u, 13u));
23+
check (hm.insert(12u, 14u));
2324

2425
check (hm.get(11u) == 13u);
2526
check (hm.get(12u) == 14u);
2627
check (hm.get(10u) == 12u);
2728

28-
hm.insert(12u, 14u);
29+
check (!hm.insert(12u, 14u));
2930
check (hm.get(12u) == 14u);
3031

31-
hm.insert(12u, 12u);
32+
check (!hm.insert(12u, 12u));
3233
check (hm.get(12u) == 12u);
3334

3435
log "*** finished test_simple";
@@ -55,7 +56,7 @@ fn test_growth() {
5556

5657
let uint i = 0u;
5758
while (i < num_to_insert) {
58-
hm.insert(i, i * i);
59+
check (hm.insert(i, i * i));
5960
log "inserting " + std._uint.to_str(i, 10u)
6061
+ " -> " + std._uint.to_str(i * i, 10u);
6162
i += 1u;
@@ -71,7 +72,7 @@ fn test_growth() {
7172
i += 1u;
7273
}
7374
74-
hm.insert(num_to_insert, 17u);
75+
check (hm.insert(num_to_insert, 17u));
7576
check (hm.get(num_to_insert) == 17u);
7677
7778
log "-----";
@@ -89,7 +90,128 @@ fn test_growth() {
8990
log "*** finished test_growth";
9091
}
9192

93+
fn test_removal() {
94+
log "*** starting test_removal";
95+
96+
let uint num_to_insert = 64u;
97+
98+
fn eq(&uint x, &uint y) -> bool { ret x == y; }
99+
fn hash(&uint u) -> uint {
100+
// This hash function intentionally causes collisions between
101+
// consecutive integer pairs.
102+
ret (u / 2u) * 2u;
103+
}
104+
105+
let map.hashfn[uint] hasher = hash;
106+
let map.eqfn[uint] eqer = eq;
107+
let map.hashmap[uint, uint] hm = map.mk_hashmap[uint, uint](hasher, eqer);
108+
109+
let uint i = 0u;
110+
while (i < num_to_insert) {
111+
check (hm.insert(i, i * i));
112+
log "inserting " + std._uint.to_str(i, 10u)
113+
+ " -> " + std._uint.to_str(i * i, 10u);
114+
i += 1u;
115+
}
116+
117+
check (hm.size() == num_to_insert);
118+
119+
log "-----";
120+
log "removing evens";
121+
122+
i = 0u;
123+
while (i < num_to_insert) {
124+
/**
125+
* FIXME (issue #150): we want to check the removed value as in the
126+
* following:
127+
128+
let util.option[uint] v = hm.remove(i);
129+
alt (v) {
130+
case (util.some[uint](u)) {
131+
check (u == (i * i));
132+
}
133+
case (util.none[uint]()) { fail; }
134+
}
135+
136+
* but we util.option is a tag type so util.some and util.none are
137+
* off limits until we parse the dwarf for tag types.
138+
*/
139+
140+
hm.remove(i);
141+
i += 2u;
142+
}
143+
144+
check (hm.size() == (num_to_insert / 2u));
145+
146+
log "-----";
147+
148+
i = 1u;
149+
while (i < num_to_insert) {
150+
log "get(" + std._uint.to_str(i, 10u) + ") = "
151+
+ std._uint.to_str(hm.get(i), 10u);
152+
check (hm.get(i) == i * i);
153+
i += 2u;
154+
}
155+
156+
log "-----";
157+
log "rehashing";
158+
159+
hm.rehash();
160+
161+
log "-----";
162+
163+
i = 1u;
164+
while (i < num_to_insert) {
165+
log "get(" + std._uint.to_str(i, 10u) + ") = "
166+
+ std._uint.to_str(hm.get(i), 10u);
167+
check (hm.get(i) == i * i);
168+
i += 2u;
169+
}
170+
171+
log "-----";
172+
173+
i = 0u;
174+
while (i < num_to_insert) {
175+
check (hm.insert(i, i * i));
176+
log "inserting " + std._uint.to_str(i, 10u)
177+
+ " -> " + std._uint.to_str(i * i, 10u);
178+
i += 2u;
179+
}
180+
181+
check (hm.size() == num_to_insert);
182+
183+
log "-----";
184+
185+
i = 0u;
186+
while (i < num_to_insert) {
187+
log "get(" + std._uint.to_str(i, 10u) + ") = "
188+
+ std._uint.to_str(hm.get(i), 10u);
189+
check (hm.get(i) == i * i);
190+
i += 1u;
191+
}
192+
193+
log "-----";
194+
log "rehashing";
195+
196+
hm.rehash();
197+
198+
log "-----";
199+
200+
check (hm.size() == num_to_insert);
201+
202+
i = 0u;
203+
while (i < num_to_insert) {
204+
log "get(" + std._uint.to_str(i, 10u) + ") = "
205+
+ std._uint.to_str(hm.get(i), 10u);
206+
check (hm.get(i) == i * i);
207+
i += 1u;
208+
}
209+
210+
log "*** finished test_removal";
211+
}
212+
92213
fn main() {
93214
test_simple();
94215
test_growth();
216+
test_removal();
95217
}

0 commit comments

Comments
 (0)