示例#1
0
        public NodeQueryMatcher(string query, IEnumerable <string> stringTable)
        {
            this.Query = query;

            this.Words = ParseIntoWords(query);

            for (int i = Words.Count - 1; i >= 0; i--)
            {
                var word = Words[i];
                if (word.Length > 2 && word[0] == '$' && word[1] != '(' && TypeKeyword == null)
                {
                    Words.RemoveAt(i);
                    TypeKeyword = word.Substring(1).ToLowerInvariant();
                    continue;
                }

                if (word.StartsWith("under(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(6, word.Length - 7);
                    Words.RemoveAt(i);
                    UnderMatcher = new NodeQueryMatcher(word, stringTable);
                    continue;
                }
            }

            PrecomputeMatchesInStrings(stringTable);
        }
        private static bool IsUnder(NodeQueryMatcher matcher, SearchResult result)
        {
            if (matcher.UnderProject)
            {
                var project = result.Node.GetNearestParent <Project>();
                if (project != null && matcher.IsMatch(project) != null)
                {
                    return(true);
                }

                var projectEvaluation = result.Node.GetNearestParent <ProjectEvaluation>();
                if (projectEvaluation != null && matcher.IsMatch(projectEvaluation) != null)
                {
                    return(true);
                }

                return(false);
            }

            foreach (var parent in result.Node.GetParentChainExcludingThis())
            {
                if (matcher.IsMatch(parent) != null)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#3
0
        public IEnumerable <SearchResult> FindNodes(string query, CancellationToken cancellationToken)
        {
            var matcher = new NodeQueryMatcher(query, build.StringTable.Instances);

            var resultSet = new List <SearchResult>();

            Visit(build, matcher, resultSet, cancellationToken);
            return(resultSet);
        }
        private static bool IsUnder(NodeQueryMatcher matcher, SearchResult result)
        {
            foreach (var parent in result.Node.GetParentChainExcludingThis())
            {
                if (matcher.IsMatch(parent) != null)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#5
0
        public IEnumerable <SearchResult> FindNodes(string query)
        {
            var matcher = new NodeQueryMatcher(query, build.StringTable.Instances);

            resultSet = new List <SearchResult>();

            var cts = new CancellationTokenSource();

            build.VisitAllChildren <object>(node => Visit(node, matcher, cts), cts.Token);

            return(resultSet);
        }
示例#6
0
        public IEnumerable <SearchResult> FindNodes(string query, CancellationToken cancellationToken)
        {
            var matcher = new NodeQueryMatcher(query, strings, cancellationToken, stringTable);

            var resultSet = new List <SearchResult>();

            foreach (var root in roots)
            {
                Visit(root, matcher, resultSet, cancellationToken);
            }

            return(resultSet);
        }
        public NodeQueryMatcher(string query, IEnumerable <string> stringTable)
        {
            this.Query = query;

            this.Words = ParseIntoWords(query);

            if (Words.Count == 1 &&
                Words[0] is string potentialNodeIndex &&
                potentialNodeIndex.Length > 1 &&
                potentialNodeIndex[0] == '$')
            {
                var nodeIndexText = potentialNodeIndex.Substring(1);
                if (int.TryParse(nodeIndexText, out var nodeIndex))
                {
                    NodeIndex = nodeIndex;
                    Words.RemoveAt(0);
                    return;
                }
            }

            for (int i = Words.Count - 1; i >= 0; i--)
            {
                var word = Words[i];

                if (word == "$time")
                {
                    Words.RemoveAt(i);
                    IncludeDuration = true;
                    continue;
                }

                if (word.Length > 2 && word[0] == '$' && word[1] != '(' && TypeKeyword == null)
                {
                    Words.RemoveAt(i);
                    TypeKeyword = word.Substring(1).ToLowerInvariant();
                    continue;
                }

                if (word.StartsWith("under(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(6, word.Length - 7);
                    Words.RemoveAt(i);
                    UnderMatcher = new NodeQueryMatcher(word, stringTable);
                    continue;
                }
            }

            PrecomputeMatchesInStrings(stringTable);
        }
示例#8
0
        private void Visit(object node, NodeQueryMatcher matcher, CancellationTokenSource cancellationTokenSource)
        {
            if (cancellationTokenSource.IsCancellationRequested)
            {
                return;
            }

            if (resultSet.Count >= maxResults)
            {
                cancellationTokenSource.Cancel();
                return;
            }

            var result = matcher.IsMatch(node);

            if (result != null)
            {
                resultSet.Add(result);
            }
        }
        public NodeQueryMatcher(string query, IEnumerable <string> stringTable)
        {
            this.Query = query;

            this.Words = ParseIntoWords(query);

            if (Words.Count == 1 &&
                Words[0] is string potentialNodeIndex &&
                potentialNodeIndex.Length > 1 &&
                potentialNodeIndex[0] == '$')
            {
                var nodeIndexText = potentialNodeIndex.Substring(1);
                if (int.TryParse(nodeIndexText, out var nodeIndex))
                {
                    NodeIndex = nodeIndex;
                    Words.RemoveAt(0);
                    return;
                }
            }

            for (int i = Words.Count - 1; i >= 0; i--)
            {
                var word = Words[i];

                if (word == "$time" || word == "$duration")
                {
                    Words.RemoveAt(i);
                    IncludeDuration = true;
                    continue;
                }
                else if (word == "$start" || word == "$starttime")
                {
                    Words.RemoveAt(i);
                    IncludeStart = true;
                    continue;
                }
                else if (word == "$end" || word == "$endtime")
                {
                    Words.RemoveAt(i);
                    IncludeEnd = true;
                    continue;
                }

                if (word.Length > 2 && word[0] == '$' && word[1] != '(' && (TypeKeyword == null || !TypeKeyword.Contains(word.Substring(1).ToLowerInvariant())))
                {
                    Words.RemoveAt(i);
                    TypeKeyword = word.Substring(1).ToLowerInvariant();
                    continue;
                }

                if (word.StartsWith("under(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(6, word.Length - 7);
                    Words.RemoveAt(i);
                    var underMatcher = new NodeQueryMatcher(word, stringTable);
                    IncludeMatchers.Add(underMatcher);
                    continue;
                }

                if (word.StartsWith("notunder(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(9, word.Length - 10);
                    Words.RemoveAt(i);
                    var underMatcher = new NodeQueryMatcher(word, stringTable);
                    ExcludeMatchers.Add(underMatcher);
                    continue;
                }

                if (word.StartsWith("name=", StringComparison.OrdinalIgnoreCase) && word.Length > 5)
                {
                    word = word.Substring(5, word.Length - 5);
                    Words.RemoveAt(i);
                    Words.Insert(i, word);
                    nameToSearch = word;
                    continue;
                }

                if (word.StartsWith("value=", StringComparison.OrdinalIgnoreCase) && word.Length > 6)
                {
                    word = word.Substring(6, word.Length - 6);
                    Words.RemoveAt(i);
                    Words.Insert(i, word);
                    valueToSearch = word;
                    continue;
                }
            }

            PrecomputeMatchesInStrings(stringTable);
        }
示例#10
0
        private bool Visit(BaseNode node, NodeQueryMatcher matcher, List <SearchResult> results, CancellationToken cancellationToken)
        {
            var isMatch       = false;
            var containsMatch = false;

            if (cancellationToken.IsCancellationRequested)
            {
                return(false);
            }

            if (resultCount < maxResults)
            {
                var result = matcher.IsMatch(node);
                if (result != null)
                {
                    isMatch = true;
                    lock (results)
                    {
                        results.Add(result);
                        resultCount++;
                    }
                }
            }
            else if (!markResultsInTree)
            {
                // we save a lot of time if we don't have to visit the entire tree to mark results
                // after we've found maximum allowed results
                return(false);
            }

            if (node is TreeNode treeNode && treeNode.HasChildren)
            {
                var children = treeNode.Children;
                if (node is Project)
                {
                    var tasks = new System.Threading.Tasks.Task <List <SearchResult> > [children.Count];

                    for (int i = 0; i < children.Count; i++)
                    {
                        var child = children[i];
                        var task  = TPLTask.Run(() =>
                        {
                            var list = new List <SearchResult>();
                            Visit(child, matcher, list, cancellationToken);
                            return(list);
                        });
                        tasks[i] = task;
                    }

                    TPLTask.WaitAll(tasks);

                    lock (results)
                    {
                        for (int i = 0; i < tasks.Length; i++)
                        {
                            var task    = tasks[i];
                            var subList = task.Result;
                            results.AddRange(subList);
                            containsMatch |= subList.Count > 0;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < children.Count; i++)
                    {
                        var child = children[i];
                        containsMatch |= Visit(child, matcher, results, cancellationToken);
                    }
                }
            }

            // setting these flags on each node is expensive so do it only if the feature is enabled
            if (markResultsInTree)
            {
                node.IsSearchResult       = isMatch;
                node.ContainsSearchResult = containsMatch;
            }

            return(isMatch || containsMatch);
        }
        public NodeQueryMatcher(string query, IEnumerable <string> stringTable)
        {
            query = PreprocessQuery(query);

            this.Query = query;

            var rawWords = TextUtilities.Tokenize(query);

            this.Words = new List <Term>(rawWords.Count);
            foreach (var rawWord in rawWords)
            {
                var trimmed = rawWord.TrimQuotes();
                if (trimmed == rawWord)
                {
                    Words.Add(new Term(rawWord));
                }
                else if (!string.IsNullOrWhiteSpace(trimmed))
                {
                    Words.Add(new Term(trimmed, quotes: true));
                }
            }

            if (Words.Count == 1 &&
                Words[0].Word is string potentialNodeIndex &&
                potentialNodeIndex.Length > 1 &&
                potentialNodeIndex[0] == '$')
            {
                var nodeIndexText = potentialNodeIndex.Substring(1);
                if (int.TryParse(nodeIndexText, out var nodeIndex))
                {
                    NodeIndex = nodeIndex;
                    Words.RemoveAt(0);
                    return;
                }
            }

            for (int i = Words.Count - 1; i >= 0; i--)
            {
                var word = Words[i].Word;

                if (word == "$time" || word == "$duration")
                {
                    Words.RemoveAt(i);
                    IncludeDuration = true;
                    continue;
                }
                else if (word == "$start" || word == "$starttime")
                {
                    Words.RemoveAt(i);
                    IncludeStart = true;
                    continue;
                }
                else if (word == "$end" || word == "$endtime")
                {
                    Words.RemoveAt(i);
                    IncludeEnd = true;
                    continue;
                }

                if (word.Length > 2 && word[0] == '$' && word[1] != '(' && (TypeKeyword == null || !TypeKeyword.Contains(word.Substring(1).ToLowerInvariant())))
                {
                    Words.RemoveAt(i);
                    TypeKeyword = word.Substring(1).ToLowerInvariant();
                    continue;
                }

                if (word.StartsWith("under(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(6, word.Length - 7);
                    Words.RemoveAt(i);
                    var underMatcher = new NodeQueryMatcher(word, stringTable);
                    IncludeMatchers.Add(underMatcher);
                    continue;
                }

                if (word.StartsWith("notunder(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(9, word.Length - 10);
                    Words.RemoveAt(i);
                    var underMatcher = new NodeQueryMatcher(word, stringTable);
                    ExcludeMatchers.Add(underMatcher);
                    continue;
                }

                if (word.StartsWith("project(", StringComparison.OrdinalIgnoreCase) && word.EndsWith(")"))
                {
                    word = word.Substring(8, word.Length - 9);
                    Words.RemoveAt(i);

                    var underMatcher = new NodeQueryMatcher(word, stringTable);
                    underMatcher.UnderProject = true;
                    IncludeMatchers.Add(underMatcher);
                    continue;
                }

                if (word.StartsWith("name=", StringComparison.OrdinalIgnoreCase) && word.Length > 5)
                {
                    word = word.Substring(5, word.Length - 5);
                    Words.RemoveAt(i);
                    Words.Insert(i, new Term(word));
                    nameToSearch = word;
                    continue;
                }

                if (word.StartsWith("value=", StringComparison.OrdinalIgnoreCase) && word.Length > 6)
                {
                    word = word.Substring(6, word.Length - 6);
                    Words.RemoveAt(i);
                    Words.Insert(i, new Term(word));
                    valueToSearch = word;
                    continue;
                }
            }

            PrecomputeMatchesInStrings(stringTable);
        }
示例#12
0
        private bool Visit(BaseNode node, NodeQueryMatcher matcher, List <SearchResult> results, CancellationToken cancellationToken)
        {
            var isMatch       = false;
            var containsMatch = false;

            if (cancellationToken.IsCancellationRequested)
            {
                return(false);
            }

            if (resultCount < maxResults)
            {
                var result = matcher.IsMatch(node);
                if (result != null)
                {
                    isMatch = true;
                    lock (results)
                    {
                        results.Add(result);
                        resultCount++;
                    }
                }
            }
            else if (!markResultsInTree)
            {
                // we save a lot of time if we don't have to visit the entire tree to mark results
                // after we've found maximum allowed results
                return(false);
            }

            if (node is TreeNode treeNode && treeNode.HasChildren)
            {
                var children = treeNode.Children;
                if (node is Project)
                {
                    for (int i = 0; i < children.Count; i++)
                    {
                        var child = children[i];
                        Visit(child, matcher, results, cancellationToken);
                    }

                    containsMatch |= results.Count > 0;
                }
                else
                {
                    for (int i = 0; i < children.Count; i++)
                    {
                        var child = children[i];
                        containsMatch |= Visit(child, matcher, results, cancellationToken);
                    }
                }
            }

            // setting these flags on each node is expensive so do it only if the feature is enabled
            if (markResultsInTree)
            {
                node.IsSearchResult       = isMatch;
                node.ContainsSearchResult = containsMatch;
            }

            return(isMatch || containsMatch);
        }