diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 5090b60b..ca9720d6 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -119,7 +119,7 @@ compiled-routes) lookup (impl/fast-map nl) matcher (trie/linear-matcher compiler pl) - match-by-path (trie/matcher matcher compiler) + match-by-path (trie/path-matcher matcher compiler) routes (impl/uncompile-routes compiled-routes)] ^{:type ::router} (reify @@ -213,7 +213,7 @@ [nil {}] compiled-routes) matcher (trie/compile pl compiler) - match-by-path (trie/matcher matcher compiler) + match-by-path (trie/path-matcher matcher compiler) lookup (impl/fast-map nl) routes (impl/uncompile-routes compiled-routes)] ^{:type ::router} diff --git a/modules/reitit-core/src/reitit/trie.cljc b/modules/reitit-core/src/reitit/trie.cljc index 4cc7ec71..242ff299 100644 --- a/modules/reitit-core/src/reitit/trie.cljc +++ b/modules/reitit-core/src/reitit/trie.cljc @@ -25,15 +25,15 @@ (wild-matcher [this key end matcher]) (catch-all-matcher [this key params data]) (linear-matcher [this matchers]) - (prettify [this matcher]) - (path-matcher [this matcher])) + (-pretty [this matcher]) + (-path-matcher [this matcher])) -(defn assoc-param [match k v] +(defn- assoc-param [match k v] (let [params (:params match)] (assoc match :params (assoc params k v)))) ;; https://stackoverflow.com/questions/8033655/find-longest-common-prefix -(defn common-prefix [s1 s2] +(defn- common-prefix [s1 s2] (let [max (min (count s1) (count s2))] (loop [i 0] (cond @@ -177,7 +177,7 @@ (update :children dissoc "")) node'))) -(defn decode [path start end percent?] +(defn- decode [path start end percent?] (let [param (subs path start end)] (if percent? #?(:cljs (js/decodeURIComponent param) @@ -254,9 +254,9 @@ (view [_] (mapv view matchers)) (depth [_] (inc (apply max 0 (map depth matchers)))) (length [_])))) - (prettify [_ matcher] + (-pretty [_ matcher] (view matcher)) - (path-matcher [_ matcher] + (-path-matcher [_ matcher] (fn [path] (if-let [match (match matcher 0 (count path) path)] (->Match (:params match) (:data match))))))) @@ -275,9 +275,9 @@ (Trie/catchAllMatcher key params data)) (linear-matcher [_ matchers] (Trie/linearMatcher matchers)) - (prettify [_ matcher] + (-pretty [_ matcher] (-> matcher str read-string eval)) - (path-matcher [_ matcher] + (-path-matcher [_ matcher] (fn [path] (if-let [match ^Trie$Match (Trie/lookup ^Trie$Matcher matcher ^String path)] (->Match (.params match) (.data match)))))))) @@ -287,6 +287,7 @@ ;; (defn insert + "Returns a trie with routes added to it." ([routes] (insert nil routes)) ([node routes] @@ -299,11 +300,14 @@ params (zipmap (->> parts (remove string?) (map :value)) (repeat nil))] (-insert (or node (-node {})) (split-path path) params data)))) -(defn compiler [] +(defn compiler + "Returns a default [[TrieCompiler]]." + [] #?(:cljs (clojure-trie-compiler) :clj (java-trie-compiler))) (defn compile + "Returns a compiled trie, to be used with [[pretty]] or [[path-matcher]]." ([options] (compile options (compiler))) ([{:keys [data params children wilds catch-all] :or {params {}}} compiler] @@ -325,16 +329,18 @@ :else (data-matcher compiler {} nil))))) (defn pretty - ([trie] - (pretty trie (compiler))) - ([trie compiler] - (prettify compiler trie))) + "Returns a simplified EDN structure of a compiled trie for printing purposes." + ([compiled-trie] + (pretty compiled-trie (compiler))) + ([compiled-trie compiler] + (-pretty compiler compiled-trie))) -(defn matcher - ([trie] - (matcher trie (compiler))) - ([trie compiler] - (path-matcher compiler trie))) +(defn path-matcher + "Returns a function of `path -> Match` from a compiled trie." + ([compiled-trie] + (path-matcher compiled-trie (compiler))) + ([compiled-trie compiler] + (-path-matcher compiler compiled-trie))) ;; ;; spike diff --git a/perf-test/clj/reitit/prefix_tree_perf_test.clj b/perf-test/clj/reitit/prefix_tree_perf_test.clj index 628f2ed8..b35a102a 100644 --- a/perf-test/clj/reitit/prefix_tree_perf_test.clj +++ b/perf-test/clj/reitit/prefix_tree_perf_test.clj @@ -70,7 +70,7 @@ nil routes)) (def trie-matcher - (trie/matcher + (trie/path-matcher (trie/compile (reduce (fn [acc [p d]] @@ -80,8 +80,10 @@ (defn bench! [] ;; 2.3µs - #_(cc/quick-bench - (p/lookup pedestal-tree "/v1/orgs/1/topics")) + ;; 2.1µs (28.2.2019) + (cc/with-progress-reporting + (cc/bench + (p/lookup pedestal-tree "/v1/orgs/1/topics"))) ;; 3.1µs ;; 2.5µs (string equals) @@ -99,7 +101,7 @@ ;; 0.8µs (return route-data) ;; 0.8µs (fix payloads) #_(cc/quick-bench - (trie/matcher reitit-tree "/v1/orgs/1/topics" {})) + (trie/path-matcher reitit-tree "/v1/orgs/1/topics" {})) ;; 0.9µs (initial) ;; 0.5µs (protocols) @@ -111,11 +113,13 @@ #_(cc/quick-bench (segment/lookup segment-matcher "/v1/orgs/1/topics")) - ;; 0.32µs (initial) - ;; 0.30µs (iterate arrays) - ;; 0.28µs (list-params) - (cc/quick-bench - (trie-matcher "/v1/orgs/1/topics"))) + ;; 0.320µs (initial) + ;; 0.300µs (iterate arrays) + ;; 0.280µs (list-params) + ;; 0.096µs (trie) + (cc/with-progress-reporting + (cc/bench + (trie-matcher "/v1/orgs/1/topics")))) (comment (bench!)) diff --git a/test/cljc/reitit/trie_test.cljc b/test/cljc/reitit/trie_test.cljc index a2575599..90286d77 100644 --- a/test/cljc/reitit/trie_test.cljc +++ b/test/cljc/reitit/trie_test.cljc @@ -17,21 +17,21 @@ (is (= (trie/->Match {} {:a 1}) ((-> (trie/insert nil "/foo" {:a 1}) (trie/compile) - (trie/matcher)) "/foo"))) + (trie/path-matcher)) "/foo"))) (is (= (trie/->Match {} {:a 1}) ((-> (trie/insert nil "/foo" {:a 1}) (trie/insert "/foo/*bar" {:b 1}) (trie/compile) - (trie/matcher)) "/foo"))) + (trie/path-matcher)) "/foo"))) (is (= (trie/->Match {:bar "bar"} {:b 1}) ((-> (trie/insert nil "/foo" {:a 1}) (trie/insert "/foo/*bar" {:b 1}) (trie/compile) - (trie/matcher)) "/foo/bar"))) + (trie/path-matcher)) "/foo/bar"))) (is (= (trie/->Match {} {:a 1}) ((-> (trie/insert nil "" {:a 1}) (trie/compile) - (trie/matcher)) "")))) + (trie/path-matcher)) ""))))