Skip to content

Instantly share code, notes, and snippets.

@refset
Last active January 7, 2022 22:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save refset/f737151c2956093bbe01d7b81a743328 to your computer and use it in GitHub Desktop.
Save refset/f737151c2956093bbe01d7b81a743328 to your computer and use it in GitHub Desktop.
generic-range-value-inversion.clj
(require '[xtdb.memory :as xt-mem])
(require '[xtdb.codec :as xt-codec])
(defn v->buffer [v]
(when (some? v)
(xt-mem/as-buffer v)))
(defn v->ba [v]
(xt-mem/->on-heap (xt-codec/->value-buffer v)))
(defn ba->v [ba]
(xt-codec/decode-value-buffer (v->buffer ba)))
(defn bit-complement [ba]
(byte-array (map bit-not ba)))
(defn ldt [^long i]
(LocalDateTime/of 1 1 i 1 1 1 1))
(def node (xt/start-node {}))
(xt/submit-tx node
(mapv #(vector ::xt/put (assoc %1
:d (v->ba (:d %1))
:d2 (-> (:d %1)
v->ba
bit-complement)))
[{:xt/id :a :i -7 :j 30 :d (ldt 17)}
{:xt/id :b :i 14 :j 25 :d (ldt 19)}
{:xt/id :c :i 14 :j 14 :d (ldt 19)}
{:xt/id :d :i 25 :j 14 :d (ldt 21)}
{:xt/id :e :i 30 :j -7 :d (ldt 22)}]))
(defn take-lt [db d n]
(with-open [res (xt/open-q db
{:find '[e d2]
:where ['[e :d2 d2]
[(list '< (v->ba d) 'd2 )]]})]
(do (take n (map (fn mapper [[e d2]] (vector e (-> d2 bit-complement ba->v))) (iterator-seq res))))))
(xt/q (xt/db node)
{:find '[e d2]
:in '[d]
:order-by '[[d2 :desc]] ; d2 relation gets reversed after take-lt returns (due to byte ordering) so we need to re-sort
:limit 2
:where '[[(dev/take-lt $ d 2) [[e d2]]]]}
(ldt 23))
;;=> [[:e #object[java.time.LocalDateTime 0x525229aa "0001-01-22T01:01:01.000000001"]] [:d #object[java.time.LocalDateTime 0x2b82fda0 "0001-01-21T01:01:01.000000001"]]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment