/// <summary> /// Performs a search /// </summary> /// <param name="dataSource">Traffic data accesssor</param> /// <param name="criteriaSet">Set of criteria for the search</param> /// <param name="result">The search result</param> public void Search(ITrafficDataAccessor dataSource, SearchCriteriaSet criteriaSet, ISearchResult result) { _stopSearch = false; //check the search results cache int hash = GetSearchHash(dataSource, criteriaSet); ICacheable entry = SearchResultCache.Instance.GetEntry(hash); ISearchResult cachedResult = null; if (entry != null) { cachedResult = entry.Reserve() as ISearchResult; entry.Release(); } if (cachedResult == null) { //check for a subset SearchSubset subset = GetSearchSubset(criteriaSet); if (subset == null) { FullSearch(dataSource, criteriaSet, result); } else { SubsetSearch(dataSource, criteriaSet, result, subset); } //cache the search SearchResultCache.Instance.Add(hash, new CacheEntry(result)); } else { result.AddRange(cachedResult); } }
/// <summary> /// Verifies a request /// </summary> /// <param name="dataSource"></param> /// <param name="header"></param> /// <param name="criteriaSet"></param> /// <param name="result"></param> protected override void RequestMatches(ITrafficDataAccessor dataSource, TVRequestInfo header, SearchCriteriaSet criteriaSet, ISearchResult result) { bool found = false; int hashSum = criteriaSet.DescriptionFilter.GetHashCode(); List <MatchCoordinates> matchCoordinates; //variable used to obtain match coordinates //create a temp list to store all the matches LineMatches tempMatches = new LineMatches(); if (criteriaSet.DescriptionFilter == null || criteriaSet.DescriptionFilter == String.Empty || header.Description.IndexOf(criteriaSet.DescriptionFilter, StringComparison.CurrentCultureIgnoreCase) > -1) { //apply an AND operation with all the search criterias from the last search criteria cached int i, n = criteriaSet.Count, start = criteriaSet.StartCriteriaIndex; for (i = start; i < n; i++) { ISearchCriteria criteria = criteriaSet[i]; found = false; //compose the text to search if (criteria.Context == SearchContext.RequestLine) { if (criteria.Matches(header.RequestLine, 0, out matchCoordinates)) { //if we got here it means that the request line matches //using the request search context since we really care only for request or response found = true; tempMatches.Add(new LineMatch(header.Id, header.RequestLine, matchCoordinates, SearchContext.Request)); } else { found = false; break; //one of the criteria did not match so the end result is false } } else { //search in request first if (criteria.Context == SearchContext.Full || criteria.Context == SearchContext.Request || criteria.Context == SearchContext.RequestBody) { found = SearchInContext(dataSource, header, criteria, SearchContext.Request, ref tempMatches); } if (criteria.Context == SearchContext.Full || criteria.Context == SearchContext.Response) { found |= SearchInContext(dataSource, header, criteria, SearchContext.Response, ref tempMatches); } if (!found) { break; //no match was found in the entire stream } } //if at the end of criteria iteration found is still true cache the hashSum of this criteria //so we can get the sublist of request ids in future searches if (found) { hashSum = hashSum ^ criteria.GetHashCode(); SearchSubset subset = null; ICacheable entry = SearchSubsetsCache.Instance.GetEntry(hashSum); if (entry == null) { subset = new SearchSubset(); subset.Add(header.Id); SearchSubsetsCache.Instance.Add(hashSum, new CacheEntry(subset)); } else { subset = entry.Reserve() as SearchSubset; if (!subset.Contains(header.Id)) { subset.Add(header.Id); } entry.Release(); } } } //end of for, all the criterias were matched or one criteria did not match if (found) { //add all the temp matches to the results result.AddRange(tempMatches); } } }