diff --git a/modules/reitit-core/java-src/reitit/SegmentTrie.java b/modules/reitit-core/java-src/reitit/SegmentTrie.java index 47bf2e91..3cb58981 100644 --- a/modules/reitit-core/java-src/reitit/SegmentTrie.java +++ b/modules/reitit-core/java-src/reitit/SegmentTrie.java @@ -6,7 +6,7 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.*; -public class Trie { +public class SegmentTrie { public static ArrayList split(final String path) { final ArrayList segments = new ArrayList<>(4); @@ -50,35 +50,35 @@ public class Trie { } } - private Map childs = new HashMap<>(); - private Map wilds = new HashMap<>(); - private Map catchAll = new HashMap<>(); + private Map childs = new HashMap<>(); + private Map wilds = new HashMap<>(); + private Map catchAll = new HashMap<>(); private Object data; - public Trie add(String path, Object data) { + public SegmentTrie add(String path, Object data) { List paths = split(path); - Trie pointer = this; + SegmentTrie pointer = this; for (String p : paths) { if (p.startsWith(":")) { Keyword k = Keyword.intern(p.substring(1)); - Trie s = pointer.wilds.get(k); + SegmentTrie s = pointer.wilds.get(k); if (s == null) { - s = new Trie(); + s = new SegmentTrie(); pointer.wilds.put(k, s); } pointer = s; } else if (p.startsWith("*")) { Keyword k = Keyword.intern(p.substring(1)); - Trie s = pointer.catchAll.get(k); + SegmentTrie s = pointer.catchAll.get(k); if (s == null) { - s = new Trie(); + s = new SegmentTrie(); pointer.catchAll.put(k, s); } break; } else { - Trie s = pointer.childs.get(p); + SegmentTrie s = pointer.childs.get(p); if (s == null) { - s = new Trie(); + s = new SegmentTrie(); pointer.childs.put(p, s); } pointer = s; @@ -93,7 +93,7 @@ public class Trie { return new StaticMatcher(childs.keySet().iterator().next(), childs.values().iterator().next().matcher()); } else { Map m = new HashMap<>(); - for (Map.Entry e : childs.entrySet()) { + for (Map.Entry e : childs.entrySet()) { m.put(e.getKey(), e.getValue().matcher()); } return new StaticMapMatcher(m); @@ -112,7 +112,7 @@ public class Trie { if (!childs.isEmpty()) { matchers.add(staticMatcher()); } - for (Map.Entry e : wilds.entrySet()) { + for (Map.Entry e : wilds.entrySet()) { matchers.add(new WildMatcher(e.getKey(), e.getValue().matcher())); } m = new LinearMatcher(matchers); @@ -301,7 +301,7 @@ public class Trie { public static void main(String[] args) { - Trie trie = new Trie(); + SegmentTrie trie = new SegmentTrie(); //trie.add("/kikka/:id/permissions", 1); trie.add("/kikka/:id", 2); trie.add("/kakka/ping", 3); @@ -311,7 +311,7 @@ public class Trie { System.out.println(lookup(m, "/kikka/1")); /* - Trie trie = new Trie(); + SegmentTrie trie = new SegmentTrie(); trie.add("/user/:id/profile/:type", 1); trie.add("/user/:id/permissions", 2); trie.add("/company/:cid/dept/:did", 3); diff --git a/modules/reitit-core/src/reitit/impl.cljc b/modules/reitit-core/src/reitit/impl.cljc index a4317999..e996def8 100644 --- a/modules/reitit-core/src/reitit/impl.cljc +++ b/modules/reitit-core/src/reitit/impl.cljc @@ -6,7 +6,7 @@ (:import (java.util.regex Pattern) (java.util HashMap Map) (java.net URLEncoder URLDecoder) - (reitit Trie)))) + (reitit SegmentTrie)))) (defn maybe-map-values "Applies a function to every value of a map, updates the value if not nil. @@ -21,7 +21,7 @@ coll)) (defn segments [path] - #?(:clj (Trie/split ^String path) + #?(:clj (SegmentTrie/split ^String path) :cljs (.split path #"/" 666))) ;; diff --git a/modules/reitit-core/src/reitit/segment.cljc b/modules/reitit-core/src/reitit/segment.cljc index 18a5638d..b0ff46fa 100644 --- a/modules/reitit-core/src/reitit/segment.cljc +++ b/modules/reitit-core/src/reitit/segment.cljc @@ -2,7 +2,7 @@ (:refer-clojure :exclude [-lookup compile]) (:require [reitit.impl :as impl] [clojure.string :as str]) - #?(:clj (:import (reitit Trie Trie$Match)))) + #?(:clj (:import (reitit SegmentTrie Trie$Match)))) (defrecord Match [data path-params]) @@ -50,13 +50,13 @@ (defn insert [root path data] #?(:cljs (-insert (or root (segment)) (impl/segments path) (map->Match {:data data})) - :clj (.add (or ^Trie root ^Trie (Trie.)) ^String path data))) + :clj (.add (or ^SegmentTrie root ^SegmentTrie (SegmentTrie.)) ^String path data))) (defn compile [segment] #?(:cljs segment - :clj (.matcher ^Trie segment))) + :clj (.matcher ^SegmentTrie segment))) (defn lookup [segment path] #?(:cljs (-lookup segment (impl/segments path) {}) - :clj (if-let [match ^Trie$Match (Trie/lookup segment path)] + :clj (if-let [match ^Trie$Match (SegmentTrie/lookup segment path)] (->Match (.data match) (clojure.lang.PersistentHashMap/create (.params match)))))) diff --git a/perf-test/clj/reitit/calf_perf_test.clj b/perf-test/clj/reitit/calf_perf_test.clj index 5137b088..b97c763f 100644 --- a/perf-test/clj/reitit/calf_perf_test.clj +++ b/perf-test/clj/reitit/calf_perf_test.clj @@ -7,7 +7,8 @@ [reitit.impl :as impl] [reitit.ring :as ring] [reitit.core :as r]) - (:import (reitit Trie Trie$Matcher))) + (:import (reitit SegmentTrie Trie$Matcher) + (calfpath Util))) ;; ;; start repl with `lein perf repl` @@ -109,20 +110,20 @@ (impl/segments "/user/1234/profile/compact"))) (comment - (Trie/split "/user/1234/profile/compact") + (SegmentTrie/split "/user/1234/profile/compact") ;; 91ns (cc/quick-bench - (Trie/split "/user/1234/profile/compact"))) + (SegmentTrie/split "/user/1234/profile/compact"))) (comment (let [router (r/router ["/user/:id/profile/:type"])] (cc/quick-bench (r/match-by-path router "/user/1234/profile/compact")))) -(let [lookup ^Trie$Matcher (Trie/sample)] - (Trie/lookup lookup "/user/1234/profile/compact") +(let [lookup ^Trie$Matcher (SegmentTrie/sample)] + (SegmentTrie/lookup lookup "/user/1234/profile/compact") #_(cc/quick-bench - (Trie/lookup lookup "/user/1234/profile/compact"))) + (SegmentTrie/lookup lookup "/user/1234/profile/compact"))) (let [router (r/router [["/user/:id" ::1] ["/user/:id/permissions" ::2] @@ -144,50 +145,50 @@ (read-string (str (.matcher - (doto (Trie.) + (doto (SegmentTrie.) (.add "/user" 1) #_(.add "/user/id/permissions" 2) (.add "/user/id/permissions2" 3))))) -(Trie/lookup +(SegmentTrie/lookup (.matcher - (doto (Trie.) + (doto (SegmentTrie.) (.add "/user/1" 1) (.add "/user/1/permissions" 2))) "/user/1") (.matcher - (doto (Trie.) + (doto (SegmentTrie.) (.add "/user/1" 1) (.add "/user/1/permissions" 2))) ;; 137ns (let [m (.matcher - (doto (Trie.) + (doto (SegmentTrie.) (.add "/user/:id/profile/:type" 1)))] #_(cc/quick-bench - (Trie/lookup m "/user/1234/profile/compact")) - (Trie/lookup m "/user/1234/profile/compact")) + (SegmentTrie/lookup m "/user/1234/profile/compact")) + (SegmentTrie/lookup m "/user/1234/profile/compact")) (comment - (let [matcher ^Trie$Matcher (Trie/sample)] - (Trie/lookup matcher "/user/1234/profile/compact") + (let [matcher ^Trie$Matcher (SegmentTrie/sample)] + (SegmentTrie/lookup matcher "/user/1234/profile/compact") (cc/quick-bench - (Trie/lookup matcher "/user/1234/profile/compact"))) + (SegmentTrie/lookup matcher "/user/1234/profile/compact"))) ;; 173ns - (let [lookup ^Trie$Matcher (Trie/tree2)] - (Trie/lookup lookup "/user/1234/profile/compact") + (let [lookup ^Trie$Matcher (SegmentTrie/tree2)] + (SegmentTrie/lookup lookup "/user/1234/profile/compact") (cc/quick-bench - (Trie/lookup lookup "/user/1234/profile/compact"))) + (SegmentTrie/lookup lookup "/user/1234/profile/compact"))) ;; 140ns - (let [lookup ^Trie$Matcher (Trie/tree1)] - (Trie/lookup lookup "/user/1234/profile/compact") + (let [lookup ^Trie$Matcher (SegmentTrie/tree1)] + (SegmentTrie/lookup lookup "/user/1234/profile/compact") (cc/quick-bench - (Trie/lookup lookup "/user/1234/profile/compact"))) + (SegmentTrie/lookup lookup "/user/1234/profile/compact"))) ;; 849ns (clojure, original) ;; 599ns (java, initial) @@ -225,15 +226,13 @@ (dotimes [_ 1000] (handler-reitit request))))) -(import '[reitit Util]) - (comment (Util/matchURI "/user/1234/profile/compact/" ["/user/" :id "/profile/" :type "/"]) (cc/quick-bench (Util/matchURI "/user/1234/profile/compact/" ["/user/" :id "/profile/" :type "/"])) (cc/quick-bench - (Trie/split "/user/1234/profile/compact/")) + (SegmentTrie/split "/user/1234/profile/compact/")) (cc/quick-bench (.split "/user/1234/profile/compact/" "/" 666))) @@ -265,9 +264,9 @@ (segment/lookup segment "/user/1/permissions/")))) #_(cc/quick-bench - (Trie/split "/user/1/profile/compat")) + (SegmentTrie/split "/user/1/profile/compat")) -#_(Trie/split "/user/1/profile/compat") +#_(SegmentTrie/split "/user/1/profile/compat") #_(cc/quick-bench (Segment2/hashLookup h "abba")) diff --git a/perf-test/clj/reitit/impl_perf_test.clj b/perf-test/clj/reitit/impl_perf_test.clj index 89fd604d..faae130a 100644 --- a/perf-test/clj/reitit/impl_perf_test.clj +++ b/perf-test/clj/reitit/impl_perf_test.clj @@ -190,7 +190,7 @@ (suite "split") ;; 114ns (String/split) - ;; 82ns (Trie/split) + ;; 82ns (SegmentTrie/split) (test "Splitting a String") (test! impl/segments "/olipa/kerran/:avaruus")) diff --git a/perf-test/clj/reitit/prefix_tree_perf_test.clj b/perf-test/clj/reitit/prefix_tree_perf_test.clj index c507e9dc..67f8f695 100644 --- a/perf-test/clj/reitit/prefix_tree_perf_test.clj +++ b/perf-test/clj/reitit/prefix_tree_perf_test.clj @@ -3,7 +3,7 @@ [io.pedestal.http.route.prefix-tree :as p] [reitit.segment :as segment] [criterium.core :as cc]) - (:import (reitit Trie))) + (:import (reitit SegmentTrie))) ;; ;; testing @@ -72,7 +72,7 @@ (def matcher (.matcher - ^Trie + ^SegmentTrie (reduce (fn [acc [p d]] (segment/insert acc p d))