Skip to content

Commit d67931b

Browse files
committed
Stable sorting of sequences of various types #470
1 parent a527437 commit d67931b

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# WIP
2+
3+
- Stable sorting of sequences of various types #470
4+
15
# 1.6.5 - May 3, 2024
26

37
- Regression: fixed some OR queries broken in 1.6.4 #468 #469

src/datascript/db.cljc

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,11 +438,46 @@
438438
#?(:clj (. clojure.lang.Util (hasheq x))
439439
:cljs (hash x)))
440440

441-
(defn value-compare
442-
^long [x y]
441+
(declare+ ^number value-compare [x y])
442+
443+
(defn- seq-compare [xs ys]
444+
(let [cx (count xs)
445+
cy (count ys)]
446+
(cond
447+
(< cx cy)
448+
-1
449+
450+
(> cx cy)
451+
1
452+
453+
:else
454+
(loop [xs xs
455+
ys ys]
456+
(if (empty? xs)
457+
0
458+
(let [x (first xs)
459+
y (first ys)]
460+
(cond
461+
(and (nil? x) (nil? y))
462+
(recur (next xs) (next ys))
463+
464+
(nil? x)
465+
-1
466+
467+
(nil? y)
468+
1
469+
470+
:else
471+
(let [v (value-compare x y)]
472+
(if (= v 0)
473+
(recur (next xs) (next ys))
474+
v)))))))))
475+
476+
(defn+ ^number value-compare [x y]
443477
(try
444478
(cond
445479
(= x y) 0
480+
(and (sequential? x) (sequential? y)) (seq-compare x y)
446481
#?@(:clj [(instance? Number x) (clojure.lang.Numbers/compare x y)])
447482
#?@(:clj [(instance? Comparable x) (.compareTo ^Comparable x y)]
448483
:cljs [(satisfies? IComparable x) (-compare x y)])

test/datascript/test/index.cljc

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,25 @@
6363
(d/datoms db :avet :name "Ivan")))
6464

6565
(is (thrown-msg? "Attribute :name should be marked as :db/index true"
66-
(d/datoms db :avet :name "Ivan" 1))))))
66+
(d/datoms db :avet :name "Ivan" 1))))
67+
68+
(testing "Sequence compare issue-470"
69+
(let [db (-> (d/empty-db {:path {:db/index true}})
70+
(d/db-with [{:db/id 1 :path [1 2]}
71+
{:db/id 2 :path [1 2 3]}]))]
72+
(are [value result] (= result (mapv :e (d/datoms db :avet :path value)))
73+
[1] []
74+
[1 1] []
75+
[1 2] [1]
76+
(list 1 2) [1]
77+
(butlast [1 2 3]) [1]
78+
[1 3] []
79+
[1 2 2] []
80+
[1 2 3] [2]
81+
(list 1 2 3) [2]
82+
(butlast [1 2 3 4]) [2]
83+
[1 2 4] []
84+
[1 2 3 4] [])))))
6785

6886
(deftest test-datom
6987
(let [dvec #(when % (vector (:e %) (:a %) (:v %)))

0 commit comments

Comments
 (0)