Skip to content

Commit 68d2d3b

Browse files
committed
use transient sets during transaction
1 parent 51b89ac commit 68d2d3b

5 files changed

Lines changed: 49 additions & 33 deletions

File tree

dev/user.clj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@
6565
(let [class (.getClassName e)]
6666
(when (and (not (str/starts-with? class "clojure."))
6767
(not (str/starts-with? class "nrepl."))
68-
(not (str/starts-with? class "java.")))
68+
(not (str/starts-with? class "java."))
69+
(not (str/starts-with? class "user$"))
70+
(not (str/starts-with? class "user/"))
71+
(not (str/starts-with? class "leiningen.")))
6972
(print prefix)
7073
(let [method (.getMethodName e)
7174
[_ ns fun] (re-matches #"([A-Za-z0-9_.-]+)\$([A-Za-z0-9_.-]+)" (str class))]

src-java/datascript/SortedSet.java

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,6 @@
33
import java.util.*;
44
import clojure.lang.*;
55

6-
/**
7-
* 8 max 16 max 32 max 64 max 128 max 256 max 512 max 1024 max
8-
*
9-
* 100K ADDs
10-
* 23..30ms 19..21ms 19..23ms 19..22ms 19..22ms 20..22ms 21..29ms 24..28ms
11-
*
12-
* 100K CONTAINS
13-
* 17..18ms 13..15ms 14..16ms 14..16ms 14..16ms 15..17ms 15..17ms 15..17ms
14-
*
15-
* ITERATE over 1M
16-
* 17..18ms 10..12ms 8..10ms 6.. 8ms 6.. 7ms 5.. 7ms 5.. 6ms 5..18ms
17-
*
18-
* SEQ ITER over 1M
19-
* 21..24ms 17..26ms 16..23ms 14..21ms 14..20ms 14..20ms 13..18ms 13..18ms
20-
*
21-
* 100K REMOVEs
22-
* 27..31ms 21..22ms 19..21ms 18..19ms 18..20ms 18..21ms 18..19ms 20..29ms
23-
*/
24-
256
@SuppressWarnings("unchecked")
267
public class SortedSet extends ASortedSet implements IEditableCollection, ITransientSet, Reversible, Sorted, IReduce, ISortedSet {
278

@@ -64,6 +45,11 @@ public SortedSet(IPersistentMap meta, Comparator cmp) {
6445
_edit = edit;
6546
}
6647

48+
void ensureEditable(boolean value) {
49+
if (value != _edit.editable())
50+
throw new RuntimeException("Expected" + (value ? " transient" : " persistent") + "set");
51+
}
52+
6753
// ISortedSet
6854
public Seq slice(Object from, Object to) { return slice(from, to, _cmp); }
6955
public Seq slice(Object from, Object to, Comparator cmp) {
@@ -243,15 +229,17 @@ public boolean contains(Object key) {
243229

244230
// IEditableCollection
245231
public SortedSet asTransient() {
232+
ensureEditable(false);
246233
return new SortedSet(_meta, _cmp, _root, _count, new Edit(true));
247234
}
248235

249236
// ITransientCollection
250237
public SortedSet conj(Object key) {
251-
return cons(key);
238+
return cons(key, _cmp);
252239
}
253240

254241
public SortedSet persistent() {
242+
ensureEditable(true);
255243
_edit.setEditable(false);
256244
return this;
257245
}

src/datascript/btset.clj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
datascript.btset
44
(:refer-clojure :exclude [iter])
55
(:import
6+
[java.util Comparator]
67
[datascript SortedSet]))
78

89
(defn btset-conj [set key cmp]
@@ -20,18 +21,18 @@
2021
([set from to]
2122
(.slice ^SortedSet set from to))
2223
([set from to cmp]
23-
(.slice ^SortedSet set from to cmp)))
24+
(.slice ^SortedSet set from to ^Comparator cmp)))
2425

2526
(defn rslice
2627
"`(rslice set from to)` returns backwards iterator for all Xs where from <= X <= to.
2728
`(rslice set from nil)` returns backwards iterator for all Xs where X <= from."
2829
([set from to]
2930
(.rslice ^SortedSet set from to))
3031
([set from to cmp]
31-
(.rslice ^SortedSet set from to cmp)))
32+
(.rslice ^SortedSet set from to ^Comparator cmp)))
3233

3334
(defn btset-by
34-
([cmp] (SortedSet. cmp))
35+
([cmp] (SortedSet. ^Comparator cmp))
3536
([cmp & keys]
3637
(into (btset-by cmp) keys)))
3738

src/datascript/db.cljc

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,18 @@
393393
(declare hash-db hash-fdb equiv-db empty-db resolve-datom validate-attr components->pattern indexing?)
394394
#?(:cljs (declare pr-db))
395395

396+
(defn db-transient [db]
397+
(-> db
398+
(update :eavt transient)
399+
(update :aevt transient)
400+
(update :avet transient)))
401+
402+
(defn db-persistent! [db]
403+
(-> db
404+
(update :eavt persistent!)
405+
(update :aevt persistent!)
406+
(update :avet persistent!)))
407+
396408
(defrecord-updatable DB [schema eavt aevt avet max-eid max-tx rschema hash]
397409
#?@(:cljs
398410
[IHash (-hash [db] (hash-db db))
@@ -401,7 +413,10 @@
401413
IReversible (-rseq [db] (-rseq (.-eavt db)))
402414
ICounted (-count [db] (count (.-eavt db)))
403415
IEmptyableCollection (-empty [db] (empty-db (.-schema db)))
404-
IPrintWithWriter (-pr-writer [db w opts] (pr-db db w opts))]
416+
IPrintWithWriter (-pr-writer [db w opts] (pr-db db w opts))
417+
IEditableCollection (-as-transient [db] (db-transient db))
418+
ITransientCollection (-conj! [db key] (throw (ex-info "datascript.DB/conj! is not supported" {})))
419+
(-persistent! [db] (db-persistent! db))]
405420

406421
:clj
407422
[Object (hashCode [db] (hash-db db))
@@ -410,7 +425,12 @@
410425
clojure.lang.IPersistentCollection
411426
(count [db] (count eavt))
412427
(equiv [db other] (equiv-db db other))
413-
(empty [db] (empty-db schema))])
428+
(empty [db] (empty-db schema))
429+
clojure.lang.IEditableCollection
430+
(asTransient [db] (db-transient db))
431+
clojure.lang.ITransientCollection
432+
(conj [db key] (throw (ex-info "datascript.DB/conj! is not supported" {})))
433+
(persistent [db] (db-persistent! db))])
414434

415435
IDB
416436
(-schema [db] (.-schema db))
@@ -1106,16 +1126,18 @@
11061126
(sequential? initial-es))
11071127
(raise "Bad transaction data " initial-es ", expected sequential collection"
11081128
{:error :transact/syntax, :tx-data initial-es}))
1109-
(loop [report initial-report
1129+
(loop [report (-> initial-report
1130+
(update :db-after transient))
11101131
es initial-es]
11111132
(let [[entity & entities] es
1112-
db (:db-after report)
1113-
{:keys [tempids]} report]
1133+
db (:db-after report)
1134+
{:keys [tempids]} report]
11141135
(cond
11151136
(empty? es)
11161137
(-> report
11171138
(assoc-in [:tempids :db/current-tx] (current-tx report))
1118-
(update-in [:db-after :max-tx] inc))
1139+
(update-in [:db-after :max-tx] inc)
1140+
(update :db-after persistent!))
11191141

11201142
(nil? entity)
11211143
(recur report entities)

test/datascript/test/btset.cljc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
(:require
33
[datascript.btset :as btset]
44
#?(:cljs [cljs.test :as t :refer-macros [is are deftest testing]]
5-
:clj [clojure.test :as t :refer [is are deftest testing]])))
5+
:clj [clojure.test :as t :refer [is are deftest testing]]))
6+
#?(:clj
7+
(:import [clojure.lang IReduce])))
68

79

810
#?(:cljs (enable-console-print!))
@@ -266,8 +268,8 @@
266268

267269

268270
(defn ireduce
269-
([f coll] (#?(:clj .reduce :cljs -reduce) coll f))
270-
([f val coll] (#?(:clj .reduce :cljs -reduce) coll f val)))
271+
([f coll] (#?(:clj .reduce :cljs -reduce) ^IReduce coll f))
272+
([f val coll] (#?(:clj .reduce :cljs -reduce) ^IReduce coll f val)))
271273

272274

273275
(defn reduce-chunked [f val coll]

0 commit comments

Comments
 (0)