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
This commit is contained in:
malte_langkabel
2016-04-18 14:05:27 +02:00
parent 325bc6ac83
commit c7940eb34f
7 changed files with 69 additions and 9 deletions
+1 -1
View File
@@ -422,7 +422,7 @@ StorageNode SqliteStorage::getNodeById(Id id) const
{ {
return getFirstNode("WHERE id == " + std::to_string(id)); 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 StorageNode SqliteStorage::getNodeBySerializedName(const std::string& serializedName) const
+38 -5
View File
@@ -12,6 +12,7 @@
#include "utility/utilityString.h" #include "utility/utilityString.h"
#include "utility/Version.h" #include "utility/Version.h"
#include "utility/Cache.h" #include "utility/Cache.h"
#include "utility/utilityString.h"
#include "data/graph/token_component/TokenComponentAggregation.h" #include "data/graph/token_component/TokenComponentAggregation.h"
#include "data/graph/token_component/TokenComponentSignature.h" #include "data/graph/token_component/TokenComponentSignature.h"
@@ -55,7 +56,7 @@ void Storage::clear()
void Storage::clearCaches() void Storage::clearCaches()
{ {
m_searchIndex.clear(); m_elementIndex.clear();
m_fileNodeIds.clear(); m_fileNodeIds.clear();
m_hierarchyCache.clear(); m_hierarchyCache.clear();
} }
@@ -214,9 +215,41 @@ Node::NodeType Storage::getNodeTypeForNodeWithId(Id nodeId) const
std::vector<SearchMatch> Storage::getAutocompletionMatches(const std::string& query) const std::vector<SearchMatch> Storage::getAutocompletionMatches(const std::string& query) const
{ {
std::vector<SearchResult> commandResults = m_commandIndex.search(query, 0);
const size_t maxResultCount = 100; const size_t maxResultCount = 100;
std::vector<SearchResult> results = m_commandIndex.search(query, 0); std::vector<SearchResult> elementResults = m_elementIndex.search(query, maxResultCount);
utility::append(results, m_searchIndex.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<SearchResult> results;
utility::append(results, commandResults);
utility::append(results, elementResults);
std::vector<SearchMatch> matches; std::vector<SearchMatch> matches;
for (size_t i = 0; i < results.size(); i++) for (size_t i = 0; i < results.size(); i++)
@@ -987,9 +1020,9 @@ void Storage::buildSearchIndex()
{ {
for (StorageNode node: m_sqliteStorage.getAllNodes()) 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() void Storage::buildHierarchyCache()
+1 -1
View File
@@ -104,7 +104,7 @@ private:
void log(std::string type, std::string str, const ParseLocation& location) const; void log(std::string type, std::string str, const ParseLocation& location) const;
SearchIndex m_commandIndex; SearchIndex m_commandIndex;
SearchIndex m_searchIndex; SearchIndex m_elementIndex;
SqliteStorage m_sqliteStorage; SqliteStorage m_sqliteStorage;
+11 -2
View File
@@ -140,9 +140,16 @@ std::vector<SearchResult> SearchIndex::search(const std::string& query, size_t m
for (size_t j = 0; j < currentIndices.size(); j++) for (size_t j = 0; j < currentIndices.size(); j++)
{ {
size_t index = currentIndices[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<SearchResult> SearchIndex::search(const std::string& query, size_t m
std::vector<SearchResult> searchResults; std::vector<SearchResult> searchResults;
for (size_t i = 0; i < scoredPaths.size() && (maxResultCount == 0 || searchResults.size() < maxResultCount); i++) for (size_t i = 0; i < scoredPaths.size() && (maxResultCount == 0 || searchResults.size() < maxResultCount); i++)
{ {
int currentScore = scoredPaths[i].first;
std::vector<Path> currentPaths; std::vector<Path> currentPaths;
currentPaths.push_back(scoredPaths[i].second); currentPaths.push_back(scoredPaths[i].second);
@@ -187,6 +195,7 @@ std::vector<SearchResult> SearchIndex::search(const std::string& query, size_t m
result.elementIds = currentPath.node->elementIds; result.elementIds = currentPath.node->elementIds;
result.indices = currentPath.indices; result.indices = currentPath.indices;
result.text = currentPath.text; result.text = currentPath.text;
result.score = currentScore;
searchResults.push_back(result); searchResults.push_back(result);
} }
+1
View File
@@ -16,6 +16,7 @@ struct SearchResult
std::string text; std::string text;
std::set<Id> elementIds; std::set<Id> elementIds;
std::vector<size_t> indices; std::vector<size_t> indices;
int score;
}; };
class SearchIndex class SearchIndex
+16
View File
@@ -133,6 +133,22 @@ namespace utility
return text.size() >= postfix.size() && text.rfind(postfix) == (text.size() - postfix.size()); 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 toUpperCase(const std::string& in)
{ {
std::string out; std::string out;
+1
View File
@@ -37,6 +37,7 @@ namespace utility
bool isPrefix(const std::string& prefix, const std::string& text); bool isPrefix(const std::string& prefix, const std::string& text);
bool isPostfix(const std::string& postfix, 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 toUpperCase(const std::string& in);
std::string toLowerCase(const std::string& in); std::string toLowerCase(const std::string& in);
bool equalsCaseInsensitive(const std::string& a, const std::string& b); bool equalsCaseInsensitive(const std::string& a, const std::string& b);