private List<ReducerFactory> resolveReducerOrder( List<ReducerFactory> reducerFactories, List<AggregatorFactory> aggFactories) { Map<String, ReducerFactory> reducerFactoriesMap = new HashMap<>(); for (ReducerFactory factory : reducerFactories) { reducerFactoriesMap.put(factory.getName(), factory); } Set<String> aggFactoryNames = new HashSet<>(); for (AggregatorFactory aggFactory : aggFactories) { aggFactoryNames.add(aggFactory.name); } List<ReducerFactory> orderedReducers = new LinkedList<>(); List<ReducerFactory> unmarkedFactories = new ArrayList<ReducerFactory>(reducerFactories); Set<ReducerFactory> temporarilyMarked = new HashSet<ReducerFactory>(); while (!unmarkedFactories.isEmpty()) { ReducerFactory factory = unmarkedFactories.get(0); resolveReducerOrder( aggFactoryNames, reducerFactoriesMap, orderedReducers, unmarkedFactories, temporarilyMarked, factory); } return orderedReducers; }
private void resolveReducerOrder( Set<String> aggFactoryNames, Map<String, ReducerFactory> reducerFactoriesMap, List<ReducerFactory> orderedReducers, List<ReducerFactory> unmarkedFactories, Set<ReducerFactory> temporarilyMarked, ReducerFactory factory) { if (temporarilyMarked.contains(factory)) { throw new IllegalStateException( "Cyclical dependancy found with reducer [" + factory.getName() + "]"); } else if (unmarkedFactories.contains(factory)) { temporarilyMarked.add(factory); String[] bucketsPaths = factory.getBucketsPaths(); for (String bucketsPath : bucketsPaths) { List<String> bucketsPathElements = AggregationPath.parse(bucketsPath).getPathElementsAsStringList(); String firstAggName = bucketsPathElements.get(0); if (bucketsPath.equals("_count") || bucketsPath.equals("_key") || aggFactoryNames.contains(firstAggName)) { continue; } else { ReducerFactory matchingFactory = reducerFactoriesMap.get(firstAggName); if (matchingFactory != null) { resolveReducerOrder( aggFactoryNames, reducerFactoriesMap, orderedReducers, unmarkedFactories, temporarilyMarked, matchingFactory); } else { throw new IllegalStateException( "No aggregation found for path [" + bucketsPath + "]"); } } } unmarkedFactories.remove(factory); temporarilyMarked.remove(factory); orderedReducers.add(factory); } }