A simple Bloom filter. It is dependency-free (Clojure only) and Babashka-compatible.
add and hit? take a byte[] key. Converting your items to bytes is the
caller's responsibility — e.g. (.getBytes s "UTF-8") for string keys.
(require '[blossom.core :as blossom])
(defn b [^String s] (.getBytes s "UTF-8"))
(let [bf (blossom/make-filter {})]
(blossom/add bf (b "a"))
(blossom/add bf (b "abc"))
(prn (blossom/hit? bf (b "a"))) ;; -> true
(prn (blossom/hit? bf (b "bc"))) ;; -> false
(prn (blossom/hit? bf (b "abc")))) ;; -> truemake-filtermakes a Bloom filter with the following paramters(blossom/make-filter {:hash-size "SHA-256" :size 1024 :num-hashes 3 :thread-safe? false})
hash-algo: You can specify an algorithm for the hash function. "MD2", "MD5", "SHA-1", "SHA-224", "SHA-256", "SHA-384" or "SHA-512" can be set. By default, "SHA-256" will be set.size: Bloom filter's size in bits. By default, the size will be 1024 bits.num-hashes: This specifies the number of bits set to the filter when an item is added. By default, this will be 3.thread-safe?: If this is true, a thread-safe filter is made. The performance of the filter will be lower than that of a filter with{:thread-safe false}. BY default, it will be false.
A filter can be serialized to a byte[] and restored later. serialize-filter
writes the salts and the bit array in a self-describing binary format;
deserialize-filter reads them back, given the same params used to build the
filter.
(let [bytes (blossom/serialize-filter bf)]
;; ... persist `bytes` somewhere ...
(blossom/deserialize-filter bytes {:size 1024}))blossom serializes only its own salts and bit array — it never serializes your keys. Integrity framing (checksums, etc.) is left to the caller.