Skip to content

Commit

Permalink
Fix premature termination of hitchhiker tree -slice (#523)
Browse files Browse the repository at this point in the history
  • Loading branch information
yflim authored May 2, 2022
1 parent 3927864 commit 4cc250b
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 20 deletions.
28 changes: 9 additions & 19 deletions src/datahike/index/hitchhiker_tree.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -68,30 +68,20 @@
(let [create-datom (index-type->datom-fn index-type)
[a b c d] (from-datom from index-type true)
[e f g h] (from-datom to index-type false)
datom-vec-compare (fn [v1 v2] (-> (filter #(not (= % 0)) (map kc/-compare v1 v2))
first
(or 0)))
xf (comp
(take-while (fn [^AMapEntry kv]
;; prefix scan
(let [key (.key kv)
[i j k l] key
new (not (cond (and e f g h)
(or (> (kc/-compare i e) 0)
(> (kc/-compare j f) 0)
(> (kc/-compare k g) 0)
(> (kc/-compare l h) 0))

(and e f g)
(or (> (kc/-compare i e) 0)
(> (kc/-compare j f) 0)
(> (kc/-compare k g) 0))

(and e f)
(or (> (kc/-compare i e) 0)
(> (kc/-compare j f) 0))

e
(> (kc/-compare i e) 0)

:else false))]
new (< (cond (and e f g h) (datom-vec-compare [i j k l] [e f g h])
(and e f g) (datom-vec-compare [i j k] [e f g])
(and e f) (datom-vec-compare [i j] [e f])
e (kc/-compare i e)
:else 0)
1)]
new)))
(map (fn [kv]
(let [[a b c d] (.key ^AMapEntry kv)]
Expand Down
87 changes: 86 additions & 1 deletion test/datahike/test/index_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
#?(:cljs [cljs.test :as t :refer-macros [is deftest testing]]
:clj [clojure.test :as t :refer [is deftest testing]])
[datahike.api :as d]
[datahike.db :as db]))
[datahike.constants :refer [e0 tx0 emax txmax]]
[datahike.datom :as dd]
[datahike.db :as db]
[datahike.index :as di]))

(deftest test-datoms
(let [dvec #(vector (:e %) (:a %) (:v %))
Expand Down Expand Up @@ -154,3 +157,85 @@
[2 :age 20]
[5 :age 20]
[4 :age 45]]))))

(deftest test-slice
(let [dvec #(vector (:e %) (:a %) (:v %))
db (d/db-with
(db/empty-db {:name {:db/index true}
:age {:db/index true}})
[{:db/id 1 :name "Ivan" :age 15}
{:db/id 2 :name "Oleg" :age 20}
{:db/id 3 :name "Sergey" :age 7}
{:db/id 4 :name "Pavel" :age 45}
{:db/id 5 :name "Petr" :age 20}])
eavt (:eavt db)
aevt (:aevt db)
avet (:avet db)]

(is (= (di/-slice eavt (dd/datom e0 nil nil tx0) (dd/datom emax nil nil txmax) :eavt)
(d/datoms db :eavt)))
(is (= (map dvec (di/-slice eavt (dd/datom e0 nil nil tx0) (dd/datom 2 nil nil tx0) :eavt))
[[1 :age 15]
[1 :name "Ivan"]
[2 :age 20]
[2 :name "Oleg"]]))
(is (= (map dvec (di/-slice eavt (dd/datom e0 nil nil tx0) (dd/datom 3 :age 7 txmax) :eavt))
[[1 :age 15]
[1 :name "Ivan"]
[2 :age 20]
[2 :name "Oleg"]
[3 :age 7]]))
(is (= (map dvec (di/-slice eavt (dd/datom e0 :age nil tx0) (dd/datom 3 :name "Timofey" txmax) :eavt))
[[1 :age 15]
[1 :name "Ivan"]
[2 :age 20]
[2 :name "Oleg"]
[3 :age 7]
[3 :name "Sergey"]]))
(is (= (map dvec (di/-slice eavt (dd/datom e0 :age nil tx0) (dd/datom 3 :name "Timofey" tx0) :eavt))
[[1 :age 15]
[1 :name "Ivan"]
[2 :age 20]
[2 :name "Oleg"]
[3 :age 7]
[3 :name "Sergey"]]))
(is (= (map dvec (di/-slice eavt (dd/datom e0 :age nil tx0) (dd/datom 5 :age nil txmax) :eavt))
[[1 :age 15]
[1 :name "Ivan"]
[2 :age 20]
[2 :name "Oleg"]
[3 :age 7]
[3 :name "Sergey"]
[4 :age 45]
[4 :name "Pavel"]
[5 :age 20]]))

(is (= (map dvec (di/-slice aevt (dd/datom e0 nil nil tx0) (dd/datom 3 :name "Pavel" txmax) :aevt))
[[1 :age 15]
[2 :age 20]
[3 :age 7]
[4 :age 45]
[5 :age 20]
[1 :name "Ivan"]
[2 :name "Oleg"]]))
(is (= (map dvec (di/-slice aevt (dd/datom e0 nil nil tx0) (dd/datom 5 :age 18 txmax) :aevt))
[[1 :age 15]
[2 :age 20]
[3 :age 7]
[4 :age 45]]))
(is (= (map dvec (di/-slice aevt (dd/datom e0 nil nil tx0) (dd/datom 3 :name nil txmax) :aevt))
[[1 :age 15]
[2 :age 20]
[3 :age 7]
[4 :age 45]
[5 :age 20]
[1 :name "Ivan"]
[2 :name "Oleg"]
[3 :name "Sergey"]]))

(is (= (map dvec (di/-slice avet (dd/datom e0 nil nil tx0) (dd/datom 3 :age 50 txmax) :avet))
[[3 :age 7]
[1 :age 15]
[2 :age 20]
[5 :age 20]
[4 :age 45]]))))

0 comments on commit 4cc250b

Please sign in to comment.