From c7940eb34ff4a75e049a90f755fd7a28a5ce98cd Mon Sep 17 00:00:00 2001 From: malte_langkabel Date: Mon, 18 Apr 2016 14:05:27 +0200 Subject: [PATCH] ui: sorting search results * search results are sorted by: score > length > name * fixed crash that occurred when trying to get a node by id with id == 0 --- src/lib/data/SqliteStorage.cpp | 2 +- src/lib/data/Storage.cpp | 43 +++++++++++++++++++++++++---- src/lib/data/Storage.h | 2 +- src/lib/data/search/SearchIndex.cpp | 13 +++++++-- src/lib/data/search/SearchIndex.h | 1 + src/lib/utility/utilityString.cpp | 16 +++++++++++ src/lib/utility/utilityString.h | 1 + 7 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index bfe2c763..7d704fdd 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -422,7 +422,7 @@ StorageNode SqliteStorage::getNodeById(Id id) const { return getFirstNode("WHERE id == " + std::to_string(id)); } - return StorageNode(0, 0, 0, definitionTypeToInt(DEFINITION_NONE)); + return StorageNode(0, 0, "", definitionTypeToInt(DEFINITION_NONE)); } StorageNode SqliteStorage::getNodeBySerializedName(const std::string& serializedName) const diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 7a982984..016ce05c 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -12,6 +12,7 @@ #include "utility/utilityString.h" #include "utility/Version.h" #include "utility/Cache.h" +#include "utility/utilityString.h" #include "data/graph/token_component/TokenComponentAggregation.h" #include "data/graph/token_component/TokenComponentSignature.h" @@ -55,7 +56,7 @@ void Storage::clear() void Storage::clearCaches() { - m_searchIndex.clear(); + m_elementIndex.clear(); m_fileNodeIds.clear(); m_hierarchyCache.clear(); } @@ -214,9 +215,41 @@ Node::NodeType Storage::getNodeTypeForNodeWithId(Id nodeId) const std::vector Storage::getAutocompletionMatches(const std::string& query) const { + std::vector commandResults = m_commandIndex.search(query, 0); + const size_t maxResultCount = 100; - std::vector results = m_commandIndex.search(query, 0); - utility::append(results, m_searchIndex.search(query, maxResultCount)); + std::vector elementResults = m_elementIndex.search(query, maxResultCount); + std::sort(elementResults.begin(), elementResults.end(), []( + SearchResult a, + SearchResult b) + { + // should a be ranked higher than b? + if (a.score > b.score) + { + return true; + } + else if (a.score == b.score) + { + + if (a.text.size() < b.text.size()) + { + return true; + } + else if (a.text.size() == b.text.size()) + { + // move uppercase letters to higher ascii range + std::string sA = utility::switchCases(a.text); + std::string sB = utility::switchCases(b.text); + return (sA.compare(sB) <= 0); + } + } + return false; + } + ); + + std::vector results; + utility::append(results, commandResults); + utility::append(results, elementResults); std::vector matches; for (size_t i = 0; i < results.size(); i++) @@ -987,9 +1020,9 @@ void Storage::buildSearchIndex() { for (StorageNode node: m_sqliteStorage.getAllNodes()) { - m_searchIndex.addNode(node.id, NameHierarchy::deserialize(node.serializedName)); + m_elementIndex.addNode(node.id, NameHierarchy::deserialize(node.serializedName)); } - m_searchIndex.finishSetup(); + m_elementIndex.finishSetup(); } void Storage::buildHierarchyCache() diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index d5ba53e2..2ca29b67 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -104,7 +104,7 @@ private: void log(std::string type, std::string str, const ParseLocation& location) const; SearchIndex m_commandIndex; - SearchIndex m_searchIndex; + SearchIndex m_elementIndex; SqliteStorage m_sqliteStorage; diff --git a/src/lib/data/search/SearchIndex.cpp b/src/lib/data/search/SearchIndex.cpp index 7ac3013f..589de072 100644 --- a/src/lib/data/search/SearchIndex.cpp +++ b/src/lib/data/search/SearchIndex.cpp @@ -140,9 +140,16 @@ std::vector SearchIndex::search(const std::string& query, size_t m for (size_t j = 0; j < currentIndices.size(); j++) { size_t index = currentIndices[j]; - if (index == 0 || islower(paths[i].text[index-1])) + + if (isupper(paths[i].text[index])) { - camelCaseScore += (isupper(paths[i].text[index]) ? camelCaseBonus : 0); + bool prevIsLower = (index == 0 || islower(paths[i].text[index-1])); + bool nextIsLower = (index + 1 == paths[i].text.size() || islower(paths[i].text[index+1])); + + if (prevIsLower && nextIsLower) + { + camelCaseScore += camelCaseBonus; + } } } @@ -171,6 +178,7 @@ std::vector SearchIndex::search(const std::string& query, size_t m std::vector searchResults; for (size_t i = 0; i < scoredPaths.size() && (maxResultCount == 0 || searchResults.size() < maxResultCount); i++) { + int currentScore = scoredPaths[i].first; std::vector currentPaths; currentPaths.push_back(scoredPaths[i].second); @@ -187,6 +195,7 @@ std::vector SearchIndex::search(const std::string& query, size_t m result.elementIds = currentPath.node->elementIds; result.indices = currentPath.indices; result.text = currentPath.text; + result.score = currentScore; searchResults.push_back(result); } diff --git a/src/lib/data/search/SearchIndex.h b/src/lib/data/search/SearchIndex.h index 4ce59ae6..499e965c 100644 --- a/src/lib/data/search/SearchIndex.h +++ b/src/lib/data/search/SearchIndex.h @@ -16,6 +16,7 @@ struct SearchResult std::string text; std::set elementIds; std::vector indices; + int score; }; class SearchIndex diff --git a/src/lib/utility/utilityString.cpp b/src/lib/utility/utilityString.cpp index 3943b131..44103b77 100644 --- a/src/lib/utility/utilityString.cpp +++ b/src/lib/utility/utilityString.cpp @@ -133,6 +133,22 @@ namespace utility return text.size() >= postfix.size() && text.rfind(postfix) == (text.size() - postfix.size()); } + std::string switchCases(std::string s) + { + for (char& c: s) + { + if (islower(c)) + { + c = toupper(c); + } + else if (isupper(c)) + { + c = tolower(c); + } + } + return s; + } + std::string toUpperCase(const std::string& in) { std::string out; diff --git a/src/lib/utility/utilityString.h b/src/lib/utility/utilityString.h index 184d50bb..501d89a3 100644 --- a/src/lib/utility/utilityString.h +++ b/src/lib/utility/utilityString.h @@ -37,6 +37,7 @@ namespace utility bool isPrefix(const std::string& prefix, const std::string& text); bool isPostfix(const std::string& postfix, const std::string& text); + std::string switchCases(std::string s); std::string toUpperCase(const std::string& in); std::string toLowerCase(const std::string& in); bool equalsCaseInsensitive(const std::string& a, const std::string& b);