Skip to content

Commit

Permalink
stdlib: add HashMap#includes and HashSet#includes, add tests
Browse files Browse the repository at this point in the history
works on #88
  • Loading branch information
soc committed Dec 27, 2023
1 parent 5501dfc commit e50234e
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 0 deletions.
64 changes: 64 additions & 0 deletions dora/stdlib/collections.dora
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,38 @@ impl[K: Hash + Identity + Equals, V] HashMap[K, V] {
false
}

@pub fun includes(key: K): Bool {
assert(self.entries <= self.cap);

if self.entries == 0i64 {
return false;
}

var hash = key.hash();
var idx = hash.toInt64() & (self.cap - 1i64);

while true {
if self
... .isLive(idx) {
let currentKey = self.keys.get(idx);

if currentKey.hash() == hash && currentKey.identicalTo(key) {
return true;
}
idx = (idx + 1i64) & (self.cap - 1i64);
}
... .isDeleted(idx) {
// There might be live entries after a deleted one.
idx = (idx + 1i64) & (self.cap - 1i64);
}
else {
return false;
}
}

false
}

@pub fun get(key: K): Option[V] {
assert(self.entries <= self.cap);

Expand Down Expand Up @@ -878,6 +910,38 @@ impl[K: Hash + Identity + Equals] HashSet[K] {
unreachable[Option[K]]()
}

@pub fun includes(key: K): Bool {
assert(self.entries <= self.cap);

if self.entries == 0i64 {
return false;
}

var hash = key.hash();
var idx = hash.toInt64() & (self.cap - 1i64);

while true {
if self
... .isLive(idx) {
let currentKey = self.keys.get(idx);

if currentKey.hash() == hash && currentKey.identicalTo(key) {
return true;
}
idx = (idx + 1i64) & (self.cap - 1i64);
}
... .isDeleted(idx) {
// There might be live entries after a deleted one.
idx = (idx + 1i64) & (self.cap - 1i64);
}
else {
return false;
}
}

false
}

@pub fun contains(key: K): Bool {
assert(self.entries <= self.cap);

Expand Down
20 changes: 20 additions & 0 deletions tests/stdlib/hashset-includes-infinity.dora
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
fun main(): Unit {
float64();
float32();
}

fun float64(): Unit {
let set = std::HashSet[Float64]::new(Float64::infinityPositive(), Float64::infinityNegative());

assert(set.size() == 2);
assert(set.includes(Float64::infinityPositive()));
assert(set.includes(Float64::infinityNegative()));
}

fun float32(): Unit {
let set = std::HashSet[Float32]::new(Float32::infinityPositive(), Float32::infinityNegative());

assert(set.size() == 2);
assert(set.includes(Float32::infinityPositive()));
assert(set.includes(Float32::infinityNegative()));
}
18 changes: 18 additions & 0 deletions tests/stdlib/hashset-includes-nan.dora
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
fun main(): Unit {
float64();
float32();
}

fun float64(): Unit {
let set = std::HashSet[Float64]::new(Float64::notANumber());

assert(set.size() == 1i64);
assert(set.includes(Float64::notANumber()));
}

fun float32(): Unit {
let set = std::HashSet[Float32]::new(Float32::notANumber());

assert(set.size() == 1i64);
assert(set.includes(Float32::notANumber()));
}
20 changes: 20 additions & 0 deletions tests/stdlib/hashset-includes-zero.dora
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
fun main(): Unit {
float64();
float32();
}

fun float64(): Unit {
let set = std::HashSet[Float64]::new(0.0);

assert(set.size() == 1i64);
assert(set.includes(0.0));
assert(set.includes(-0.0).not());
}

fun float32(): Unit {
let set = std::HashSet[Float32]::new(0.0f32);

assert(set.size() == 1i64);
assert(set.includes(0.0f32));
assert(set.includes(-0.0f32).not());
}
9 changes: 9 additions & 0 deletions tests/stdlib/hashset-includes.dora
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fun main(): Unit {
let set = std::HashSet[Int32]::new(1i32, 10'000i32, 7i32);

assert(set.size() == 3);
assert(set.includes(1i32));
assert(set.includes(10'000i32));
assert(set.includes(7i32));
assert(set.includes(0i32).not());
}

0 comments on commit e50234e

Please sign in to comment.