public static HiPerfTimer StartNew() { var t = new HiPerfTimer(); t.Start(); return(t); }
/// <summary> /// Search /// </summary> /// <param name="query"></param> /// <returns>Matched results</returns> public SearchResult[] Search(string query) { LastPerfInfo = new PerfInfo(); if (Keywords.Length == 0) { return(new SearchResult[0]); } var timer = HiPerfTimer.StartNew(); var lastMatchedPositions = new Dictionary <int, int>(); var resultList = new Dictionary <int, SearchResult>(); for (var pos = 0; pos < query.Length; pos++) { var c = query[pos]; Node node; if (!Nodes.TryGetValue(c, out node)) { resultList.Clear(); break; } // Clear items in resultList which do not appears in node. FilterOut(resultList, node); // whether the result is matched in order. var isInOrder = new Dictionary <int, bool>(); node.Infos.ForEach(info => { var index = info.Index; if (pos == 0) { // This is the start point. Only the isInOrder of matched index will be set to true // to initiate the searching range. // Since that positions with the same index is added in asc order, I take // the first one to add to lastMatchedPositions. isInOrder[index] = true; if (!lastMatchedPositions.ContainsKey(index)) { lastMatchedPositions[index] = info.Position; } } else { if (!resultList.ContainsKey(index)) { // Not in the last searching range. resultList.Remove(index); return; } if (isInOrder.ContainsKey(index) && isInOrder[index]) { // Skip duplicate matched index. return; } if (info.Position > lastMatchedPositions[index]) { // This matched char is behind the last matched char, which means it's in order. // Update lastMatchedPositions for next matching. isInOrder[index] = true; lastMatchedPositions[index] = info.Position; } else { // Not in order, which means this matched char is in front of the // last matched char. So mark it "false". isInOrder[index] = false; } } }); // Add to result list if in order. // Otherwise remove from list. foreach (var info in node.Infos) { bool inOrder; if (isInOrder.TryGetValue(info.Index, out inOrder) && inOrder) { AddToResult(resultList, info); } else { resultList.Remove(info.Index); } } } // other procedures var resultArray = PostProcess(resultList); timer.Stop(); LastPerfInfo.TotalMs = timer.Duration; return(resultArray); }