diff --git a/src/app/qt/element/QtSmartSearchBox.cpp b/src/app/qt/element/QtSmartSearchBox.cpp index 08893d26..4e31f9c8 100644 --- a/src/app/qt/element/QtSmartSearchBox.cpp +++ b/src/app/qt/element/QtSmartSearchBox.cpp @@ -822,7 +822,7 @@ void QtSmartSearchBox::clearLineEdit() void QtSmartSearchBox::requestAutoCompletions() const { - MessageSearchAutocomplete("", text().toStdString()).dispatch(); + MessageSearchAutocomplete(text().toStdString()).dispatch(); } void QtSmartSearchBox::hideAutoCompletions() @@ -832,5 +832,10 @@ void QtSmartSearchBox::hideAutoCompletions() std::deque QtSmartSearchBox::getMatchesForInput(const std::string& text) const { - return std::deque(1, SearchMatch(text)); + std::deque matches; + if (text.size()) + { + matches.push_back(SearchMatch(text)); + } + return matches; } diff --git a/src/lib/component/controller/SearchController.cpp b/src/lib/component/controller/SearchController.cpp index d70af241..dc9feaf4 100644 --- a/src/lib/component/controller/SearchController.cpp +++ b/src/lib/component/controller/SearchController.cpp @@ -27,8 +27,8 @@ void SearchController::handleMessage(MessageFind* message) void SearchController::handleMessage(MessageSearchAutocomplete* message) { - LOG_INFO("autocomplete string: \"" + message->word + "\""); - getView()->setAutocompletionList(m_storageAccess->getAutocompletionMatches(message->query, message->word)); + LOG_INFO("autocomplete string: \"" + message->query + "\""); + getView()->setAutocompletionList(m_storageAccess->getAutocompletionMatches(message->query)); } SearchView* SearchController::getView() diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 201bb64a..3d296bf1 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -635,7 +635,7 @@ Id Storage::onTemplateMemberFunctionSpecializationParsed( Id specializedFunctionNodeId = addNodeHierarchyWithDistinctSignature(Node::NODE_FUNCTION, specializedFunction, false); Id edgeId = addEdge(instantiatedFunctionNodeId, specializedFunctionNodeId, Edge::EDGE_TEMPLATE_MEMBER_SPECIALIZATION_OF, location); - + return edgeId; } @@ -770,12 +770,26 @@ Node::NodeType Storage::getNodeTypeForNodeWithId(Id nodeId) const return Node::intToType(m_sqliteStorage.getNodeById(nodeId).type); } -std::vector Storage::getAutocompletionMatches(const std::string& query, const std::string& word) const +std::vector Storage::getAutocompletionMatches(const std::string& query) const { - SearchResults tokenResults = m_tokenIndex.runFuzzySearch(word); + if (query.size() == m_cachedQuery.size() + 1 && query.find(m_cachedQuery) == 0 && m_cachedResults.size()) + { + m_cachedResults = m_tokenIndex.runFuzzySearchCached(query, m_cachedResults); + } + else + { + m_cachedResults = m_tokenIndex.runFuzzySearch(query); + } - std::vector matches = SearchIndex::getMatches(tokenResults, word); - SearchMatch::log(matches, word); + m_cachedQuery = query; + + std::vector matches = SearchIndex::getMatches(m_cachedResults, query); + SearchMatch::log(matches, query); + + if (matches.size() > 100) + { + matches.resize(100); + } for (SearchMatch& match : matches) { diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 31cce696..8b24b6ae 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -134,8 +134,7 @@ public: virtual NameHierarchy getNameHierarchyForNodeWithId(Id nodeId) const; virtual Node::NodeType getNodeTypeForNodeWithId(Id nodeId) const; - virtual std::vector getAutocompletionMatches( - const std::string& query, const std::string& word) const; + virtual std::vector getAutocompletionMatches(const std::string& query) const; virtual std::vector getSearchMatchesForTokenIds(const std::vector& tokenIds) const; virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const; @@ -205,6 +204,9 @@ private: TokenLocationCollection m_errorLocationCollection; std::vector m_errorMessages; + + mutable SearchResults m_cachedResults; + mutable std::string m_cachedQuery; }; #endif // STORAGE_H diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index 6dc25aad..2047ca77 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -32,8 +32,7 @@ public: virtual NameHierarchy getNameHierarchyForNodeWithId(Id id) const = 0; virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const = 0; - virtual std::vector getAutocompletionMatches( - const std::string& query, const std::string& word) const = 0; + virtual std::vector getAutocompletionMatches(const std::string& query) const = 0; virtual std::vector getSearchMatchesForTokenIds(const std::vector& tokenIds) const = 0; virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index 0f5ee366..6cd5218e 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -82,13 +82,11 @@ NameHierarchy StorageAccessProxy::getNameHierarchyForNodeWithId(Id id) const return NameHierarchy(); } -std::vector StorageAccessProxy::getAutocompletionMatches( - const std::string& query, - const std::string& word -) const { +std::vector StorageAccessProxy::getAutocompletionMatches(const std::string& query) const +{ if (hasSubject()) { - return m_subject->getAutocompletionMatches(query, word); + return m_subject->getAutocompletionMatches(query); } return std::vector(); diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index 23fbb547..24b892fd 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -22,7 +22,7 @@ public: virtual NameHierarchy getNameHierarchyForNodeWithId(Id id) const; virtual Node::NodeType getNodeTypeForNodeWithId(Id id) const; - virtual std::vector getAutocompletionMatches(const std::string& query, const std::string& word) const; + virtual std::vector getAutocompletionMatches(const std::string& query) const; virtual std::vector getSearchMatchesForTokenIds(const std::vector& tokenIds) const; virtual std::shared_ptr getGraphForActiveTokenIds(const std::vector& tokenIds) const; diff --git a/src/lib/data/search/SearchIndex.cpp b/src/lib/data/search/SearchIndex.cpp index 94b6c46f..73bba0d2 100644 --- a/src/lib/data/search/SearchIndex.cpp +++ b/src/lib/data/search/SearchIndex.cpp @@ -15,7 +15,7 @@ std::vector SearchIndex::getMatches( for (SearchResultsIterator it = searchResults.begin(); it != searchResults.end(); it++) { - SearchMatch match = it->node->fuzzyMatchData(query, it->parent); + SearchMatch match = it->node->fuzzyMatchData(query, it->parent->getParent()); result.push_back(match); } @@ -171,6 +171,11 @@ SearchResults SearchIndex::runFuzzySearch(const std::string& query) const return m_root.runFuzzySearch(query); } +SearchResults SearchIndex::runFuzzySearchCached(const std::string& query, const SearchResults& searchResults) const +{ + return m_root.runFuzzySearchCached(query, searchResults); +} + std::vector SearchIndex::runFuzzySearchAndGetMatches(const std::string& query) const { return getMatches(runFuzzySearch(query), query); diff --git a/src/lib/data/search/SearchIndex.h b/src/lib/data/search/SearchIndex.h index c071211b..300a653e 100644 --- a/src/lib/data/search/SearchIndex.h +++ b/src/lib/data/search/SearchIndex.h @@ -40,6 +40,7 @@ public: NameHierarchy getNameHierarchyForTokenId(Id tokenId) const; SearchResults runFuzzySearch(const std::string& query) const; + SearchResults runFuzzySearchCached(const std::string& query, const SearchResults& searchResults) const; std::vector runFuzzySearchAndGetMatches(const std::string& query) const; static const std::string DELIMITER; diff --git a/src/lib/data/search/SearchNode.cpp b/src/lib/data/search/SearchNode.cpp index 5938a3cf..2b396d5c 100644 --- a/src/lib/data/search/SearchNode.cpp +++ b/src/lib/data/search/SearchNode.cpp @@ -162,12 +162,32 @@ SearchResults SearchNode::runFuzzySearch(const std::string& query) const FuzzyMap m = n->fuzzyMatchRecursive(query, 0, 0, 0); for (const std::pair& p : m) { - addResultsRecursive(&result, p.first, p.second); + addResultsRecursive(&result, p.first, p.second, n.get()); + } + } + + return result; +} + +SearchResults SearchNode::runFuzzySearchCached(const std::string& query, const SearchResults& searchResults) const +{ + SearchResults result; + + std::set nodes; + for (const SearchResult& r : searchResults) + { + nodes.insert(r.parent); + } + + for (const SearchNode* n : nodes) + { + FuzzyMap m = n->fuzzyMatchRecursive(query, 0, 0, 0); + for (const std::pair& p : m) + { + addResultsRecursive(&result, p.first, p.second, n); } } - // TODO: Currently all matches are added to the ordered set and get compared by their fullName for alphabetical - // order. This could be improved by limiting the number of items to e.g. 100. return result; } @@ -177,26 +197,20 @@ SearchResults SearchNode::runFuzzySearchOnSelf(const std::string& query) const FuzzyMap m = fuzzyMatchRecursive(query, 0, 0, 0); for (const std::pair& p : m) { - addResultsRecursive(&result, p.first, p.second); + addResultsRecursive(&result, p.first, p.second, this); } - // TODO: Currently all matches are added to the ordered set and get compared by their fullName for alphabetical - // order. This could be improved by limiting the number of items to e.g. 100. return result; } -void SearchNode::addResults(SearchResults* results, size_t weight, const SearchNode* node) const -{ - results->insert(SearchResult(weight, node, this)); -} - -void SearchNode::addResultsRecursive(SearchResults* results, size_t weight, const SearchNode* node) const -{ - addResults(results, weight, node); +void SearchNode::addResultsRecursive( + SearchResults* results, size_t weight, const SearchNode* node, const SearchNode* parent +) const { + results->insert(SearchResult(weight, node, parent)); for (std::shared_ptr n: node->m_nodes) { - addResultsRecursive(results, weight, n.get()); + addResultsRecursive(results, weight, n.get(), parent); } } diff --git a/src/lib/data/search/SearchNode.h b/src/lib/data/search/SearchNode.h index 1052a2ac..8ada0ce1 100644 --- a/src/lib/data/search/SearchNode.h +++ b/src/lib/data/search/SearchNode.h @@ -45,10 +45,10 @@ public: const std::set>& getChildren() const; SearchResults runFuzzySearch(const std::string& query) const; + SearchResults runFuzzySearchCached(const std::string& query, const SearchResults& searchResults) const; SearchResults runFuzzySearchOnSelf(const std::string& query) const; - void addResults(SearchResults* results, size_t weight, const SearchNode* node) const; - void addResultsRecursive(SearchResults* results, size_t weight, const SearchNode* node) const; + void addResultsRecursive(SearchResults* results, size_t weight, const SearchNode* node, const SearchNode* parent) const; private: typedef std::multimap FuzzyMap; diff --git a/src/lib/utility/messaging/type/MessageSearchAutocomplete.h b/src/lib/utility/messaging/type/MessageSearchAutocomplete.h index 00106034..53e31a78 100644 --- a/src/lib/utility/messaging/type/MessageSearchAutocomplete.h +++ b/src/lib/utility/messaging/type/MessageSearchAutocomplete.h @@ -7,9 +7,8 @@ class MessageSearchAutocomplete: public Message { public: - MessageSearchAutocomplete(const std::string& query, const std::string& word) + MessageSearchAutocomplete(const std::string& query) : query(query) - , word(word) { } @@ -19,7 +18,6 @@ public: } const std::string query; - const std::string word; }; #endif // MESSAGE_SEARCH_AUTOCOMPLETE_H