static Router<ServiceConfig> ofVirtualHost(VirtualHost virtualHost, Iterable<ServiceConfig> configs,
                                               RejectedRouteHandler rejectionHandler) {
        requireNonNull(virtualHost, "virtualHost");
        requireNonNull(configs, "configs");
        requireNonNull(rejectionHandler, "rejectionHandler");

        final BiConsumer<Route, Route> rejectionConsumer = (route, existingRoute) -> {
            try {
                rejectionHandler.handleDuplicateRoute(virtualHost, route, existingRoute);
            } catch (Exception e) {
                logger.warn("Unexpected exception from a {}:",
                            RejectedRouteHandler.class.getSimpleName(), e);
            }
        };

        final Map<Route, ServiceConfig> newServiceConfigs = new HashMap<>();
        final BiFunction<Route, ServiceConfig, ServiceConfig> fallbackValueConfigurator =
                (originalRoute, fallbackServiceConfig) -> {
                    final Route fallbackRoute = fallbackServiceConfig.route();

                    if (originalRoute.complexity() == fallbackRoute.complexity() &&
                        originalRoute.methods().containsAll(fallbackRoute.methods())) {
                        return fallbackServiceConfig;
                    }

                    assert fallbackRoute.equals(FALLBACK_ROUTE)
                            : "Fallback service must catch all requests, but its route is: " + fallbackRoute;
                    final Route newRoute =
                            originalRoute.toBuilder()
                                         .pathMapping(CatchAllPathMapping.INSTANCE)
                                         // Set this route as a fallback.
                                         .fallback(true)
                                         .build();
                    // We have only one fallback ServiceConfig instance so finding a cached config
                    // with a Route instance is okay at the moment.
                    final ServiceConfig cachedConfig = newServiceConfigs.get(newRoute);
                    if (cachedConfig != null) {
                        return cachedConfig;
                    }
                    final ServiceConfig newConfig = fallbackServiceConfig.withRoute(newRoute);
                    newServiceConfigs.put(newRoute, newConfig);
                    return newConfig;
                };
        final Set<Route> dynamicPredicateRoutes =
                resolveDynamicPredicateRoutes(StreamSupport.stream(configs.spliterator(), false)
                                                           .map(ServiceConfig::route)
                                                           .collect(toImmutableList()));
        return wrapVirtualHostRouter(
                defaultRouter(configs, virtualHost.fallbackServiceConfig(), fallbackValueConfigurator,
                              ServiceConfig::route, rejectionConsumer, false),
                dynamicPredicateRoutes);
    }
Returns the default implementation of the {@link Router} to find a {@link ServiceConfig}.
It consists of several router implementations which use one of Trie and List. It also includes
cache mechanism to improve its performance.
core/src/main/java/com/linecorp/armeria/server/Routers.java