From bed82e10d3ab4af51958dd5c425b865bee5e9d99 Mon Sep 17 00:00:00 2001 From: Ben Sless Date: Tue, 24 Aug 2021 19:16:31 +0300 Subject: [PATCH] Add lightweight keyset wrapper Saves on allocation and provides an immutable facade to underlying regular set --- src/malli/core.cljc | 49 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/malli/core.cljc b/src/malli/core.cljc index eeb69fdf4..2ab600023 100644 --- a/src/malli/core.cljc +++ b/src/malli/core.cljc @@ -278,14 +278,49 @@ (-arange [^objects arr to] #?(:clj (let [-arr (object-array to)] (System/arraycopy arr 0 -arr 0 to) -arr) :cljs (.slice arr 0 to))) + #?(:clj + (-set-wrapper + [^java.util.Set s] + (reify + Collection + (size [_] (.size s)) + (containsAll [_ c] (.containsAll s c)) + clojure.lang.IPersistentSet + (disjoin [_ key] (disj (set s) key)) + (contains [_ key] (.contains s key)) + (get [_ key] (when (.contains s key) key)) + clojure.lang.Counted + (count [_] (.size s)) + clojure.lang.IPersistentCollection + (cons [_ o] (.cons (set s) o)) + (empty [_] #{}) + (equiv [_ o] + (if (instance? java.util.Set o) + (if (== (.size s) (.size ^Collection o)) + (.containsAll s o) + false) + false)) + clojure.lang.Seqable + (seq [_] (seq s)) + clojure.lang.IFn + (invoke [_ o] (when (.contains s o) o)) + Iterable + (iterator [_] (.iterator s))))) (-keyset [] - (let [data (volatile! #{})] - (fn - ([] @data) - ([k] (let [old @data] - (vswap! data conj k) - (when (= old @data) - (-fail! ::non-distinct-entry-keys {:keys old, :key k})))))))] + #?(:clj + (let [data (java.util.HashSet.)] + (fn + ([] (-set-wrapper data)) + ([k] (when-not (.add data k) + (-fail! ::non-distinct-entry-keys {:keys (seq data), :key k}))))) + :cljs + (let [data (volatile! #{})] + (fn + ([] @data) + ([k] (let [old @data] + (vswap! data conj k) + (when (= old @data) + (-fail! ::non-distinct-entry-keys {:keys old, :key k}))))))))] (let [n (count children) -children (object-array n) -entries (object-array n)