Show root node in seq of Trie

Before, if you did a lookup in a trie and then did a seq of the result,
you would get all of the children of the node that you looked up, but
you wouldn't get the value of the node itself.

This was nice when I was only getting children of the root node
because the root node never had a value and I didn't want it.

But I think it makes more since to always include the root node.
If it's not wanted, filter it out at the application level.
main
Eric Ihli 4 years ago
parent 77475e0c13
commit fd191332cd

@ -50,6 +50,7 @@ But there's a couple cool Trie-specific functions.
#+begin_src clojure :results none :session usage-example #+begin_src clojure :results none :session usage-example
(trie/lookup loosely-packed-trie "do") (trie/lookup loosely-packed-trie "do")
;; => {[\g] :dog, [\t] :dot} ;; => {[\g] :dog, [\t] :dot}
(seq (trie/lookup loosely-packed-trie "do"))
#+end_src #+end_src
`children` returns the direct children of a node. `children` returns the direct children of a node.
@ -95,12 +96,12 @@ Here's a similar example to that above, but with values that we can tightly pack
v v
(if (zero? v) nil v))) (if (zero? v) nil v)))
(def loosely-packed-trie (def tight-ready-loosely-packed-trie
(trie/make-trie '(1 2 3) 123 '(1 2 1) 121 '(1 2 2) 122 '(1 3 1) 131)) (trie/make-trie '(1 2 3) 123 '(1 2 1) 121 '(1 2 2) 122 '(1 3 1) 131))
(def tightly-packed-trie (def tightly-packed-trie
(tpt/tightly-packed-trie (tpt/tightly-packed-trie
loosely-packed-trie tight-ready-loosely-packed-trie
encode-fn encode-fn
decode-fn)) decode-fn))

@ -236,7 +236,7 @@
) )
(defn value-encode-fn [v] (defn value-encode-fn [v]
(if (= v ::tpt/root) (if (and (number? v) (zero? v))
(encoding/encode 0) (encoding/encode 0)
(byte-array (byte-array
(concat (encoding/encode (:id v)) (concat (encoding/encode (:id v))
@ -245,7 +245,7 @@
(defn value-decode-fn [byte-buffer] (defn value-decode-fn [byte-buffer]
(let [id (encoding/decode byte-buffer)] (let [id (encoding/decode byte-buffer)]
(if (zero? id) (if (zero? id)
{:id :root} {:id id}
{:id id {:id id
:count (encoding/decode byte-buffer)}))) :count (encoding/decode byte-buffer)})))

@ -38,23 +38,37 @@
(.limit ~byte-buffer original-limit#) (.limit ~byte-buffer original-limit#)
(.position ~byte-buffer original-position#))))) (.position ~byte-buffer original-position#)))))
(defn trie->depth-first-post-order-traversable-zipperable-vector (defn -trie->depth-first-post-order-traversable-zipperable-vector
([path node decode-value-fn] [path node decode-value-fn]
(vec (vec
(map (map
(fn [child] (fn [child]
[(trie->depth-first-post-order-traversable-zipperable-vector [(-trie->depth-first-post-order-traversable-zipperable-vector
(conj path (.key child))
child
decode-value-fn)
(wrap-byte-buffer
(.byte-buffer child)
(.limit (.byte-buffer child) (.limit child))
(.position (.byte-buffer child) (.address child))
(clojure.lang.MapEntry.
(conj path (.key child)) (conj path (.key child))
child (decode-value-fn (.byte-buffer child))))])
decode-value-fn) (trie/children node))))
(wrap-byte-buffer
(.byte-buffer child) (defn trie->depth-first-post-order-traversable-zipperable-vector
(.limit (.byte-buffer child) (.limit child)) [path node decode-value-fn]
(.position (.byte-buffer child) (.address child)) (let [byte-buffer (.byte-buffer node)
(clojure.lang.MapEntry. val (wrap-byte-buffer
(conj path (.key child)) byte-buffer
(decode-value-fn (.byte-buffer child))))]) (.limit byte-buffer (.limit node))
(trie/children node))))) (.position byte-buffer (.address node))
(decode-value-fn byte-buffer))]
[(-trie->depth-first-post-order-traversable-zipperable-vector
path
node
decode-value-fn)
(clojure.lang.MapEntry. path val)]))
(defn rewind-to-key [bb stop] (defn rewind-to-key [bb stop]
(loop [] (loop []

@ -1,15 +1,24 @@
(ns com.owoga.trie (ns com.owoga.trie
(:require [clojure.zip :as zip])) (:require [clojure.zip :as zip]))
(defn trie->depth-first-post-order-traversable-zipperable-vector (defn -trie->depth-first-post-order-traversable-zipperable-vector
([path node] ([path node]
(vec (vec
(map (map
(fn [[k v]] (fn [[k v]]
[(trie->depth-first-post-order-traversable-zipperable-vector (conj path k) v) [(-trie->depth-first-post-order-traversable-zipperable-vector (conj path k) v)
(clojure.lang.MapEntry. (conj path k) (.value v))]) (clojure.lang.MapEntry. (conj path k) (.value v))])
(.children- node))))) (.children- node)))))
(defn trie->depth-first-post-order-traversable-zipperable-vector
[path node]
(if (.value node)
[(-trie->depth-first-post-order-traversable-zipperable-vector
path node)
(clojure.lang.MapEntry. path (.value node))]
(-trie->depth-first-post-order-traversable-zipperable-vector
path node)))
(defn depth-first-post-order-traversable-zipperable-vector->trie (defn depth-first-post-order-traversable-zipperable-vector->trie
[cls [children [key node]]] [cls [children [key node]]]
(sorted-map (sorted-map

@ -18,15 +18,6 @@
nil nil
v))) v)))
(comment
(let [t (->> '([1 3] 13 [1] 1 [1 2] 12)
(apply trie/make-trie)
(#(tpt/tightly-packed-trie % value-encode-fn value-decode-fn)))
bb (.byte-buffer t)]
(trie/lookup t [1 2]))
)
(deftest tightly-packed-trie-tests (deftest tightly-packed-trie-tests
(let [empty-trie (-> (trie/make-trie) (let [empty-trie (-> (trie/make-trie)
(#(tpt/tightly-packed-trie % value-encode-fn value-decode-fn))) (#(tpt/tightly-packed-trie % value-encode-fn value-decode-fn)))
@ -70,7 +61,8 @@
[[1 2] nil] [[1 2] nil]
[[1 3 1] 131] [[1 3 1] 131]
[[1 3] nil] [[1 3] nil]
[[1] nil]) [[1] nil]
[[] nil])
(seq initialized-trie)))))) (seq initialized-trie))))))
(comment (comment

Loading…
Cancel
Save