mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 05:25:28 +03:00
fix Map and Set behaviour for negative hash values
fixes #335 - add new Int.positive-mod function - use it for Map and Set operations - add tests
This commit is contained in:
parent
b42e506fc3
commit
cfb61847cb
@ -53,6 +53,13 @@
|
||||
(set! y (/ y 2))
|
||||
(set! x (* x x))))
|
||||
r))
|
||||
|
||||
(doc positive-mod "Like mod but always returns a positive answer.")
|
||||
(defn positive-mod [k n]
|
||||
(let [r (Int.mod k n)]
|
||||
(if (> 0 r)
|
||||
(+ r n)
|
||||
r)))
|
||||
)
|
||||
|
||||
(defmodule IntRef
|
||||
|
@ -101,14 +101,14 @@
|
||||
|
||||
(doc put "Put a a value v into map m, using the key k.")
|
||||
(defn put [m k v]
|
||||
(let [idx (Int.mod (hash k) @(n-buckets &m))]
|
||||
(let [idx (Int.positive-mod (hash k) @(n-buckets &m))]
|
||||
(update-buckets m &(fn [b]
|
||||
(let [n (Array.nth &b idx)]
|
||||
(Array.aset b idx (Bucket.grow n (Pair.init @k @v))))))))
|
||||
|
||||
(doc get "Get the value for the key k from map m. If it isn’t found, a zero element for the value type is returned.")
|
||||
(defn get [m k]
|
||||
(let [idx (Int.mod (hash k) @(n-buckets m))]
|
||||
(let [idx (Int.positive-mod (hash k) @(n-buckets m))]
|
||||
(Bucket.get (Array.nth (buckets m) idx) k)))
|
||||
|
||||
(doc length "Get the length of the map m.")
|
||||
@ -124,12 +124,12 @@
|
||||
|
||||
(doc contains? "Check whether the map m contains the key k.")
|
||||
(defn contains? [m k]
|
||||
(let [idx (Int.mod (hash k) @(n-buckets m))]
|
||||
(let [idx (Int.positive-mod (hash k) @(n-buckets m))]
|
||||
(Bucket.contains? (Array.nth (buckets m) idx) k)))
|
||||
|
||||
(doc remove "Remove the value under the key k from the map m.")
|
||||
(defn remove [m k]
|
||||
(let [idx (Int.mod (hash k) @(n-buckets &m))]
|
||||
(let [idx (Int.positive-mod (hash k) @(n-buckets &m))]
|
||||
(update-buckets m &(fn [b]
|
||||
(let [n (Array.nth &b idx)]
|
||||
(Array.aset b idx (Bucket.shrink n k)))))))
|
||||
@ -216,7 +216,7 @@
|
||||
|
||||
(doc put "Put a a key k into the set s.")
|
||||
(defn put [s k]
|
||||
(let [idx (Int.mod (hash k) @(n-buckets &s))]
|
||||
(let [idx (Int.positive-mod (hash k) @(n-buckets &s))]
|
||||
(update-buckets s &(fn [b]
|
||||
(let [n (Array.nth &b idx)]
|
||||
(Array.aset b idx (SetBucket.grow n @k)))))))
|
||||
@ -234,12 +234,12 @@
|
||||
|
||||
(doc contains? "Check whether the set s contains the key k.")
|
||||
(defn contains? [s k]
|
||||
(let [idx (Int.mod (hash k) @(n-buckets s))]
|
||||
(let [idx (Int.positive-mod (hash k) @(n-buckets s))]
|
||||
(SetBucket.contains? (Array.nth (buckets s) idx) k)))
|
||||
|
||||
(doc remove "Remove the key k from the set s.")
|
||||
(defn remove [s k]
|
||||
(let [idx (Int.mod (hash k) @(n-buckets &s))]
|
||||
(let [idx (Int.positive-mod (hash k) @(n-buckets &s))]
|
||||
(update-buckets s &(fn [b]
|
||||
(let [n (Array.nth &b idx)]
|
||||
(Array.aset b idx (SetBucket.shrink n k)))))))
|
||||
|
@ -58,4 +58,13 @@
|
||||
(assert-equal test
|
||||
1
|
||||
(/ 3 2)
|
||||
"integer division truncates as expected"))
|
||||
"integer division truncates as expected")
|
||||
(assert-equal test
|
||||
3
|
||||
(positive-mod -7 5)
|
||||
"positive-mod works on negative inputs")
|
||||
(assert-equal test
|
||||
0
|
||||
(positive-mod 0 7)
|
||||
"positive-mod works on zero")
|
||||
)
|
||||
|
@ -9,6 +9,11 @@
|
||||
&(Map.get &(Map.put (Map.create) "1" "2") "1")
|
||||
"basic put and get works"
|
||||
)
|
||||
(assert-equal test
|
||||
"2"
|
||||
&(Map.get &(Map.put (Map.create) &-7 "2") &-7)
|
||||
"basic put and get works with negative keys"
|
||||
)
|
||||
(assert-equal test
|
||||
1
|
||||
(Map.length &(Map.put (Map.create) "1" "2"))
|
||||
@ -29,6 +34,16 @@
|
||||
(Map.contains? &(Map.put (Map.create) "1" "2") "1")
|
||||
"contains? works"
|
||||
)
|
||||
(assert-equal test
|
||||
true
|
||||
(Map.contains? &(Map.put (Map.create) &-7 "2") &-7)
|
||||
"contains? works with negative keys"
|
||||
)
|
||||
(assert-equal test
|
||||
false
|
||||
(Map.contains? &(Map.put (Map.create) &1 "2") &-7)
|
||||
"contains? works with negative keys"
|
||||
)
|
||||
(assert-equal test
|
||||
true
|
||||
(Map.empty? &(the (Map Int Int) (Map.create)))
|
||||
@ -80,6 +95,11 @@
|
||||
(Set.contains? &(Set.put (Set.create) "1") "1")
|
||||
"contains? works"
|
||||
)
|
||||
(assert-equal test
|
||||
true
|
||||
(Set.contains? &(Set.put (Set.create) &-7) &-7)
|
||||
"contains? works with negative keys"
|
||||
)
|
||||
(assert-equal test
|
||||
true
|
||||
(Set.empty? &(the (Set Int) (Set.create)))
|
||||
|
Loading…
Reference in New Issue
Block a user