Skip to content

Commit 9ad7c85

Browse files
committed
chi router: get back single method matching optimization
1 parent c256b90 commit 9ad7c85

File tree

1 file changed

+73
-24
lines changed
  • jooby/src/main/java/io/jooby/internal

1 file changed

+73
-24
lines changed

jooby/src/main/java/io/jooby/internal/Chi.java

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import io.jooby.Router;
1111

1212
import java.util.Arrays;
13-
import java.util.Collections;
1413
import java.util.Map;
1514
import java.util.Objects;
1615
import java.util.concurrent.ConcurrentHashMap;
@@ -31,24 +30,71 @@ class Chi implements RouteTree {
3130

3231
private static final int NODE_SIZE = ntCatchAll + 1;
3332

34-
static final StaticRoute NO_MATCH = new StaticRoute(Collections.emptyMap());
35-
3633
static final char ZERO_CHAR = (char) 0;
3734
private MessageEncoder encoder;
3835

39-
static class StaticRoute {
40-
private final Map<String, StaticRouterMatch> methods;
36+
private interface MethodMatcher {
37+
StaticRouterMatch get(String method);
38+
39+
void put(String method, StaticRouterMatch route);
40+
41+
boolean matches(String method);
42+
}
43+
44+
private static class SingleMethodMatcher implements MethodMatcher {
45+
private String method;
46+
private StaticRouterMatch route;
47+
48+
@Override public void put(String method, StaticRouterMatch route) {
49+
this.method = method;
50+
this.route = route;
51+
}
4152

42-
public StaticRoute(Map<String, StaticRouterMatch> methods) {
43-
this.methods = methods;
53+
@Override public StaticRouterMatch get(String method) {
54+
return this.method.equals(method) ? route : null;
4455
}
4556

46-
public StaticRoute() {
47-
this(new ConcurrentHashMap<>(Router.METHODS.size()));
57+
@Override public boolean matches(String method) {
58+
return this.method.equals(method);
4859
}
4960

61+
public void clear() {
62+
this.method = null;
63+
this.route = null;
64+
}
65+
}
66+
67+
private static class MultipleMethodMatcher implements MethodMatcher {
68+
private Map<String, StaticRouterMatch> methods = new ConcurrentHashMap<>();
69+
70+
public MultipleMethodMatcher(SingleMethodMatcher matcher) {
71+
methods.put(matcher.method, matcher.route);
72+
matcher.clear();
73+
}
74+
75+
@Override public StaticRouterMatch get(String method) {
76+
return methods.get(method);
77+
}
78+
79+
@Override public void put(String method, StaticRouterMatch route) {
80+
methods.put(method, route);
81+
}
82+
83+
@Override public boolean matches(String method) {
84+
return this.methods.containsKey(method);
85+
}
86+
}
87+
88+
static class StaticRoute {
89+
private MethodMatcher matcher;
90+
5091
public void put(String method, Route route) {
51-
methods.put(method, new StaticRouterMatch(route));
92+
if (matcher == null) {
93+
matcher = new SingleMethodMatcher();
94+
} else if (matcher instanceof SingleMethodMatcher) {
95+
matcher = new MultipleMethodMatcher((SingleMethodMatcher) matcher);
96+
}
97+
matcher.put(method, new StaticRouterMatch(route));
5298
}
5399
}
54100

@@ -707,24 +753,27 @@ public void destroy() {
707753
}
708754

709755
public boolean exists(String method, String path) {
710-
if (!staticPaths.getOrDefault(path, NO_MATCH).methods.containsKey(method)) {
711-
return root.findRoute(new RouterMatch(), method, path) != null;
712-
}
713-
return true;
756+
return find(method, path) != null;
714757
}
715758

716759
@Override public Router.Match find(String method, String path) {
717-
StaticRouterMatch match = staticPaths.getOrDefault(path, NO_MATCH).methods.get(method);
718-
if (match == null) {
719-
// use radix tree
720-
RouterMatch result = new RouterMatch();
721-
Route route = root.findRoute(result, method, path);
722-
if (route == null) {
723-
return result.missing(method, path, encoder);
724-
}
725-
return result.found(route);
760+
StaticRoute staticRoute = staticPaths.get(path);
761+
if (staticRoute == null) {
762+
return findInternal(method, path);
763+
} else {
764+
StaticRouterMatch match = staticRoute.matcher.get(method);
765+
return match == null ? findInternal(method, path) : match;
766+
}
767+
}
768+
769+
private Router.Match findInternal(String method, String path) {
770+
// use radix tree
771+
RouterMatch result = new RouterMatch();
772+
Route route = root.findRoute(result, method, path);
773+
if (route == null) {
774+
return result.missing(method, path, encoder);
726775
}
727-
return match;
776+
return result.found(route);
728777
}
729778

730779
public void setEncoder(MessageEncoder encoder) {

0 commit comments

Comments
 (0)