public static FiltersExecutionPipeline Build(IFilter filter) { var pipeline = new FiltersExecutionPipeline(); pipeline.Visit(filter); return(pipeline); }
public PreparedExecution PrepareExecution(IFilter filter, IIndicesCoverage indicesCoverage) { var executionPipeline = FiltersExecutionPipeline.Build(filter); var availableExecutorsColelction = ExecutorsManager.Instance.AvailableExecutorsCollection; // In this collection we will collect best executors of each filter in tree var allPreparedFilterExecutions = new List <Tuple <IFilter, PreparedExecution> >(); foreach (var executionGroup in executionPipeline.GetExecutionGroups()) { foreach (var localFilter in executionGroup.Filters) { if (!(localFilter is IOneOperationTargetFilter oneOperationTargetFilter)) { return(PreparedExecution.Unsuccess); } // Get available for filter's operation target indices. var availableIndices = indicesCoverage.GetIndices(oneOperationTargetFilter.OperationTarget); // Find all executors which are allowed with specifed indices var allowedExecutors = availableExecutorsColelction.GetAvailableExecutors(oneOperationTargetFilter.OperationTarget.TargetType, availableIndices); // Prepare execution with all of them var preparedExecutions = allowedExecutors.Select(x => x.PrepareExecution(localFilter)).ToArray(); // Find executor which can execute this filter with minimal complexity var bestPreparedExecution = preparedExecutions .Where(x => x.CanBeExecuted) .OrderBy(x => x.TimeComplexity.Weight) .FirstOrDefault(); if (bestPreparedExecution == null && !(localFilter is CompoundFilter)) { // TODO: if we can't execute one filter in tree we don't need to break execution for whole tree return(PreparedExecution.Unsuccess); } allPreparedFilterExecutions.Add(new Tuple <IFilter, PreparedExecution>(localFilter, bestPreparedExecution)); } } // TODO: parallel filters execution return(CombinePreparedExecutions(allPreparedFilterExecutions)); }