Skip to content

Commit fd913cf

Browse files
committed
router: remove predicate matching from internal router
1 parent 59fb97f commit fd913cf

File tree

5 files changed

+45
-74
lines changed

5 files changed

+45
-74
lines changed

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

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -804,9 +804,8 @@ public void insert(Route route) {
804804
root.destroy();
805805
}
806806

807-
public RouterMatch find(Context context, MessageEncoder encoder,
808-
List<RadixTree> more) {
809-
return find(context, context.pathString(), encoder, more);
807+
public RouterMatch find(Context context, MessageEncoder encoder) {
808+
return find(context, context.pathString(), encoder);
810809
}
811810

812811
public boolean find(String method, String path) {
@@ -816,27 +815,14 @@ public boolean find(String method, String path) {
816815
return true;
817816
}
818817

819-
public RouterMatch find(Context context, String path, MessageEncoder encoder,
820-
List<RadixTree> more) {
818+
public RouterMatch find(Context context, String path, MessageEncoder encoder) {
821819
String method = context.getMethod();
822820
Route route = staticPaths.getOrDefault(path, NO_MATCH).methods.get(method);
823821
if (route == null) {
824822
// use radix tree
825823
RouterMatch result = new RouterMatch();
826824
route = root.findRoute(result, method, new ZeroCopyString(path));
827-
if (route == null) {
828-
if (more != null) {
829-
// expand search
830-
for (RadixTree tree : more) {
831-
RouterMatch match = tree.find(context, path, encoder, null);
832-
if (match.matches) {
833-
return match;
834-
}
835-
}
836-
}
837-
return result.missing(method, path, encoder);
838-
}
839-
return result.found(route);
825+
return route == null ? result.missing(method, path, encoder) : result.found(route);
840826
}
841827
return new RouterMatch(route);
842828
}

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

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,12 @@
1010
import io.jooby.Route;
1111
import io.jooby.Router;
1212

13-
import java.util.List;
14-
import java.util.function.Predicate;
15-
1613
interface RadixTree {
1714
void insert(String method, String pattern, Route route);
1815

1916
boolean find(String method, String path);
2017

21-
RouterMatch find(Context context, String path, MessageEncoder encoder, List<RadixTree> more);
22-
23-
default RadixTree with(Predicate<Context> predicate) {
24-
return new RadixTree() {
25-
@Override public void insert(String method, String pattern, Route route) {
26-
RadixTree.this.insert(method, pattern, route);
27-
}
28-
29-
@Override public boolean find(String method, String path) {
30-
return RadixTree.this.find(method, path);
31-
}
32-
33-
@Override
34-
public RouterMatch find(Context context, String path, MessageEncoder encoder,
35-
List<RadixTree> more) {
36-
if (!predicate.test(context)) {
37-
return new RouterMatch()
38-
.missing(context.getMethod(), context.pathString(), encoder);
39-
}
40-
return RadixTree.this.find(context, path, encoder, more);
41-
}
42-
43-
@Override public void destroy() {
44-
RadixTree.this.destroy();
45-
}
46-
};
47-
}
18+
RouterMatch find(Context context, String path, MessageEncoder encoder);
4819

4920
default RadixTree options(boolean ignoreCase, boolean ignoreTrailingSlash) {
5021
return new RadixTree() {
@@ -58,11 +29,9 @@ default RadixTree options(boolean ignoreCase, boolean ignoreTrailingSlash) {
5829
.find(method, Router.normalizePath(path, ignoreCase, ignoreTrailingSlash));
5930
}
6031

61-
@Override public RouterMatch find(Context context, String path, MessageEncoder encoder,
62-
List<RadixTree> more) {
32+
@Override public RouterMatch find(Context context, String path, MessageEncoder encoder) {
6333
return RadixTree.this
64-
.find(context, Router.normalizePath(path, ignoreCase, ignoreTrailingSlash), encoder,
65-
more);
34+
.find(context, Router.normalizePath(path, ignoreCase, ignoreTrailingSlash), encoder);
6635
}
6736

6837
@Override public void destroy() {

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.util.ArrayList;
4242
import java.util.Collections;
4343
import java.util.HashMap;
44+
import java.util.LinkedHashMap;
4445
import java.util.LinkedList;
4546
import java.util.List;
4647
import java.util.Map;
@@ -123,7 +124,7 @@ public Stack executor(Executor executor) {
123124

124125
private String basePath;
125126

126-
private List<RadixTree> trees;
127+
private Map<Predicate<Context>, RadixTree> predicateMap;
127128

128129
private Executor worker = new ForwardingExecutor();
129130

@@ -194,11 +195,11 @@ public RouterImpl(ClassLoader loader) {
194195

195196
@Nonnull @Override
196197
public Router use(@Nonnull Predicate<Context> predicate, @Nonnull Router router) {
197-
RadixTree tree = new $Chi().with(predicate);
198-
if (trees == null) {
199-
trees = new ArrayList<>();
198+
RadixTree tree = new $Chi();
199+
if (predicateMap == null) {
200+
predicateMap = new LinkedHashMap<>();
200201
}
201-
trees.add(tree);
202+
predicateMap.put(predicate, tree);
202203
for (Route route : router.getRoutes()) {
203204
Route newRoute = defineRoute(route.getMethod(), route.getPattern(), route.getHandler(), tree);
204205
copy(route, newRoute);
@@ -339,7 +340,8 @@ public Router encoder(@Nonnull MediaType contentType, @Nonnull MessageEncoder en
339340
return beanConverters;
340341
}
341342

342-
@Nonnull @Override public Route ws(@Nonnull String pattern, @Nonnull WebSocket.Initializer handler) {
343+
@Nonnull @Override
344+
public Route ws(@Nonnull String pattern, @Nonnull WebSocket.Initializer handler) {
343345
return route(WS, pattern, new WebSocketHandler(handler)).setHandle(handler);
344346
}
345347

@@ -464,7 +466,8 @@ private Route defineRoute(@Nonnull String method, @Nonnull String pattern,
464466
}
465467
} else {
466468
/** Consumes && Produces (only for HTTP routes (not web socket) */
467-
route.setBefore(prependMediaType(route.getConsumes(), route.getBefore(), Route.SUPPORT_MEDIA_TYPE));
469+
route.setBefore(
470+
prependMediaType(route.getConsumes(), route.getBefore(), Route.SUPPORT_MEDIA_TYPE));
468471
route.setBefore(prependMediaType(route.getProduces(), route.getBefore(), Route.ACCEPT));
469472
}
470473
/** Response handler: */
@@ -517,10 +520,10 @@ public void destroy() {
517520
errorCodes.clear();
518521
errorCodes = null;
519522
}
520-
if (this.trees != null) {
521-
this.trees.forEach(RadixTree::destroy);
522-
this.trees.clear();
523-
this.trees = null;
523+
if (this.predicateMap != null) {
524+
this.predicateMap.values().forEach(RadixTree::destroy);
525+
this.predicateMap.clear();
526+
this.predicateMap = null;
524527
}
525528
}
526529

@@ -529,7 +532,17 @@ public void destroy() {
529532
}
530533

531534
@Nonnull @Override public Match match(@Nonnull Context ctx) {
532-
return chi.find(ctx, ctx.pathString(), encoder, trees);
535+
if (predicateMap != null) {
536+
for (Map.Entry<Predicate<Context>, RadixTree> e : predicateMap.entrySet()) {
537+
if (e.getKey().test(ctx)) {
538+
RouterMatch match = e.getValue().find(ctx, ctx.pathString(), encoder);
539+
if (match.matches) {
540+
return match;
541+
}
542+
}
543+
}
544+
}
545+
return chi.find(ctx, ctx.pathString(), encoder);
533546
}
534547

535548
@Override public boolean match(@Nonnull String pattern, @Nonnull String path) {

jooby/src/test/java/io/jooby/internal/ChiTest.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ public void routeOverride() {
2424
router.insert(bar);
2525

2626
RouterMatch result = router
27-
.find(ctx("/abcd"), MessageEncoder.TO_STRING,
28-
Collections.emptyList());
27+
.find(ctx("/abcd"), MessageEncoder.TO_STRING);
2928
assertTrue(result.matches);
3029
assertEquals(bar, result.route());
3130
}
@@ -46,8 +45,7 @@ public void routeCase() {
4645
router.insert(foos);
4746

4847
RouterMatch result = router
49-
.find(ctx("/abcd/"), MessageEncoder.TO_STRING,
50-
Collections.emptyList());
48+
.find(ctx("/abcd/"), MessageEncoder.TO_STRING);
5149
assertTrue(result.matches);
5250
assertEquals(foos, result.route());
5351
}
@@ -102,7 +100,7 @@ public void searchString() throws Exception {
102100

103101
// app.get("/regex/{zid:[0-9]+}/edit", ctx -> ctx.getRoute().getPathKeys());
104102

105-
router.insert(route("GET", "/regex/{nid:[0-9]+}", stringHandler("nid")));
103+
router.insert(route("GET", "/regex/{nid:[0-9]+}", stringHandler("nid")));
106104
router.insert(route("GET", "/regex/{zid:[0-9]+}/edit", stringHandler("zid")));
107105
router.insert(route("GET", "/articles/{id}", stringHandler("id")));
108106
router.insert(route("GET", "/articles/*", stringHandler("*")));
@@ -127,8 +125,8 @@ public void searchString() throws Exception {
127125
public void searchParam() throws Exception {
128126
$Chi router = new $Chi();
129127

130-
router.insert(route("GET", "/articles/{id}", stringHandler("id")));
131-
router.insert(route("GET", "/articles/*", stringHandler("catchall")));
128+
router.insert(route("GET", "/articles/{id}", stringHandler("id")));
129+
router.insert(route("GET", "/articles/*", stringHandler("catchall")));
132130

133131
find(router, "/articles/123", (ctx, result) -> {
134132
assertTrue(result.matches);
@@ -145,7 +143,7 @@ private void find($Chi router, String pattern,
145143
SneakyThrows.Consumer2<Context, RouterMatch> consumer) {
146144
Context rootctx = ctx(pattern);
147145
RouterMatch result = router
148-
.find(rootctx, MessageEncoder.TO_STRING, Collections.emptyList());
146+
.find(rootctx, MessageEncoder.TO_STRING);
149147
consumer.accept(rootctx, result);
150148
}
151149

tests/src/test/java/io/jooby/FeaturedTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,9 +1136,10 @@ public void dynamicRoutingComposition(ServerTestRunner runner) {
11361136
Jooby v2 = new Jooby();
11371137
v2.get("/api", ctx -> "v2");
11381138

1139-
app.use(ctx -> ctx.header("version").value().equals("v1"), v1);
1140-
app.use(ctx -> ctx.header("version").value().equals("v2"), v2);
1139+
app.use(ctx -> ctx.header("version").value("").equals("v1"), v1);
1140+
app.use(ctx -> ctx.header("version").value("").equals("v2"), v2);
11411141

1142+
app.get("/api",ctx -> "fallback");
11421143
}).ready(client -> {
11431144
client.header("version", "v2");
11441145
client.get("/api", rsp -> {
@@ -1149,6 +1150,10 @@ public void dynamicRoutingComposition(ServerTestRunner runner) {
11491150
client.get("/api", rsp -> {
11501151
assertEquals("v1", rsp.body().string());
11511152
});
1153+
1154+
client.get("/api", rsp -> {
1155+
assertEquals("fallback", rsp.body().string());
1156+
});
11521157
});
11531158
}
11541159

0 commit comments

Comments
 (0)