예제 #1
0
        public SearchResult[] PerformSearch(string search, FrecencyStorage frecencyStorage)
        {
            bool updated;

            _indexableUpdateState = _indexableUpdateState.CheckUpdate(out updated);

            if (updated)
            {
                Log.Information("Updated searcher with new indexables.");
                _selectaSeacher = Searcher.Create(_indexableUpdateState.Indexables);
            }

            var frecencyData = frecencyStorage.GetFrecencyData();
            Func <IIndexable, int> boosterFunc = x => frecencyData.ContainsKey(x.BoostIdentifier) ? frecencyData[x.BoostIdentifier] : 0;

            _selectaSeacher = _selectaSeacher.Search(search, boosterFunc);

            SearchResult[] searchResults = _selectaSeacher.SearchResults.Take(100).ToArray();

            try
            {
                double result = _calculationEngine.Calculate(search);
                var    name   = result.ToString(CultureInfo.InvariantCulture);

                if (!string.Equals(name, search?.Trim(), StringComparison.InvariantCultureIgnoreCase))
                {
                    searchResults = searchResults.Concat(new[] { new SearchResult(name, 0, new StringIndexable(name, "Result of formula"), ImmutableHashSet.Create <int>()) }).ToArray();
                }
            }
            catch
            {
                // Ignore calculation errors.
            }

            return(searchResults);
        }
예제 #2
0
        public ISearchFrame GetSearchFrame(IIndexable[] indexables)
        {
            indexables = indexables?.Where(x => x != null).ToArray() ?? new IIndexable[0];

            if (!indexables.Any())
            {
                Func <string>          getUpdatedState = () => $"{_updateCounter}-{SearchResources.UpdateCounter}";
                Func <IndexableResult> fetchIndexables = () => new IndexableResult(_indexers.SelectMany(x => x()).ToArray(), getUpdatedState());
                var indexableUpdateState = new IndexableUpdateState(fetchIndexables, getUpdatedState);
                return(new UpdateableIndexableSearchFrame(indexableUpdateState));
            }

            Type type = indexables.First().GetType();

            var closedActionType = GetInstanceOfGenericType(typeof(IAction <>), type);

            if (closedActionType != null && closedActionType == typeof(IAction <StringIndexable>))
            {
                if (indexables.Length > 1)
                {
                    return(null);
                }

                if (typeof(IHasSearchFrame).IsAssignableFrom(type))
                {
                    IHasSearchFrame hasSearchFrame = (IHasSearchFrame)Activator.CreateInstance(type);
                    return(hasSearchFrame.GetSearchFrame());
                }

                if (typeof(IAutocomplete).IsAssignableFrom(type))
                {
                    IAutocomplete autocomplete = (IAutocomplete)Activator.CreateInstance(type);
                    return(new StringSearchFrame(autocomplete.GetAutocompleteResults));
                }

                return(new StringSearchFrame(null));
            }

            var targetTypes = new Type[0];

            foreach (IIndexable indexable in indexables)
            {
                if (indexable is IAction)
                {
                    if (targetTypes.Any())
                    {
                        return(null);
                    }

                    var actionParameterTypes = indexable.GetType().GetInterfaces()
                                               .Where(x => x.IsGenericTypeDefinition && x.GetGenericTypeDefinition() == typeof(IAction <>))
                                               .Select(x => x.GenericTypeArguments[0])
                                               .ToArray();

                    targetTypes = actionParameterTypes;
                }
                else if (indexable is IConvert)
                {
                    if (targetTypes.Length == 1)
                    {
                        var convertParameterTypes = indexable.GetType().GetInterfaces()
                                                    .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IConvert <,>) && x.GenericTypeArguments[0] == targetTypes[0])
                                                    .Select(x => x.GenericTypeArguments[1])
                                                    .ToArray();

                        targetTypes = convertParameterTypes;
                    }
                }
                else
                {
                    targetTypes = new[] { indexable.GetType() };
                }
            }

            var actionTypes = targetTypes
                              .SelectMany(x => GetActionForInType(x).Select(y => y.ActionType))
                              .ToArray();

            var convertTypes = targetTypes
                               .SelectMany(x => GetConvertForInType(x).Select(y => y.ConvertType))
                               .ToArray();

            if (actionTypes.Any())
            {
                var matchedIndexables = actionTypes.Concat(convertTypes).Select(Activator.CreateInstance).OfType <IIndexable>().ToArray();
                return(new IndexableSearchFrame(matchedIndexables));
            }

            return(null);
        }
예제 #3
0
 public UpdateableIndexableSearchFrame(IndexableUpdateState indexableUpdateState)
 {
     _indexableUpdateState = indexableUpdateState;
     _selectaSeacher       = Searcher.Create(_indexableUpdateState.Indexables);
     _calculationEngine    = new CalculationEngine();
 }