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); }
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); }
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); }
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); }
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); }
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); }
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); }