Use a set of id as key for a the searcher Cache.

It will allow use to cache seacher for multiple zim files.
This commit is contained in:
Matthieu Gautier 2022-03-22 11:42:29 +01:00
parent f5af0633ec
commit fd0edbba80
3 changed files with 33 additions and 3 deletions

View File

@ -59,6 +59,27 @@ bool booksReferToTheSameArchive(const Book& book1, const Book& book2)
&& book1.getPath() == book2.getPath();
}
template<typename Key, typename Value>
class MultiKeyCache: public ConcurrentCache<std::set<Key>, Value>
{
public:
explicit MultiKeyCache(size_t maxEntries)
: ConcurrentCache<std::set<Key>, Value>(maxEntries)
{}
bool drop(const Key& key)
{
std::unique_lock<std::mutex> 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<std::string, Entry> m_books;
using ArchiveCache = ConcurrentCache<std::string, std::shared_ptr<zim::Archive>>;
std::unique_ptr<ArchiveCache> mp_archiveCache;
using SearcherCache = ConcurrentCache<std::string, std::shared_ptr<zim::Searcher>>;
using SearcherCache = MultiKeyCache<std::string, std::shared_ptr<zim::Searcher>>;
std::unique_ptr<SearcherCache> mp_searcherCache;
std::vector<kiwix::Bookmark> m_bookmarks;
Xapian::WritableDatabase m_bookDB;
@ -285,8 +306,9 @@ std::shared_ptr<zim::Archive> Library::getArchiveById(const std::string& id)
std::shared_ptr<zim::Searcher> Library::getSearcherById(const std::string& id)
{
std::set<std::string> ids {id};
try {
return mp_impl->mp_searcherCache->getOrPut(id,
return mp_impl->mp_searcherCache->getOrPut(ids,
[&](){
auto archive = getArchiveById(id);
if(!archive) {

View File

@ -90,7 +90,7 @@ public: // types
return impl_.setMaxSize(new_size);
}
private: // data
protected: // data
Impl impl_;
std::mutex lock_;
};

View File

@ -144,6 +144,14 @@ public: // functions
return previous;
}
std::set<key_t> keys() const {
std::set<key_t> 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());