internal SearchManager( ILogSourcesManager sources, ISynchronizationContext modelSynchronization, IHeartBeatTimer heartBeat, ISearchObjectsFactory factory, IChangeNotification changeNotification ) { this.sources = sources; this.factory = factory; this.changeNotification = changeNotification; this.combinedSearchResult = factory.CreateCombinedSearchResult(this); this.combinedResultUpdateInvoker = new AsyncInvokeHelper( modelSynchronization, UpdateCombinedResult); this.combinedResultNeedsLazyUpdateFlag = new LazyUpdateFlag(); sources.OnLogSourceAdded += (s, e) => { results.ForEach(r => r.FireChangeEventIfContainsSourceResults(s as ILogSource)); }; sources.OnLogSourceRemoved += (s, e) => { results.ForEach(r => r.FireChangeEventIfContainsSourceResults(s as ILogSource)); // Search result is fully disposed if it contains messages // only from disposed log sources. // Fully disposed results are automatically dropped. var toBeDropped = results.Where( r => r.Results.All(sr => sr.Source.IsDisposed)).ToHashSet(); var nrOfFullyDisposedResults = DisposeResults(toBeDropped); if (nrOfFullyDisposedResults > 0 && SearchResultsChanged != null) { SearchResultsChanged(this, EventArgs.Empty); } if (nrOfFullyDisposedResults > 0) { changeNotification.Post(); combinedResultNeedsLazyUpdateFlag.Invalidate(); } }; heartBeat.OnTimer += (s, e) => { if (e.IsNormalUpdate && combinedResultNeedsLazyUpdateFlag.Validate()) { combinedResultUpdateInvoker.Invoke(); } }; }
public SearchResult( ISearchManagerInternal owner, SearchAllOptions options, IFilter optionsFilter, IList <ILogSourceSearchWorkerInternal> workers, Progress.IProgressAggregatorFactory progressAggregatorFactory, ISynchronizationContext modelSynchronization, Settings.IGlobalSettingsAccessor settings, int id, ISearchObjectsFactory factory, ITraceSourceFactory traceSourceFactory ) { this.owner = owner; this.options = options; this.optionsFilter = optionsFilter; this.factory = factory; this.modelSynchronization = modelSynchronization; this.id = id; this.cancellation = new CancellationTokenSource(); this.results = new List <ISourceSearchResultInternal>(); this.progressAggregator = progressAggregatorFactory.CreateProgressAggregator(); this.updateInvokationHelper = new AsyncInvokeHelper(modelSynchronization, UpdateStatus); this.hitsLimit = settings.MaxNumberOfHitsInSearchResultsView; this.visible = true; this.trace = traceSourceFactory.CreateTraceSource("SearchManager", "sr." + id.ToString()); this.timeGapsDetector = new TimeGapsDetector(trace, modelSynchronization, this, traceSourceFactory); this.timeGapsDetector.OnTimeGapsChanged += (s, e) => { owner.OnResultChanged(this, SearchResultChangeFlag.TimeGapsChanged); }; this.progressAggregator.ProgressChanged += HandleProgressChanged; this.searchTime = Stopwatch.StartNew(); this.results.AddRange(workers.Select(w => factory.CreateSourceSearchResults(w, this, cancellation.Token, progressAggregator))); if (results.Count == 0) { status = SearchResultStatus.Finished; HandleFinalStateTransition(); } }
public CombinedSearchResult(ISearchManagerInternal owner, ISearchObjectsFactory objectsFactory) { this.owner = owner; this.objectsFactory = objectsFactory; }