mirror of
https://github.com/carp-lang/Carp.git
synced 2024-11-10 19:54:38 +03:00
247 lines
7.1 KiB
Plaintext
247 lines
7.1 KiB
Plaintext
(definterface hash (Fn [(Ref a)] Int))
|
||
|
||
(defmodule String
|
||
(defn rehash [k l]
|
||
(let-do [a 31415
|
||
b 27183
|
||
vh 0]
|
||
(for [x 0 (length k)]
|
||
(do
|
||
(set! vh (+ (* a (* vh l)) (Char.to-int (char-at k x))))
|
||
(set! a (* a b))
|
||
(set! x (Int.inc x))))
|
||
(Int.abs vh)))
|
||
|
||
(defn hash [k]
|
||
(rehash k 1))
|
||
)
|
||
|
||
(defmodule Int
|
||
(defn hash [k] (the Int @k))
|
||
)
|
||
|
||
(defmodule Long
|
||
(defn hash [k] (to-int (the Long @k)))
|
||
)
|
||
|
||
(defmodule Bool
|
||
(defn hash [k] (if (the Bool @k) 1 0))
|
||
)
|
||
|
||
(defmodule Char
|
||
(defn hash [k] (to-int (the Char @k)))
|
||
)
|
||
|
||
(defmodule Float
|
||
(defn hash [k] (to-bytes @k))
|
||
)
|
||
|
||
(defmodule Double
|
||
(defn hash [k] (Long.to-int (to-bytes @k)))
|
||
)
|
||
|
||
(deftype (Entry a b) [key a value b])
|
||
(deftype (Bucket a b) [entries (Array (Entry a b))])
|
||
|
||
(defmodule Bucket
|
||
(defn empty []
|
||
(Bucket.init []))
|
||
|
||
(defn grow [b e]
|
||
(set-entries @b (Array.push-back @(entries b) e)))
|
||
|
||
(defn get [b k]
|
||
(let-do [e &(zero)
|
||
l (Array.length (Bucket.entries b))
|
||
es (entries b)]
|
||
(for [i 0 l]
|
||
(when (= (Entry.key (Array.nth es i)) k)
|
||
(do
|
||
(set! e (Entry.value (Array.nth es i)))
|
||
(break))))
|
||
@e))
|
||
|
||
(defn contains? [b k]
|
||
(let-do [e false
|
||
l (Array.length (Bucket.entries b))
|
||
es (entries b)]
|
||
(for [i 0 l]
|
||
(when (= (Entry.key (Array.nth es i)) k)
|
||
(do
|
||
(set! e true)
|
||
(break))))
|
||
e))
|
||
|
||
(defn remove [entries k]
|
||
(let-do [nentries (the (Array (Entry a b)) [])]
|
||
(for [i 0 (Array.length entries)]
|
||
(let [e (Array.nth entries i)]
|
||
(unless (= (Entry.key e) k)
|
||
(set! nentries (Array.push-back nentries @e)))))
|
||
nentries))
|
||
|
||
(defn shrink [b k]
|
||
(if (contains? b k)
|
||
(set-entries @b (remove (entries b) k))
|
||
@b))
|
||
)
|
||
|
||
(deftype (Map a b) [n-buckets Int buckets (Array (Bucket a b))])
|
||
|
||
(defmodule Map
|
||
(hidden dflt-len)
|
||
(def dflt-len 256)
|
||
|
||
(doc create "Create an empty hashmap.")
|
||
(defn create []
|
||
(init dflt-len (Array.repeat dflt-len Bucket.empty)))
|
||
|
||
(doc create-with-len "Create an empty hashmap with a given minimum size.")
|
||
(defn create-with-len [len]
|
||
(init len (Array.repeat len Bucket.empty)))
|
||
|
||
(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))
|
||
b (buckets m)]
|
||
(set-buckets @m (Array.aset @b
|
||
idx
|
||
(Bucket.grow (Array.nth b idx) (Entry.init @k @v))))))
|
||
|
||
(doc get "Get the value for the key k from map m. If it isn’t found, a zero element is returned.")
|
||
(defn get [m k]
|
||
(let [idx (Int.mod (hash k) @(n-buckets m))]
|
||
(Bucket.get (Array.nth (buckets m) idx) k)))
|
||
|
||
(doc length "Get the length of the map m.")
|
||
(defn length [m]
|
||
(let-do [c 0]
|
||
(for [i 0 @(n-buckets m)]
|
||
(set! c (+ c (Array.length (Bucket.entries (Array.nth (buckets m) i))))))
|
||
c))
|
||
|
||
(doc length "Check whether the map m is empty.")
|
||
(defn empty? [m]
|
||
(= (length m) 0))
|
||
|
||
(doc contains? "Check whether the map m contains the key k.")
|
||
(defn contains? [m k]
|
||
(let [idx (Int.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))
|
||
b (buckets &m)]
|
||
(set-buckets m (Array.aset @b
|
||
idx
|
||
(Bucket.shrink (Array.nth b idx) k)))))
|
||
|
||
(doc for-each "Execute the binary function f for all keys and value in map m.")
|
||
(defn for-each [m f]
|
||
(for [i 0 @(n-buckets m)]
|
||
(let [bucket (Array.nth (buckets m) i)
|
||
len (Array.length (Bucket.entries bucket))
|
||
entries (Bucket.entries bucket)]
|
||
(for [j 0 len]
|
||
(let [e (Array.nth entries j)]
|
||
(f (Entry.key e) (Entry.value e)))))))
|
||
|
||
(doc from-array "Create a map from the array a containing key-value pairs.")
|
||
(defn from-array [a]
|
||
(let-do [m (create)]
|
||
(for [i 0 (Array.length a)]
|
||
(let [e (Array.nth a i)
|
||
k (Pair.a e)
|
||
v (Pair.b e)]
|
||
(set! m (put &m k v))))
|
||
m))
|
||
|
||
(defn str [m]
|
||
(let-do [res @"{"]
|
||
(for [i 0 @(n-buckets m)]
|
||
(let [bucket (Array.nth (buckets m) i)
|
||
len (Array.length (Bucket.entries bucket))
|
||
entries (Bucket.entries bucket)]
|
||
(for [j 0 len]
|
||
(let [e (Array.nth entries j)]
|
||
(set! res (String.join @"" &[res @" " (prn @(Entry.key e)) @" " (prn @(Entry.value e))]))))))
|
||
(String.append &res " }")))
|
||
)
|
||
|
||
(deftype (Set a) [n-buckets Int buckets (Array (Bucket a Bool))])
|
||
|
||
(defmodule Set
|
||
(def dflt-len 256)
|
||
|
||
(doc create "Create an empty hashset.")
|
||
(defn create []
|
||
(init dflt-len (Array.repeat dflt-len Bucket.empty)))
|
||
|
||
(doc create-with-len "Create an empty hashset with a given minimum size.")
|
||
(defn create-with-len [len]
|
||
(init len (Array.repeat len Bucket.empty)))
|
||
|
||
(doc put "Put a a value v into set m, using the key k.")
|
||
(defn put [m k]
|
||
(let [idx (Int.mod (hash k) @(n-buckets m))
|
||
b (buckets m)]
|
||
(set-buckets @m (Array.aset @b
|
||
idx
|
||
(Bucket.grow (Array.nth b idx) (Entry.init @k true))))))
|
||
|
||
(doc length "Get the length of set m.")
|
||
(defn length [m]
|
||
(let-do [c 0]
|
||
(for [i 0 @(n-buckets m)]
|
||
(set! c (+ c (Array.length (Bucket.entries (Array.nth (buckets m) i))))))
|
||
c))
|
||
|
||
(doc empty? "Check whether the set m is empty.")
|
||
(defn empty? [m]
|
||
(= (length m) 0))
|
||
|
||
(doc contains? "Check whether the set m contains a value associated with key k.")
|
||
(defn contains? [m k]
|
||
(let [idx (Int.mod (hash k) @(n-buckets m))]
|
||
(Bucket.contains? (Array.nth (buckets m) idx) k)))
|
||
|
||
(doc remove "Remove the value associated with key k from set m.")
|
||
(defn remove [m k]
|
||
(let [idx (Int.mod (hash k) @(n-buckets &m))
|
||
b (buckets &m)]
|
||
(set-buckets m (Array.aset @b
|
||
idx
|
||
(Bucket.shrink (Array.nth b idx) k)))))
|
||
|
||
|
||
(doc for-each "Execute the unary function f for each element in set m.")
|
||
(defn for-each [m f]
|
||
(for [i 0 @(n-buckets m)]
|
||
(let [bucket (Array.nth (buckets m) i)
|
||
len (Array.length (Bucket.entries bucket))
|
||
entries (Bucket.entries bucket)]
|
||
(for [j 0 len]
|
||
(let [e (Array.nth entries j)]
|
||
(f (Entry.key e)))))))
|
||
|
||
(doc from-array "Create a set from the values in array a.")
|
||
(defn from-array [a]
|
||
(let-do [m (create)]
|
||
(for [i 0 (Array.length a)]
|
||
(let [e (Array.nth a i)]
|
||
(set! m (put &m e))))
|
||
m))
|
||
|
||
(defn str [m]
|
||
(let-do [res @"{"]
|
||
(for [i 0 @(n-buckets m)]
|
||
(let [bucket (Array.nth (buckets m) i)
|
||
len (Array.length (Bucket.entries bucket))
|
||
entries (Bucket.entries bucket)]
|
||
(for [j 0 len]
|
||
(let [e (Array.nth entries j)]
|
||
(set! res (String.join @"" &[res @" " (prn @(Entry.key e))]))))))
|
||
(String.append &res " }")))
|
||
)
|