Single wild optimization

This commit is contained in:
Tommi Reiman 2019-01-13 22:02:53 +02:00
parent b847af4ae7
commit 16499cceb1
2 changed files with 18 additions and 15 deletions

View file

@ -106,17 +106,21 @@ public class SegmentTrie {
if (!catchAll.isEmpty()) {
m = new CatchAllMatcher(catchAll.keySet().iterator().next(), data);
} else if (!wilds.isEmpty()) {
List<Matcher> matchers = new ArrayList<>();
if (data != null) {
matchers.add(new DataMatcher(data));
if(wilds.size() == 1 && data == null && childs.isEmpty()) {
m = new WildMatcher(wilds.keySet().iterator().next(), wilds.values().iterator().next().matcher());
} else {
List<Matcher> matchers = new ArrayList<>();
if (data != null) {
matchers.add(new DataMatcher(data));
}
if (!childs.isEmpty()) {
matchers.add(staticMatcher());
}
for (Map.Entry<Keyword, SegmentTrie> e : wilds.entrySet()) {
matchers.add(new WildMatcher(e.getKey(), e.getValue().matcher()));
}
m = new LinearMatcher(matchers);
}
if (!childs.isEmpty()) {
matchers.add(staticMatcher());
}
for (Map.Entry<Keyword, SegmentTrie> e : wilds.entrySet()) {
matchers.add(new WildMatcher(e.getKey(), e.getValue().matcher()));
}
m = new LinearMatcher(matchers);
} else if (!childs.isEmpty()) {
m = staticMatcher();
if (data != null) {
@ -305,14 +309,11 @@ public class SegmentTrie {
public static void main(String[] args) {
SegmentTrie trie = new SegmentTrie();
trie.add("/:abba", 1);
trie.add("/abba/1", 2);
trie.add("/:abba/:dabba/doo", 3);
trie.add("/abba/:dabba/boo", 4);
trie.add("/repos/:owner/:repo/stargazers", 1);
Matcher m = trie.matcher();
System.err.println(m);
System.err.println(m.getClass());
System.out.println(lookup(m, "/abba"));
System.out.println(lookup(m, "/repos/metosin/reitit/stargazers"));
/*
SegmentTrie trie = new SegmentTrie();
trie.add("/user/:id/profile/:type", 1);

View file

@ -327,6 +327,7 @@
;; 830ns (faster decode params)
;; 560µs (java-segment-router)
;; 490ns (java-segment-router, no injects)
;; 440ns (java-segment-router, no injects, single-wild-optimization)
(let [req (map->Req {:request-method :get, :uri "/repos/julienschmidt/httprouter/stargazers"})]
(title "param")
(assert (= {:status 200, :body "/repos/:owner/:repo/stargazers"} (app req)))
@ -337,6 +338,7 @@
;; 160µs (faster decode params)
;; 120µs (java-segment-router)
;; 100µs (java-segment-router, no injects)
;; 90µs (java-segment-router, no injects, single-wild-optimization)
(let [requests (mapv route->req routes)]
(title "all")
(cc/quick-bench