@Override public Optional<String> triePath() { return pathStringMapping.triePath(); }
@Nullable static String getNormalizedTriePath(PathMapping pathMapping) { requireNonNull(pathMapping, "pathMapping"); final Optional<String> triePath = pathMapping.triePath(); if (!triePath.isPresent()) { return null; } final String path = triePath.get(); int beginIndex = 0; final StringBuilder sb = new StringBuilder(); for (String paramName : pathMapping.paramNames()) { final int colonIndex = path.indexOf(':', beginIndex); assert colonIndex != -1; sb.append(path, beginIndex, colonIndex); sb.append('{'); sb.append(paramName); sb.append('}'); beginIndex = colonIndex + 1; } if (beginIndex < path.length()) { sb.append(path, beginIndex, path.length()); } return sb.toString(); }
/** * Returns a list of {@link Router}s. */ @VisibleForTesting static <V> List<Router<V>> routers(Iterable<V> values, Function<V, PathMapping> pathMappingResolver, BiConsumer<PathMapping, PathMapping> rejectionHandler) { rejectDuplicateMapping(values, pathMappingResolver, rejectionHandler); final ImmutableList.Builder<Router<V>> builder = ImmutableList.builder(); final List<V> group = new ArrayList<>(); boolean addingTrie = true; for (V value : values) { final PathMapping mapping = pathMappingResolver.apply(value); final boolean triePathPresent = mapping.triePath().isPresent(); if (addingTrie && triePathPresent || !addingTrie && !triePathPresent) { // We are adding the same type of PathMapping to 'group'. group.add(value); continue; } // Changed the router type. if (!group.isEmpty()) { builder.add(router(addingTrie, group, pathMappingResolver)); } addingTrie = !addingTrie; group.add(value); } if (!group.isEmpty()) { builder.add(router(addingTrie, group, pathMappingResolver)); } return builder.build(); }
/** * Returns a {@link Router} implementation which is using one of {@link RoutingTrie} and {@link List}. */ private static <V> Router<V> router(boolean isTrie, List<V> values, Function<V, PathMapping> pathMappingResolver) { final Comparator<V> valueComparator = Comparator.comparingInt(e -> -1 * pathMappingResolver.apply(e).complexity()); final Router<V> router; if (isTrie) { final RoutingTrie.Builder<V> builder = new Builder<>(); // Set a comparator to sort services by the number of conditions to be checked in a descending // order. builder.comparator(valueComparator); values.forEach(v -> builder.add(pathMappingResolver.apply(v).triePath().get(), v)); router = new TrieRouter<>(builder.build(), pathMappingResolver); } else { values.sort(valueComparator); router = new SequentialRouter<>(values, pathMappingResolver); } if (logger.isDebugEnabled()) { logger.debug("Router created for {} service(s): {}", values.size(), router.getClass().getSimpleName()); values.forEach(c -> { final PathMapping mapping = pathMappingResolver.apply(c); logger.debug("meterTag: {}, complexity: {}", mapping.meterTag(), mapping.complexity()); }); } values.clear(); return router; }
for (V v : values) { final PathMapping mapping = pathMappingResolver.apply(v); final Optional<String> triePathOpt = mapping.triePath(); if (!triePathOpt.isPresent()) { continue;