1
0

IdentifierDatabase.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Copyright (C) 2013 Google Inc.
  2. //
  3. // This file is part of YouCompleteMe.
  4. //
  5. // YouCompleteMe is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // YouCompleteMe is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
  17. #include "IdentifierDatabase.h"
  18. #include "standard.h"
  19. #include "Candidate.h"
  20. #include "CandidateRepository.h"
  21. #include "IdentifierUtils.h"
  22. #include "Result.h"
  23. #include "Utils.h"
  24. #include <boost/thread/locks.hpp>
  25. #include <boost/unordered_set.hpp>
  26. #include <boost/algorithm/string.hpp>
  27. #include <boost/algorithm/cxx11/any_of.hpp>
  28. using boost::algorithm::any_of;
  29. using boost::algorithm::is_upper;
  30. namespace YouCompleteMe {
  31. IdentifierDatabase::IdentifierDatabase()
  32. : candidate_repository_( CandidateRepository::Instance() ) {
  33. }
  34. void IdentifierDatabase::AddIdentifiers(
  35. const FiletypeIdentifierMap &filetype_identifier_map ) {
  36. boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
  37. foreach ( const FiletypeIdentifierMap::value_type & filetype_and_map,
  38. filetype_identifier_map ) {
  39. foreach( const FilepathToIdentifiers::value_type & filepath_and_identifiers,
  40. filetype_and_map.second ) {
  41. AddIdentifiersNoLock( filepath_and_identifiers.second,
  42. filetype_and_map.first,
  43. filepath_and_identifiers.first );
  44. }
  45. }
  46. }
  47. void IdentifierDatabase::AddIdentifiers(
  48. const std::vector< std::string > &new_candidates,
  49. const std::string &filetype,
  50. const std::string &filepath ) {
  51. boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
  52. AddIdentifiersNoLock( new_candidates, filetype, filepath );
  53. }
  54. void IdentifierDatabase::ClearCandidatesStoredForFile(
  55. const std::string &filetype,
  56. const std::string &filepath ) {
  57. boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
  58. GetCandidateSet( filetype, filepath ).clear();
  59. }
  60. void IdentifierDatabase::ResultsForQueryAndType(
  61. const std::string &query,
  62. const std::string &filetype,
  63. std::vector< Result > &results ) const {
  64. FiletypeCandidateMap::const_iterator it;
  65. {
  66. boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
  67. it = filetype_candidate_map_.find( filetype );
  68. if ( it == filetype_candidate_map_.end() || query.empty() )
  69. return;
  70. }
  71. Bitset query_bitset = LetterBitsetFromString( query );
  72. bool query_has_uppercase_letters = any_of( query, is_upper() );
  73. boost::unordered_set< const Candidate * > seen_candidates;
  74. seen_candidates.reserve( candidate_repository_.NumStoredCandidates() );
  75. {
  76. boost::lock_guard< boost::mutex > locker( filetype_candidate_map_mutex_ );
  77. foreach ( const FilepathToCandidates::value_type & path_and_candidates,
  78. *it->second ) {
  79. foreach ( const Candidate * candidate, *path_and_candidates.second ) {
  80. if ( ContainsKey( seen_candidates, candidate ) )
  81. continue;
  82. else
  83. seen_candidates.insert( candidate );
  84. if ( !candidate->MatchesQueryBitset( query_bitset ) )
  85. continue;
  86. Result result = candidate->QueryMatchResult(
  87. query, query_has_uppercase_letters );
  88. if ( result.IsSubsequence() )
  89. results.push_back( result );
  90. }
  91. }
  92. }
  93. std::sort( results.begin(), results.end() );
  94. }
  95. // WARNING: You need to hold the filetype_candidate_map_mutex_ before calling
  96. // this function and while using the returned set.
  97. std::set< const Candidate * > &IdentifierDatabase::GetCandidateSet(
  98. const std::string &filetype,
  99. const std::string &filepath ) {
  100. boost::shared_ptr< FilepathToCandidates > &path_to_candidates =
  101. filetype_candidate_map_[ filetype ];
  102. if ( !path_to_candidates )
  103. path_to_candidates.reset( new FilepathToCandidates() );
  104. boost::shared_ptr< std::set< const Candidate * > > &candidates =
  105. ( *path_to_candidates )[ filepath ];
  106. if ( !candidates )
  107. candidates.reset( new std::set< const Candidate * >() );
  108. return *candidates;
  109. }
  110. // WARNING: You need to hold the filetype_candidate_map_mutex_ before calling
  111. // this function and while using the returned set.
  112. void IdentifierDatabase::AddIdentifiersNoLock(
  113. const std::vector< std::string > &new_candidates,
  114. const std::string &filetype,
  115. const std::string &filepath ) {
  116. std::set< const Candidate *> &candidates =
  117. GetCandidateSet( filetype, filepath );
  118. std::vector< const Candidate * > repository_candidates =
  119. candidate_repository_.GetCandidatesForStrings( new_candidates );
  120. candidates.insert( repository_candidates.begin(),
  121. repository_candidates.end() );
  122. }
  123. } // namespace YouCompleteMe