using System; using System.Collections.Generic; using System.Linq; using AutoMapper; using DR.FV2016.Service.Interfaces; using DR.FV2016.Web.Models; namespace DR.FV2016.Web.PoliticianLink { public class SearchIndexCache { private readonly ICompositeCandidateService _compositeCandidateService; public SearchIndexCache(ICompositeCandidateService compositeCandidateService) { _compositeCandidateService = compositeCandidateService; } private static IDictionary> _searchCache = new SortedDictionary>(StringComparer.InvariantCultureIgnoreCase); private static DateTime _lastSearchIndexLoad; private static readonly TimeSpan SearchIndexCacheTime = new TimeSpan(0, 0, 30, 0); //30 minutes public IDictionary> GetSearchIndex() { if (_lastSearchIndexLoad.Add(SearchIndexCacheTime) < DateTime.Now && !_searchCache.Any()) { _lastSearchIndexLoad = DateTime.Now; try { _searchCache = LoadSearchItems(); } catch (Exception e) { //_articleColliderLogService.LogErrorEvent(new ErrorLogEvent(e), ErrorSeverity.Error); } return _searchCache; } if (_lastSearchIndexLoad.Add(SearchIndexCacheTime) < DateTime.Now) { _lastSearchIndexLoad = DateTime.Now; Func>> loader = LoadSearchItems; loader.BeginInvoke(callback => { try { _searchCache = loader.EndInvoke(callback); } catch (Exception e) { //_articleColliderLogService.LogErrorEvent(new ErrorLogEvent(e), ErrorSeverity.Error); } }, null); } return _searchCache; } private IDictionary> LoadSearchItems() { var searchItems = new List(); var candidateSearchType = SearchType.Fv15Candidate; var candidateSearchItems = Mapper.Map>(_compositeCandidateService.GetCandidates().GroupBy(c => c.Id).Select(g => g.FirstOrDefault())); candidateSearchItems = candidateSearchItems.Select(c => { c.Type = candidateSearchType; return c; }).ToList(); searchItems.AddRange(candidateSearchItems); var ambigousSearchWords = searchItems.Select(a => new { word = a.Word, count = searchItems.Count(b => b.Word == a.Word) }).Where(a => a.count > 1).ToList(); var distinctCandidates = searchItems.Where(a => !ambigousSearchWords.Any(b => b.word == a.Word)); var index = new SortedDictionary>(StringComparer.InvariantCultureIgnoreCase); foreach (var candidate in distinctCandidates) { var key = candidate.Word.Split(" ".ToCharArray()).First(); List list; if (!index.TryGetValue(key, out list)) { list = new List(); index[key] = list; } list.Add(candidate); } return index; } } }