From ce6f1c729438e278053a8f0e95897d7ca26c7f3a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 1 Feb 2018 17:59:01 -0800 Subject: [PATCH] QueryDatabase::{detailed_names,short_names} -> GetSymbol{DetailedName,ShortName} --- src/messages/text_document_code_action.cc | 5 +- src/messages/workspace_symbol.cc | 23 +++--- src/query.cc | 99 +++++++++++++++-------- src/query.h | 22 ++--- 4 files changed, 90 insertions(+), 59 deletions(-) diff --git a/src/messages/text_document_code_action.cc b/src/messages/text_document_code_action.cc index 78cf6aad..6de17dec 100644 --- a/src/messages/text_document_code_action.cc +++ b/src/messages/text_document_code_action.cc @@ -450,10 +450,11 @@ struct TextDocumentCodeActionHandler std::unordered_set include_absolute_paths; // Find include candidate strings. - for (int i = 0; i < db->detailed_names.size(); ++i) { + for (int i = 0; i < db->symbols.size(); ++i) { if (include_absolute_paths.size() > kMaxResults) break; - if (db->detailed_names[i].find(include_query) == std::string::npos) + if (db->GetSymbolDetailedName(i).find(include_query) == + std::string::npos) continue; optional decl_file_id = diff --git a/src/messages/workspace_symbol.cc b/src/messages/workspace_symbol.cc index 03587256..d2414a01 100644 --- a/src/messages/workspace_symbol.cc +++ b/src/messages/workspace_symbol.cc @@ -124,8 +124,8 @@ gap_penalty(k+1, j) + score[j] : k < j)) The first dimension can be suppressed since we do not need a matching scheme, which reduces the space complexity from O(N*M) to O(M) */ -int FuzzyEvaluate(const std::string& pattern, - const std::string& str, +int FuzzyEvaluate(std::string_view pattern, + std::string_view str, std::vector& score, std::vector& dp) { bool pfirst = true, // aligning the first character of pattern @@ -181,7 +181,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { Out_WorkspaceSymbol out; out.id = request->id; - LOG_S(INFO) << "[querydb] Considering " << db->detailed_names.size() + LOG_S(INFO) << "[querydb] Considering " << db->symbols.size() << " candidates for query " << request->params.query; std::string query = request->params.query; @@ -201,10 +201,11 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { // detailed_names. // Find exact substring matches. - for (int i = 0; i < db->detailed_names.size(); ++i) { - if (db->detailed_names[i].find(query) != std::string::npos) { + for (int i = 0; i < db->symbols.size(); ++i) { + std::string_view detailed_name = db->GetSymbolDetailedName(i); + if (detailed_name.find(query) != std::string::npos) { // Do not show the same entry twice. - if (!inserted_results.insert(db->detailed_names[i]).second) + if (!inserted_results.insert(std::string(detailed_name)).second) continue; if (InsertSymbolIntoResult(db, working_files, db->symbols[i], @@ -224,10 +225,10 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { if (!isspace(c)) query_without_space += c; - for (int i = 0; i < db->short_names.size(); ++i) { - if (SubsequenceMatch(query_without_space, db->short_names[i])) { + for (int i = 0; i < db->symbols.size(); ++i) { + if (SubsequenceMatch(query_without_space, db->GetSymbolShortName(i))) { // Do not show the same entry twice. - if (!inserted_results.insert(db->detailed_names[i]).second) + if (!inserted_results.insert(std::string(db->GetSymbolDetailedName(i))).second) continue; if (InsertSymbolIntoResult(db, working_files, db->symbols[i], @@ -244,7 +245,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { // Sort results with a fuzzy matching algorithm. int longest = 0; for (int i : result_indices) - longest = std::max(longest, int(db->short_names[i].size())); + longest = std::max(longest, int(db->GetSymbolShortName(i).size())); std::vector score(longest); // score for each position std::vector dp( @@ -252,7 +253,7 @@ struct WorkspaceSymbolHandler : BaseMessageHandler { std::vector> permutation(result_indices.size()); for (int i = 0; i < int(result_indices.size()); i++) { permutation[i] = { - FuzzyEvaluate(query, db->short_names[result_indices[i]], score, dp), + FuzzyEvaluate(query, db->GetSymbolShortName(result_indices[i]), score, dp), i}; } std::sort(permutation.begin(), permutation.end(), diff --git a/src/query.cc b/src/query.cc index ad6a7637..da85212b 100644 --- a/src/query.cc +++ b/src/query.cc @@ -790,7 +790,8 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, case SymbolKind::Type: { for (const Usr& usr : to_remove) { QueryType& type = types[usr_to_type[usr].id]; - RemoveSymbol(type.detailed_name_idx); + if (type.symbol_idx != size_t(-1)) + symbols[type.symbol_idx].kind = SymbolKind::Invalid; type.def = nullopt; } break; @@ -798,7 +799,8 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, case SymbolKind::Func: { for (const Usr& usr : to_remove) { QueryFunc& func = funcs[usr_to_func[usr].id]; - RemoveSymbol(func.detailed_name_idx); + if (func.symbol_idx != size_t(-1)) + symbols[func.symbol_idx].kind = SymbolKind::Invalid; func.def = nullopt; } break; @@ -806,7 +808,8 @@ void QueryDatabase::RemoveUsrs(SymbolKind usr_kind, case SymbolKind::Var: { for (const Usr& usr : to_remove) { QueryVar& var = vars[usr_to_var[usr].id]; - RemoveSymbol(var.detailed_name_idx); + if (var.symbol_idx != size_t(-1)) + symbols[var.symbol_idx].kind = SymbolKind::Invalid; var.def = nullopt; } break; @@ -868,8 +871,8 @@ void QueryDatabase::ImportOrUpdate( QueryFile& existing = files[it->second.id]; existing.def = def.value; - UpdateDetailedNames(&existing.detailed_name_idx, SymbolKind::File, - it->second.id, def.value.path, def.value.path); + UpdateSymbols(&existing.symbol_idx, SymbolKind::File, + it->second.id); } } @@ -892,9 +895,8 @@ void QueryDatabase::ImportOrUpdate( continue; existing.def = def.value; - UpdateDetailedNames(&existing.detailed_name_idx, SymbolKind::Type, - it->second.id, std::string(def.value.ShortName()), - def.value.detailed_name); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Type, + it->second.id); } } @@ -917,9 +919,8 @@ void QueryDatabase::ImportOrUpdate( continue; existing.def = def.value; - UpdateDetailedNames(&existing.detailed_name_idx, SymbolKind::Func, - it->second.id, std::string(def.value.ShortName()), - def.value.detailed_name); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Func, + it->second.id); } } @@ -943,34 +944,68 @@ void QueryDatabase::ImportOrUpdate( existing.def = def.value; if (!def.value.is_local()) - UpdateDetailedNames(&existing.detailed_name_idx, SymbolKind::Var, - it->second.id, std::string(def.value.ShortName()), - def.value.detailed_name); + UpdateSymbols(&existing.symbol_idx, SymbolKind::Var, + it->second.id); } } -void QueryDatabase::UpdateDetailedNames(size_t* qualified_name_index, - SymbolKind kind, - size_t symbol_index, - const std::string& short_name, - const std::string& detailed_name) { - if (*qualified_name_index == -1) { - short_names.push_back(short_name); - detailed_names.push_back(detailed_name); - symbols.push_back(SymbolIdx(kind, symbol_index)); - *qualified_name_index = detailed_names.size() - 1; - } else { - short_names[*qualified_name_index] = short_name; - detailed_names[*qualified_name_index] = detailed_name; +void QueryDatabase::UpdateSymbols(size_t* symbol_idx, + SymbolKind kind, + size_t idx) { + if (*symbol_idx == -1) { + *symbol_idx = symbols.size(); + symbols.push_back(SymbolIdx(kind, idx)); } } -void QueryDatabase::RemoveSymbol(size_t idx) { - if (idx != size_t(-1)) { - symbols[idx].kind = SymbolKind::Invalid; - short_names[idx].clear(); - detailed_names[idx].clear(); +std::string_view QueryDatabase::GetSymbolDetailedName(size_t symbol_idx) const { + size_t idx = symbols[symbol_idx].idx; + switch (symbols[symbol_idx].kind) { + default: + break; + case SymbolKind::File: + if (files[idx].def) + return files[idx].def->path; + break; + case SymbolKind::Func: + if (funcs[idx].def) + return funcs[idx].def->detailed_name; + break; + case SymbolKind::Type: + if (types[idx].def) + return types[idx].def->detailed_name; + break; + case SymbolKind::Var: + if (vars[idx].def) + return vars[idx].def->detailed_name; + break; } + return ""; +} + +std::string_view QueryDatabase::GetSymbolShortName(size_t symbol_idx) const { + size_t idx = symbols[symbol_idx].idx; + switch (symbols[symbol_idx].kind) { + default: + break; + case SymbolKind::File: + if (files[idx].def) + return files[idx].def->path; + break; + case SymbolKind::Func: + if (funcs[idx].def) + return funcs[idx].def->ShortName(); + break; + case SymbolKind::Type: + if (types[idx].def) + return types[idx].def->ShortName(); + break; + case SymbolKind::Var: + if (vars[idx].def) + return vars[idx].def->ShortName(); + break; + } + return ""; } TEST_SUITE("query") { diff --git a/src/query.h b/src/query.h index 1b2c8d8b..3abf8f7e 100644 --- a/src/query.h +++ b/src/query.h @@ -211,7 +211,7 @@ struct QueryFile { using DefUpdate = WithFileContent; optional def; - size_t detailed_name_idx = (size_t)-1; + size_t symbol_idx = (size_t)-1; explicit QueryFile(const std::string& path) { def = Def(); @@ -241,7 +241,7 @@ struct QueryType { std::vector derived; std::vector instances; std::vector uses; - size_t detailed_name_idx = (size_t)-1; + size_t symbol_idx = (size_t)-1; explicit QueryType(const Usr& usr) : usr(usr) {} }; @@ -262,7 +262,7 @@ struct QueryFunc { std::vector declarations; std::vector derived; std::vector callers; - size_t detailed_name_idx = (size_t)-1; + size_t symbol_idx = (size_t)-1; explicit QueryFunc(const Usr& usr) : usr(usr) {} }; @@ -278,7 +278,7 @@ struct QueryVar { optional def; std::vector declarations; std::vector uses; - size_t detailed_name_idx = (size_t)-1; + size_t symbol_idx = (size_t)-1; explicit QueryVar(const Usr& usr) : usr(usr) {} }; @@ -361,10 +361,7 @@ MAKE_HASHABLE(NormalizedPath, t.path); // The query database is heavily optimized for fast queries. It is stored // in-memory. struct QueryDatabase { - // Indicies between lookup vectors are related to symbols, ie, index 5 in - // |detailed_names| matches index 5 in |symbols|. - std::vector detailed_names; - std::vector short_names; + // All File/Func/Type/Var symbols. std::vector symbols; // Raw data storage. Accessible via SymbolIdx instances. @@ -387,12 +384,9 @@ struct QueryDatabase { void ImportOrUpdate(const std::vector& updates); void ImportOrUpdate(const std::vector& updates); void ImportOrUpdate(const std::vector& updates); - void UpdateDetailedNames(size_t* qualified_name_index, - SymbolKind kind, - size_t symbol_index, - const std::string& short_name, - const std::string& detailed_name); - void RemoveSymbol(size_t idx); + void UpdateSymbols(size_t* symbol_idx, SymbolKind kind, size_t idx); + std::string_view GetSymbolDetailedName(size_t symbol_idx) const; + std::string_view GetSymbolShortName(size_t symbol_idx) const; // Query the indexing structure to look up symbol id for given Usr. optional GetQueryFileIdFromPath(const std::string& path);