From 4dfb55987222f961ea60db7026fcf281a9f493f7 Mon Sep 17 00:00:00 2001 From: Oleksandr Yakushev Date: Mon, 26 Aug 2024 21:51:50 +0300 Subject: [PATCH] Add native implementation for IKVReduce in toucan2.instance.Instance (#174) Without this, if kv-reduce is called on an Instance, the code follows the slow unoptimal path of calling 'reduce' on the map and constructing MapEntries. --- src/toucan2/instance.clj | 5 +++++ test/toucan2/instance_test.clj | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/toucan2/instance.clj b/src/toucan2/instance.clj index a1fd05d..6f73676 100644 --- a/src/toucan2/instance.clj +++ b/src/toucan2/instance.clj @@ -13,6 +13,7 @@ current value and their model is the same." (:refer-clojure :exclude [instance?]) (:require + clojure.core.protocols [potemkin :as p] [pretty.core :as pretty] [toucan2.protocols :as protocols] @@ -137,6 +138,10 @@ (asTransient [_this] (->TransientInstance model (transient m) mta)) + clojure.lang.IKVReduce + (kvreduce [_this f init] + (clojure.core.protocols/kv-reduce m f init)) + protocols/IModel (protocols/model [_this] model) diff --git a/test/toucan2/instance_test.clj b/test/toucan2/instance_test.clj index e99d17e..b8cea7c 100644 --- a/test/toucan2/instance_test.clj +++ b/test/toucan2/instance_test.clj @@ -429,3 +429,8 @@ m2 (assoc m :location nil)] (is (= {:location nil} (protocols/changes m2)))))) + +(deftest ^:parallel reduce-kv-test + (testing "instance supports IKVReduce iteration natively" + (let [instance (instance/instance ::foo (zipmap (range 100) (range)))] + (is (= 100 (.kvreduce instance (fn [c _ _] (inc c)) 0))))))