|
|
|
(ns tightly-packed-trie-test
|
|
|
|
(:require [clojure.test :refer [deftest is testing] :as t]
|
|
|
|
[com.owoga.trie :as trie]
|
|
|
|
[com.owoga.tightly-packed-trie :as tpt]
|
|
|
|
[com.owoga.tightly-packed-trie.encoding :as encode]
|
|
|
|
[com.owoga.tightly-packed-trie.encoding :as encoding]
|
|
|
|
[com.owoga.tightly-packed-trie.bit-manip :as bm]))
|
|
|
|
|
|
|
|
#_(set! *warn-on-reflection* true)
|
|
|
|
|
|
|
|
(defn value-encode-fn
|
|
|
|
(#^bytes [^Integer v]
|
|
|
|
(if (nil? v)
|
|
|
|
(encode/encode 0)
|
|
|
|
(encode/encode v))))
|
|
|
|
|
|
|
|
(defn value-decode-fn [^java.nio.ByteBuffer byte-buffer]
|
|
|
|
(let [^Integer v (encode/decode byte-buffer)]
|
|
|
|
(if (zero? v)
|
|
|
|
nil
|
|
|
|
v)))
|
|
|
|
|
|
|
|
(deftest tightly-packed-trie-tests
|
|
|
|
(let [empty-trie (-> (trie/make-trie)
|
|
|
|
(#(tpt/tightly-packed-trie % value-encode-fn value-decode-fn)))
|
|
|
|
initialized-trie (->> '([1 3] 13 [1] 1 [1 2] 12)
|
|
|
|
(apply trie/make-trie)
|
|
|
|
(#(tpt/tightly-packed-trie % value-encode-fn value-decode-fn)))]
|
|
|
|
(testing "ILookup"
|
|
|
|
(is (= 13 (get initialized-trie [1 3])))
|
|
|
|
(is (= :not-found (get initialized-trie [4] :not-found)))
|
|
|
|
(is (= nil (get initialized-trie [4]))))
|
|
|
|
(testing "ITrie"
|
|
|
|
(testing "lookup"
|
|
|
|
(is (= nil (trie/lookup empty-trie [1])))
|
|
|
|
|
|
|
|
;; A `get` of a node returns the value at the node.
|
|
|
|
(is (= 1 (get (trie/lookup initialized-trie [1]) [])))
|
|
|
|
(is (= 12 (get (trie/lookup initialized-trie [1]) [2])))
|
|
|
|
|
|
|
|
;; A `seq` of a node is a depth-first post-order traversal of its descendants.
|
|
|
|
(is (= '([[2] 12] [[3] 13] [[] 1])
|
|
|
|
(seq (trie/lookup initialized-trie [1])))))
|
|
|
|
|
|
|
|
;; The children of a node are only the immediate children and
|
|
|
|
;; the root node's value is excluded.
|
|
|
|
(testing "children"
|
|
|
|
(is (= '(12 13)
|
|
|
|
(map #(get % [])
|
|
|
|
(trie/children (trie/lookup initialized-trie [1])))))))))
|
|
|
|
|
|
|
|
(deftest extended-tightly-packed-trie-tests
|
|
|
|
(let [initialized-trie (->> (trie/make-trie '(1 2 3) 123 '(1 2 1) 121 '(1 2 2) 122 '(1 3 1) 131)
|
|
|
|
(#(tpt/tightly-packed-trie % value-encode-fn value-decode-fn)))]
|
|
|
|
(testing "ILookup"
|
|
|
|
(is (= 123 (get initialized-trie [1 2 3])))
|
|
|
|
(is (= :not-found (get initialized-trie [4] :not-found)))
|
|
|
|
(is (= nil (get initialized-trie [4]))))
|
|
|
|
(testing "ITrie"
|
|
|
|
(testing "lookup"
|
|
|
|
(is (= nil (trie/lookup initialized-trie [4])))
|
|
|
|
(is (= nil (get (trie/lookup initialized-trie [1]) [])))
|
|
|
|
(is (= nil (get (trie/lookup initialized-trie [1]) [2]))))
|
|
|
|
(testing "children"
|
|
|
|
(is (= '(121 122 123)
|
|
|
|
(map #(get % [])
|
|
|
|
(trie/children (trie/lookup initialized-trie [1 2])))))))
|
|
|
|
(testing "Seq"
|
|
|
|
(is (= '([[1 2 1] 121]
|
|
|
|
[[1 2 2] 122]
|
|
|
|
[[1 2 3] 123]
|
|
|
|
[[1 2] nil]
|
|
|
|
[[1 3 1] 131]
|
|
|
|
[[1 3] nil]
|
|
|
|
[[1] nil])
|
|
|
|
(seq initialized-trie))))
|
|
|
|
(testing "Seq on lookup"
|
|
|
|
(is (= '([[1] 121]
|
|
|
|
[[2] 122]
|
|
|
|
[[3] 123]
|
|
|
|
[[] nil])
|
|
|
|
(seq (trie/lookup initialized-trie [1 2])))))))
|
|
|
|
|
|
|
|
(deftest children-at-depth-tests
|
|
|
|
(let [initialized-trie (->> (trie/make-trie '(1) 1 '(1 2 3) 123 '(1 2 1) 121 '(1 2 2) 122 '(1 3 1) 131
|
|
|
|
'(1 2 3 4) 1234
|
|
|
|
'(1 2 3 4 5 6) 123456)
|
|
|
|
(#(tpt/tightly-packed-trie % value-encode-fn value-decode-fn)))]
|
|
|
|
(testing "children at depth"
|
|
|
|
(is (= '([(1) 1])
|
|
|
|
(trie/children-at-depth initialized-trie 0)))
|
|
|
|
(is (= '([(1 2 3 4 5 6) 123456]
|
|
|
|
[(1 2 3 4) 1234])
|
|
|
|
(trie/children-at-depth initialized-trie 4 6))))))
|
|
|
|
|
|
|
|
(comment
|
|
|
|
(let [trie (trie/make-trie '(1 2 3) 123 '(1 2 1) 121 '(1 2 2) 122 '(1 3 1) 131)
|
|
|
|
tpt (tpt/tightly-packed-trie trie value-encode-fn value-decode-fn)
|
|
|
|
byte-buffer (.byte-buffer tpt)]
|
|
|
|
|
|
|
|
(tpt/wrap-byte-buffer
|
|
|
|
byte-buffer
|
|
|
|
(.limit byte-buffer (.limit tpt))
|
|
|
|
(.position byte-buffer (.address tpt))
|
|
|
|
[(value-decode-fn byte-buffer)
|
|
|
|
(value-decode-fn byte-buffer)
|
|
|
|
(encode/decode-number-from-tightly-packed-trie-index byte-buffer)
|
|
|
|
(encode/decode-number-from-tightly-packed-trie-index byte-buffer)]))
|
|
|
|
|
|
|
|
(let [trie (trie/make-trie '(1) 1 '(1 2) 12 '(1 3) 13 '(2 3) 23 '(5) 5 '(6 7 8) 678)
|
|
|
|
tpt (tpt/tightly-packed-trie trie value-encode-fn value-decode-fn)]
|
|
|
|
(get tpt []))
|
|
|
|
|
|
|
|
(let [trie (trie/make-trie '(1) 1 '(1 2) 12 '(1 3) 13 '(2 3) 23 '(5) 5 '(6 7 8) 678)
|
|
|
|
tpt (tpt/tightly-packed-trie trie value-encode-fn value-decode-fn)]
|
|
|
|
(tpt/trie->children-at-depth (list (list tpt)) '() 3 5))
|
|
|
|
|
|
|
|
)
|
|
|
|
|