From be0085aca9f9eefd431e9f9bd49cb7f424b4fd92 Mon Sep 17 00:00:00 2001 From: Strahinja Val Markovic Date: Wed, 11 Jul 2012 22:08:04 -0700 Subject: [PATCH] CandidateRepository is used for Candidate storage This will make it easy to use the same Candidates for both the IdentifierCompleter and the ClangCompleter, thereby reducing memory consumption and increasing performance. --- cpp/ycm/CandidateRepository.cpp | 78 +++++++++++++++++++++++++++++++++ cpp/ycm/CandidateRepository.h | 60 +++++++++++++++++++++++++ cpp/ycm/IdentifierCompleter.cpp | 37 +++++++--------- cpp/ycm/IdentifierCompleter.h | 14 +++--- 4 files changed, 161 insertions(+), 28 deletions(-) create mode 100644 cpp/ycm/CandidateRepository.cpp create mode 100644 cpp/ycm/CandidateRepository.h diff --git a/cpp/ycm/CandidateRepository.cpp b/cpp/ycm/CandidateRepository.cpp new file mode 100644 index 00000000..5498fd81 --- /dev/null +++ b/cpp/ycm/CandidateRepository.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2011, 2012 Strahinja Val Markovic +// +// This file is part of YouCompleteMe. +// +// YouCompleteMe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// YouCompleteMe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with YouCompleteMe. If not, see . + +#include "CandidateRepository.h" +#include "standard.h" +#include "Utils.h" + +#include + +namespace YouCompleteMe +{ + +boost::mutex CandidateRepository::singleton_mutex_; +CandidateRepository *CandidateRepository::instance_ = NULL; + +CandidateRepository& CandidateRepository::Instance() +{ + boost::lock_guard< boost::mutex > locker( singleton_mutex_ ); + + if ( !instance_ ) + { + static CandidateRepository repo; + instance_ = &repo; + } + + return *instance_; +} + + +std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings( + const std::vector< std::string > &strings) +{ + std::vector< const Candidate* > candidates; + candidates.reserve( strings.size() ); + + { + boost::lock_guard< boost::mutex > locker( holder_mutex_ ); + + foreach ( const std::string &candidate_text, strings ) + { + const Candidate *&candidate = GetValueElseInsert( candidate_holder_, + candidate_text, + NULL ); + if ( !candidate ) + candidate = new Candidate( candidate_text ); + + candidates.push_back( candidate ); + } + } + + return candidates; +} + + +CandidateRepository::~CandidateRepository() +{ + foreach ( const CandidateHolder::value_type &pair, + candidate_holder_ ) + { + delete pair.second; + } +} + +} // namespace YouCompleteMe diff --git a/cpp/ycm/CandidateRepository.h b/cpp/ycm/CandidateRepository.h new file mode 100644 index 00000000..c56be943 --- /dev/null +++ b/cpp/ycm/CandidateRepository.h @@ -0,0 +1,60 @@ +// Copyright (C) 2011, 2012 Strahinja Val Markovic +// +// This file is part of YouCompleteMe. +// +// YouCompleteMe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// YouCompleteMe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with YouCompleteMe. If not, see . + +#ifndef CANDIDATEREPOSITORY_H_K9OVCMHG +#define CANDIDATEREPOSITORY_H_K9OVCMHG + +#include "Candidate.h" + +#include +#include +#include + +#include +#include + +namespace YouCompleteMe +{ + +typedef boost::unordered_map< std::string, const Candidate* > + CandidateHolder; + +class CandidateRepository : boost::noncopyable +{ +public: + static CandidateRepository& Instance(); + + std::vector< const Candidate* > GetCandidatesForStrings( + const std::vector< std::string > &strings ); + +private: + CandidateRepository() {}; + ~CandidateRepository(); + + boost::mutex holder_mutex_; + + static boost::mutex singleton_mutex_; + static CandidateRepository *instance_; + + // This data structure owns all the Candidate pointers + CandidateHolder candidate_holder_; +}; + +} // namespace YouCompleteMe + +#endif /* end of include guard: CANDIDATEREPOSITORY_H_K9OVCMHG */ + diff --git a/cpp/ycm/IdentifierCompleter.cpp b/cpp/ycm/IdentifierCompleter.cpp index faf1ebb0..b0dc7044 100644 --- a/cpp/ycm/IdentifierCompleter.cpp +++ b/cpp/ycm/IdentifierCompleter.cpp @@ -17,6 +17,7 @@ #include "IdentifierCompleter.h" #include "standard.h" +#include "CandidateRepository.h" #include "Utils.h" #include @@ -53,9 +54,17 @@ void ThreadMain( LatestTask &latest_task ) } // unnamed namespace +IdentifierCompleter::IdentifierCompleter() + : candidate_repository_( CandidateRepository::Instance() ), + threading_enabled_( false ) +{ +} + + IdentifierCompleter::IdentifierCompleter( const std::vector< std::string > &candidates ) - : threading_enabled_( false ) + : candidate_repository_( CandidateRepository::Instance() ), + threading_enabled_( false ) { AddCandidatesToDatabase( candidates, "", "", true ); } @@ -65,22 +74,13 @@ IdentifierCompleter::IdentifierCompleter( const std::vector< std::string > &candidates, const std::string &filetype, const std::string &filepath ) - : threading_enabled_( false ) + : candidate_repository_( CandidateRepository::Instance() ), + threading_enabled_( false ) { AddCandidatesToDatabase( candidates, filetype, filepath, true ); } -IdentifierCompleter::~IdentifierCompleter() -{ - foreach ( const CandidateRepository::value_type &pair, - candidate_repository_ ) - { - delete pair.second; - } -} - - // We need this mostly so that we can not use it in tests. Apparently the // GoogleTest framework goes apeshit on us if we enable threads by default. void IdentifierCompleter::EnableThreading() @@ -102,15 +102,12 @@ void IdentifierCompleter::AddCandidatesToDatabase( if ( clear_database ) candidates.clear(); - foreach ( const std::string &candidate_text, new_candidates ) - { - const Candidate *&candidate = GetValueElseInsert( candidate_repository_, - candidate_text, NULL ); - if ( !candidate ) - candidate = new Candidate( candidate_text ); + std::vector< const Candidate* > repository_candidates = + candidate_repository_.GetCandidatesForStrings( new_candidates ); - candidates.push_back( candidate ); - } + candidates.insert( candidates.end(), + repository_candidates.begin(), + repository_candidates.end() ); } diff --git a/cpp/ycm/IdentifierCompleter.h b/cpp/ycm/IdentifierCompleter.h index b9e4e7df..eb785530 100644 --- a/cpp/ycm/IdentifierCompleter.h +++ b/cpp/ycm/IdentifierCompleter.h @@ -18,12 +18,12 @@ #ifndef COMPLETER_H_7AR4UGXE #define COMPLETER_H_7AR4UGXE +// TODO: can we remove the inclusion of Candidate.h now? #include "Candidate.h" #include "ConcurrentLatestValue.h" #include "Future.h" #include -#include #include #include @@ -34,11 +34,11 @@ namespace YouCompleteMe { -typedef boost::python::list Pylist; +class CandidateRepository; // candidate text string -> candidate objects -typedef boost::unordered_map< std::string, const Candidate* > - CandidateRepository; +// typedef boost::unordered_map< std::string, const Candidate* > +// CandidateRepository; // filepath -> *( *candidate ) typedef boost::unordered_map< std::string, @@ -57,12 +57,11 @@ typedef ConcurrentLatestValue< class IdentifierCompleter : boost::noncopyable { public: - IdentifierCompleter() {} + IdentifierCompleter(); IdentifierCompleter( const std::vector< std::string > &candidates ); IdentifierCompleter( const std::vector< std::string > &candidates, const std::string &filetype, const std::string &filepath ); - ~IdentifierCompleter(); void EnableThreading(); @@ -103,8 +102,7 @@ private: // PRIVATE MEMBER VARIABLES ///////////////////////////// - // This data structure owns all the Candidate pointers - CandidateRepository candidate_repository_; + CandidateRepository &candidate_repository_; FiletypeMap filetype_map_;