diff --git a/src/library.cpp b/src/library.cpp index 4369f58a7..d57b4d450 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -59,6 +59,27 @@ bool booksReferToTheSameArchive(const Book& book1, const Book& book2) && book1.getPath() == book2.getPath(); } +template +class MultiKeyCache: public ConcurrentCache, Value> +{ + public: + explicit MultiKeyCache(size_t maxEntries) + : ConcurrentCache, Value>(maxEntries) + {} + + bool drop(const Key& key) + { + std::unique_lock l(this->lock_); + bool removed = false; + for(auto& cache_key: this->impl_.keys()) { + if(cache_key.find(key)!=cache_key.end()) { + removed |= this->impl_.drop(cache_key); + } + } + return removed; + } +}; + } // unnamed namespace struct Library::Impl @@ -72,7 +93,7 @@ struct Library::Impl std::map m_books; using ArchiveCache = ConcurrentCache>; std::unique_ptr mp_archiveCache; - using SearcherCache = ConcurrentCache>; + using SearcherCache = MultiKeyCache>; std::unique_ptr mp_searcherCache; std::vector m_bookmarks; Xapian::WritableDatabase m_bookDB; @@ -285,8 +306,9 @@ std::shared_ptr Library::getArchiveById(const std::string& id) std::shared_ptr Library::getSearcherById(const std::string& id) { + std::set ids {id}; try { - return mp_impl->mp_searcherCache->getOrPut(id, + return mp_impl->mp_searcherCache->getOrPut(ids, [&](){ auto archive = getArchiveById(id); if(!archive) { diff --git a/src/tools/concurrent_cache.h b/src/tools/concurrent_cache.h index 4c5c324aa..3ee8ce60e 100644 --- a/src/tools/concurrent_cache.h +++ b/src/tools/concurrent_cache.h @@ -90,7 +90,7 @@ public: // types return impl_.setMaxSize(new_size); } -private: // data +protected: // data Impl impl_; std::mutex lock_; }; diff --git a/src/tools/lrucache.h b/src/tools/lrucache.h index 08fa1b4d8..06ee9c992 100644 --- a/src/tools/lrucache.h +++ b/src/tools/lrucache.h @@ -144,6 +144,14 @@ public: // functions return previous; } + std::set keys() const { + std::set keys; + for(auto& item:_cache_items_map) { + keys.insert(item.first); + } + return keys; + } + private: // functions void putMissing(const key_t& key, const value_t& value) { assert(_cache_items_map.find(key) == _cache_items_map.end());