Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions core/Map.carp
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ returns whatever `f` returns. If the key is missing, returns `default`.")
(doc shrink "shrinks dynamic map.")
(defndynamic shrink [m]
(let [new-size (/ (length m) 2)]
(if (< new-size dflt-len)
(if (< new-size Map.dflt-len)
m
(Map.resize m new-size))))

Expand All @@ -720,7 +720,7 @@ returns whatever `f` returns. If the key is missing, returns `default`.")
(doc put "adds a value `v` under the key `k` into the map. If `k` already
exists in the map, it is updated.")
(defndynamic put [m k v]
(if (> (/ (* (Map.len m) 100) (length m)) Map.min-load)
(if (> (/ (* (Map.len m) 100) (length m)) Map.max-load)
(Map.put (Map.grow m) k v)
(if (Map.contains? m k)
(Map.update m k (fn [_] v))
Expand Down Expand Up @@ -804,10 +804,13 @@ function `f`. If `k` doesn’t exist in the map, it is set to `(f v)`.")
(doc remove "removes the pair under the key `k` from the map `m`. If it
doesn’t exist, the map is returned unchanged.")
(defndynamic remove [m k]
(if (> (/ (* (Map.len m) 100) (length m)) Map.min-load)
(Map.remove (Map.shrink m) k)
(let [idx (imod (hash k) (length m))]
(reduce (fn [acc l] (cons (filter (fn [pair] (/= (car pair) k)) l) acc)) '() m))))
(if (Map.contains? m k)
(let [idx (Dynamic.imod (hash k) (length m))
removed (List.update-nth m idx (fn [l] (filter (fn [pair] (/= (car pair) k)) l)))]
(if (< (/ (* (Map.len removed) 100) (length removed)) Map.min-load)
(Map.shrink removed)
removed))
m))

(doc all? "checks whether all key value pairs in `m` satisfy the predicate
`pred`. `pred` takes the pair `(k v)` as its sole argument.")
Expand Down
33 changes: 32 additions & 1 deletion test/dynamic_map.carp
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,36 @@
{1 "hi" 2 "bye" 3 "!"}
(Map.merge {1 "bye" 3 "!"} {2 "bye" 1 "hi"})
"merge works"
Map.=))
Map.=)

(assert-dynamic-equal test
16
(length (Map.shrink (Map.create)))
"shrink keeps a map at the default size")

(assert-dynamic-equal test
32
(length (Map.shrink (Map.resize (Map.create) 64)))
"shrink halves a larger map")

(assert-dynamic-equal test
'(1 "b")
(let [m (Map.remove (Map.put (Map.put (Map.create) 1 "a") 2 "b") 1)]
(list (Map.len m) (Map.get m 2)))
"remove drops the key and keeps the others findable")

(assert-dynamic-equal test
32
(length (Map.remove (Map.put (Map.resize (Map.create) 64) 1 "a") 1))
"remove shrinks a sparse map")

(assert-dynamic-equal test
64
(length (Map.remove (Map.put (Map.resize (Map.create) 64) 1 "a") 2))
"remove of a missing key returns the map unchanged")

(assert-dynamic-equal test
16
(length (reduce (fn [m k] (Map.put m k k)) (Map.create) '(1 2 3 4 5 6 7 8)))
"put only grows past max-load"))

Loading