MatchLane CloneLane(MatchLane other) { MatchLane lane = GetPoolLane(); lane.Initialize(other); return(lane); }
MatchLane CreateLane(MatchMode mode, int pos) { MatchLane lane = GetPoolLane(); lane.Initialize(mode, pos); if (mode == MatchMode.Acronym) { lane.WordStartsMatched = 1; } return(lane); }
public MatchLane Clone() { MatchLane lane = new MatchLane(); lane.Positions = (int[])Positions.Clone(); lane.Lengths = (int[])Lengths.Clone(); lane.MatchMode = MatchMode; lane.MatchIndex = MatchIndex; lane.Index = Index; return(lane); }
public void Initialize(MatchLane other) { for (int n = 0; n <= other.Index; n++) { Positions [n] = other.Positions [n]; Lengths [n] = other.Lengths [n]; } MatchMode = other.MatchMode; MatchIndex = other.MatchIndex; Index = other.Index; ExactCaseMatches = other.ExactCaseMatches; WordStartsMatched = other.WordStartsMatched; }
MatchLane GetPoolLane() { if (lanePoolIndex < lanePool.Count) { return(lanePool [lanePoolIndex++]); } MatchLane lane = new MatchLane(filterLowerCase.Length * 2); lanePool.Add(lane); lanePoolIndex++; return(lane); }
bool LaneExists(MatchMode mode, int matchIndex) { if (matchLanes == null) { return(false); } for (int n = 0; n < matchLanes.Count; n++) { MatchLane lane = matchLanes [n]; if (lane != null && lane.MatchMode == mode && lane.MatchIndex == matchIndex) { return(true); } } return(false); }
static bool CalcMatchRank(string name, string toMatch, out int matchRank) { if (toMatch.Length == 0) { matchRank = int.MinValue; return(true); } MatchLane lane = MatchString(name, toMatch); if (lane != null) { matchRank = -(lane.Positions [0] + (name.Length - toMatch.Length)); return(true); } matchRank = int.MinValue; return(false); }
public override bool CalcMatchRank(string name, out int matchRank) { if (filterLowerCase.Length == 0) { matchRank = int.MinValue; return(true); } int totalWords; MatchLane lane = MatchString(name, out totalWords); if (lane != null) { matchRank = filterLowerCase.Length - name.Length; matchRank -= lane.Positions [0]; matchRank += (lane.WordStartsMatched - totalWords) * 100; // Favor matches where all parts are word starts if (lane.WordStartsMatched == lane.Index + 1) { matchRank += 100; } // Favor matches with less splits. That is, 'abc def' is better than 'ab c def'. int baseRank = (filter.Length - lane.Index - 1) * 5000; // First matching letter close to the begining is better // The more matched letters the better matchRank = baseRank - (lane.Positions [0] + (name.Length - filterLowerCase.Length)); matchRank += lane.ExactCaseMatches * 10; // rank up matches which start with a filter substring if (lane.Positions [0] == 0) { matchRank += lane.Lengths[0] * 50; } return(true); } matchRank = int.MinValue; return(false); }
MatchLane MatchString(string text, out int totalWords) { totalWords = 0; if (text == null || text.Length < filterLowerCase.Length) { return(null); } // Pre-match check string textLowerCase = text.ToLowerInvariant(); bool lastWasSeparator = false; int firstMatchPos = -1; int j = 0; int tlen = text.Length; int flen = filterLowerCase.Length; for (int n = 0; n < tlen && j < flen; n++) { char ctLower = textLowerCase[n]; char cfLower = filterLowerCase [j]; bool wordStart = (ctLower != text[n]) || n == 0 || lastWasSeparator; if (wordStart) { totalWords++; } if (ctLower == cfLower && !(cfLower != filter[j] && ctLower == text[n])) { bool exactMatch = filter[j] == text[n]; j++; if (firstMatchPos == -1) { firstMatchPos = n; } if (flen == 1) { MatchLane lane = CreateLane(MatchMode.Substring, n); if (exactMatch) { lane.ExactCaseMatches++; } return(lane); } } lastWasSeparator = IsSeparator(ctLower); } if (j < flen) { return(null); } ResetLanePool(); // Full match check matchLanes.Clear(); int tn = firstMatchPos; char filterStartLower = filterLowerCase[0]; bool filterStartIsUpper = filterStartLower != filter[0]; while (tn < text.Length) { char ct = text [tn]; char ctLower = textLowerCase [tn]; bool ctIsUpper = ct != ctLower; bool wordStart = ctIsUpper || tn == 0 || lastWasSeparator; if (wordStart) { totalWords++; } // Keep the lane count in a var because new lanes don't have to be updated // until the next iteration int laneCount = matchLanes != null ? matchLanes.Count : 0; if (ctLower == filterStartLower && !(filterStartIsUpper && !ctIsUpper)) { // Potential start position of a match MatchLane lane = CreateLane(MatchMode.Substring, tn); if (filterStartIsUpper == ctIsUpper) { lane.ExactCaseMatches++; } matchLanes.Add(lane); if (filterLowerCase.Length == 1) { return(matchLanes[0]); } if (ctIsUpper || lastWasSeparator) { matchLanes.Add(CreateLane(MatchMode.Acronym, tn)); } } for (int n = 0; n < laneCount; n++) { MatchLane lane = matchLanes [n]; if (lane == null) { continue; } char cfLower = filterLowerCase [lane.MatchIndex]; bool cfIsUpper = cfLower != filter [lane.MatchIndex]; bool match = ctLower == cfLower && !(cfIsUpper && !ctIsUpper); bool exactMatch = match && (cfIsUpper == ctIsUpper); bool wordStartMatch = match && wordStart; if (lane.MatchMode == MatchMode.Substring) { if (wordStartMatch && !LaneExists(MatchMode.Acronym, lane.MatchIndex + 1)) { // Possible acronym match after a substring. Start a new lane. MatchLane newLane = CloneLane(lane); newLane.MatchMode = MatchMode.Acronym; newLane.WordStartsMatched++; newLane.Index++; newLane.Positions [newLane.Index] = tn; newLane.Lengths [newLane.Index] = 1; newLane.MatchIndex++; if (exactMatch) { newLane.ExactCaseMatches++; } matchLanes.Add(newLane); } if (match) { if (!LaneExists(MatchMode.Acronym, lane.MatchIndex)) { // Maybe it is a false substring start, so add a new lane to keep // track of the old lane MatchLane newLane = CloneLane(lane); newLane.MatchMode = MatchMode.Acronym; matchLanes.Add(newLane); if (exactMatch) { newLane.ExactCaseMatches++; } } // Update the current lane lane.Lengths [lane.Index]++; lane.MatchIndex++; } else { if (lane.Lengths [lane.Index] > 1) { lane.MatchMode = MatchMode.Acronym; } else { matchLanes [n] = null; // Kill the lane } } } else if (lane.MatchMode == MatchMode.Acronym && (wordStartMatch || (match && char.IsPunctuation(cfLower)))) { if (!LaneExists(MatchMode.Substring, lane.MatchIndex + 1)) { // This acronym match could be the start of a substring. Create a new lane to track this possibility. MatchLane newLane = CloneLane(lane); newLane.MatchMode = MatchMode.Substring; newLane.Index++; newLane.Positions [newLane.Index] = tn; newLane.Lengths [newLane.Index] = 1; newLane.MatchIndex++; if (exactMatch) { newLane.ExactCaseMatches++; } matchLanes.Add(newLane); if (newLane.MatchIndex == filterLowerCase.Length) { return(newLane); } } if (!LaneExists(MatchMode.Acronym, lane.MatchIndex + 1)) { // Maybe it is a false acronym start, so add a new lane to keep // track of the old lane MatchLane newLane = CloneLane(lane); matchLanes.Add(newLane); // Update the current lane lane.Index++; lane.Positions [lane.Index] = tn; lane.Lengths [lane.Index] = 1; lane.MatchIndex++; if (wordStartMatch) { lane.WordStartsMatched++; } if (exactMatch) { newLane.ExactCaseMatches++; } } } if (lane.MatchIndex == filterLowerCase.Length) { return(lane); } } lastWasSeparator = IsSeparator(ct); tn++; } return(null); }
public void Initialize (MatchLane other) { for (int n=0; n<=other.Index; n++) { Positions [n] = other.Positions [n]; Lengths [n] = other.Lengths [n]; } MatchMode = other.MatchMode; MatchIndex = other.MatchIndex; Index = other.Index; ExactCaseMatches = other.ExactCaseMatches; WordStartsMatched = other.WordStartsMatched; }
MatchLane CloneLane (MatchLane other) { MatchLane lane = GetPoolLane (); lane.Initialize (other); return lane; }
MatchLane GetPoolLane () { if (lanePoolIndex < lanePool.Count) return lanePool [lanePoolIndex++]; MatchLane lane = new MatchLane (filterLowerCase.Length * 2); lanePool.Add (lane); lanePoolIndex++; return lane; }
internal static MatchLane MatchString(string text, string toMatch) { if (text.Length < toMatch.Length) { return(null); } List <MatchLane> matchLanes = null; bool lastWasSeparator = false; int tn = 0; while (tn < text.Length) { char ct = text [tn]; // Keep the lane count in a var because new lanes don't have to be updated // until the next iteration int laneCount = matchLanes != null ? matchLanes.Count : 0; char cm = toMatch [0]; if (char.ToLower(ct) == char.ToLower(cm)) { if (matchLanes == null) { matchLanes = new List <MatchLane> (); } matchLanes.Add(new MatchLane(MatchMode.Substring, tn, text.Length - tn)); if (toMatch.Length == 1) { return(matchLanes[0]); } if (char.IsUpper(ct) || lastWasSeparator) { matchLanes.Add(new MatchLane(MatchMode.Acronym, tn, text.Length - tn)); } } for (int n = 0; n < laneCount; n++) { MatchLane lane = matchLanes [n]; if (lane == null) { continue; } cm = toMatch [lane.MatchIndex]; bool match = char.ToLower(ct) == char.ToLower(cm); bool wordStartMatch = match && (tn == 0 || char.IsUpper(ct) || lastWasSeparator); if (lane.MatchMode == MatchMode.Substring) { if (wordStartMatch) { // Possible acronym match after a substring. Start a new lane. MatchLane newLane = lane.Clone(); newLane.MatchMode = MatchMode.Acronym; newLane.Index++; newLane.Positions [newLane.Index] = tn; newLane.Lengths [newLane.Index] = 1; newLane.MatchIndex++; matchLanes.Add(newLane); } if (match) { // Maybe it is a false substring start, so add a new lane to keep // track of the old lane MatchLane newLane = lane.Clone(); newLane.MatchMode = MatchMode.Acronym; matchLanes.Add(newLane); // Update the current lane lane.Lengths [lane.Index]++; lane.MatchIndex++; } else { if (lane.Lengths [lane.Index] > 1) { lane.MatchMode = MatchMode.Acronym; } else { matchLanes [n] = null; // Kill the lane } } } else if (lane.MatchMode == MatchMode.Acronym) { if (match && lane.Positions [lane.Index] == tn - 1) { // Possible substring match after an acronim. Start a new lane. MatchLane newLane = lane.Clone(); newLane.MatchMode = MatchMode.Substring; newLane.Lengths [newLane.Index]++; newLane.MatchIndex++; matchLanes.Add(newLane); if (newLane.MatchIndex == toMatch.Length) { return(newLane); } } if (wordStartMatch || (match && char.IsPunctuation(cm))) { // Maybe it is a false acronym start, so add a new lane to keep // track of the old lane MatchLane newLane = lane.Clone(); matchLanes.Add(newLane); // Update the current lane lane.Index++; lane.Positions [lane.Index] = tn; lane.Lengths [lane.Index] = 1; lane.MatchIndex++; } } if (lane.MatchIndex == toMatch.Length) { return(lane); } } lastWasSeparator = (ct == '.' || ct == '_' || ct == '-' || ct == ' ' || ct == '/' || ct == '\\'); tn++; } return(null); }