コード例 #1
0
        MatchLane CloneLane(MatchLane other)
        {
            MatchLane lane = GetPoolLane();

            lane.Initialize(other);
            return(lane);
        }
コード例 #2
0
        MatchLane CreateLane(MatchMode mode, int pos)
        {
            MatchLane lane = GetPoolLane();

            lane.Initialize(mode, pos);
            if (mode == MatchMode.Acronym)
            {
                lane.WordStartsMatched = 1;
            }
            return(lane);
        }
コード例 #3
0
            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);
            }
コード例 #4
0
 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;
 }
コード例 #5
0
        MatchLane GetPoolLane()
        {
            if (lanePoolIndex < lanePool.Count)
            {
                return(lanePool [lanePoolIndex++]);
            }

            MatchLane lane = new MatchLane(filterLowerCase.Length * 2);

            lanePool.Add(lane);
            lanePoolIndex++;
            return(lane);
        }
コード例 #6
0
 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);
 }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
			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;
			}
コード例 #11
0
		MatchLane CloneLane (MatchLane other)
		{
			MatchLane lane = GetPoolLane ();
			lane.Initialize (other);
			return lane;
		}
コード例 #12
0
		MatchLane GetPoolLane ()
		{
			if (lanePoolIndex < lanePool.Count)
				return lanePool [lanePoolIndex++];
			
			MatchLane lane = new MatchLane (filterLowerCase.Length * 2);
			lanePool.Add (lane);
			lanePoolIndex++;
			return lane;
		}
コード例 #13
0
        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);
        }