This commit is contained in:
Tommi Reiman 2019-01-13 21:25:25 +02:00
parent 93bcc5dad8
commit 5079daa8f3
6 changed files with 35 additions and 30 deletions

View file

@ -3,7 +3,7 @@ package reitit;
import clojure.lang.Keyword;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.util.*;
public class SegmentTrie {
@ -30,7 +30,7 @@ public class SegmentTrie {
if (s.contains("+")) {
_s = s.replace("+", "%2B");
}
return URLEncoder.encode(_s, "UTF-8");
return URLDecoder.decode(_s, "UTF-8");
}
} catch (UnsupportedEncodingException ignored) {
}
@ -72,6 +72,7 @@ public class SegmentTrie {
SegmentTrie s = pointer.catchAll.get(k);
if (s == null) {
s = new SegmentTrie();
s.data = data;
pointer.catchAll.put(k, s);
}
break;
@ -103,7 +104,7 @@ public class SegmentTrie {
public Matcher matcher() {
Matcher m;
if (!catchAll.isEmpty()) {
m = new CatchAllMatcher(catchAll.keySet().iterator().next(), catchAll.values().iterator().next().data);
m = new CatchAllMatcher(catchAll.keySet().iterator().next(), data);
} else if (!wilds.isEmpty()) {
List<Matcher> matchers = new ArrayList<>();
if (data != null) {
@ -118,12 +119,12 @@ public class SegmentTrie {
m = new LinearMatcher(matchers);
} else if (!childs.isEmpty()) {
m = staticMatcher();
if (data != null) {
m = new LinearMatcher(Arrays.asList(new DataMatcher(data), m));
}
} else {
return new DataMatcher(data);
}
if (data != null) {
m = new LinearMatcher(Arrays.asList(new DataMatcher(data), m));
}
return m;
}
@ -165,10 +166,12 @@ public class SegmentTrie {
@Override
public Match match(int i, List<String> segments, Match match) {
final Match m = child.match(i + 1, segments, match);
if (m != null) {
m.params.put(parameter, encode(segments.get(i)));
return m;
if (i < segments.size() && !segments.get(i).isEmpty()) {
final Match m = child.match(i + 1, segments, match);
if (m != null) {
m.params.put(parameter, encode(segments.get(i)));
return m;
}
}
return null;
}
@ -294,7 +297,7 @@ public class SegmentTrie {
Map<String, Matcher> m2 = new HashMap<>();
m2.put("user", new WildMatcher(Keyword.intern("id"), new StaticMapMatcher(m1)));
m2.put("company", new WildMatcher(Keyword.intern("cid"), new StaticMatcher("dept", new WildMatcher(Keyword.intern("did"), new DataMatcher(3)))));
m2.put("public", new CatchAllMatcher(Keyword.intern("*"), 4));
m2.put("public", new CatchAllMatcher(Keyword.intern("*"), new DataMatcher(4)));
m2.put("kikka", new LinearMatcher(Arrays.asList(new StaticMatcher("ping", new DataMatcher(5)), new WildMatcher(Keyword.intern("id"), new StaticMatcher("ping", new DataMatcher(6))))));
return new StaticMapMatcher(m2);
}
@ -302,14 +305,14 @@ public class SegmentTrie {
public static void main(String[] args) {
SegmentTrie trie = new SegmentTrie();
//trie.add("/kikka/:id/permissions", 1);
trie.add("/kikka/:id", 2);
trie.add("/kakka/ping", 3);
trie.add("/:abba", 1);
trie.add("/abba/1", 2);
trie.add("/:abba/:dabba/doo", 3);
trie.add("/abba/:dabba/boo", 4);
Matcher m = trie.matcher();
System.err.println(m);
System.out.println(lookup(m, "/kikka/1/permissions"));
System.out.println(lookup(m, "/kikka/1"));
System.err.println(m.getClass());
System.out.println(lookup(m, "/abba"));
/*
SegmentTrie trie = new SegmentTrie();
trie.add("/user/:id/profile/:type", 1);

View file

@ -289,7 +289,9 @@
names)
(match-by-path [_ path]
(if-let [match (segment/lookup pl path)]
(assoc (:data match) :path path)))
(-> (:data match)
(assoc :path-params (:path-params match))
(assoc :path path))))
(match-by-name [_ name]
(if-let [match (impl/fast-get lookup name)]
(match nil)))

View file

@ -2,7 +2,7 @@
(:refer-clojure :exclude [-lookup compile])
(:require [reitit.impl :as impl]
[clojure.string :as str])
#?(:clj (:import (reitit SegmentTrie Trie$Match))))
#?(:clj (:import (reitit SegmentTrie SegmentTrie$Match))))
(defrecord Match [data path-params])
@ -54,9 +54,9 @@
(defn compile [segment]
#?(:cljs segment
:clj (.matcher ^SegmentTrie segment)))
:clj (.matcher ^SegmentTrie (or segment (SegmentTrie.)))))
(defn lookup [segment path]
#?(:cljs (-lookup segment (impl/segments path) {})
:clj (if-let [match ^Trie$Match (SegmentTrie/lookup segment path)]
:clj (if-let [match ^SegmentTrie$Match (SegmentTrie/lookup segment path)]
(->Match (.data match) (clojure.lang.PersistentHashMap/create (.params match))))))

View file

@ -144,7 +144,7 @@
request (enrich-request request path-params match router)]
(or (interceptor/execute executor interceptors request)
(interceptor/execute executor default-queue request)))
(interceptor/execute executor default-queue (enrich-default-request request))))
(interceptor/execute executor default-queue (enrich-default-request request router))))
([request respond raise]
(let [default #(interceptor/execute executor default-queue % respond raise)]
(if-let [match (r/match-by-path router (:uri request))]
@ -160,7 +160,7 @@
(if interceptors
(interceptor/execute executor interceptors request respond' raise)
(default request)))
(default (enrich-default-request request))))
(default (enrich-default-request request router))))
nil))
{::r/router router}))))

View file

@ -285,7 +285,7 @@
handler (-> result method :handler (or default-handler))
request (enrich-request request path-params match router)]
(or (handler request) (default-handler request)))
(default-handler (enrich-default-request request))))
(default-handler (enrich-default-request request router))))
([request respond raise]
(if-let [match (r/match-by-path router (:uri request))]
(let [method (:request-method request)
@ -294,7 +294,7 @@
handler (-> result method :handler (or default-handler))
request (enrich-request request path-params match router)]
((routes handler default-handler) request respond raise))
(default-handler (enrich-default-request request) respond raise))
(default-handler (enrich-default-request request router) respond raise))
nil)))
{::r/router router}))))

View file

@ -7,7 +7,7 @@
[reitit.impl :as impl]
[reitit.ring :as ring]
[reitit.core :as r])
(:import (reitit SegmentTrie Trie$Matcher)
(:import (reitit SegmentTrie SegmentTrie$Matcher)
(calfpath Util)))
;;
@ -120,7 +120,7 @@
(cc/quick-bench
(r/match-by-path router "/user/1234/profile/compact"))))
(let [lookup ^Trie$Matcher (SegmentTrie/sample)]
(let [lookup ^SegmentTrie$Matcher (SegmentTrie/sample)]
(SegmentTrie/lookup lookup "/user/1234/profile/compact")
#_(cc/quick-bench
(SegmentTrie/lookup lookup "/user/1234/profile/compact")))
@ -172,20 +172,20 @@
(comment
(let [matcher ^Trie$Matcher (SegmentTrie/sample)]
(let [matcher ^SegmentTrie$Matcher (SegmentTrie/sample)]
(SegmentTrie/lookup matcher "/user/1234/profile/compact")
(cc/quick-bench
(SegmentTrie/lookup matcher "/user/1234/profile/compact")))
;; 173ns
(let [lookup ^Trie$Matcher (SegmentTrie/tree2)]
(let [lookup ^SegmentTrie$Matcher (SegmentTrie/tree2)]
(SegmentTrie/lookup lookup "/user/1234/profile/compact")
(cc/quick-bench
(SegmentTrie/lookup lookup "/user/1234/profile/compact")))
;; 140ns
(let [lookup ^Trie$Matcher (SegmentTrie/tree1)]
(let [lookup ^SegmentTrie$Matcher (SegmentTrie/tree1)]
(SegmentTrie/lookup lookup "/user/1234/profile/compact")
(cc/quick-bench
(SegmentTrie/lookup lookup "/user/1234/profile/compact")))