diff --git a/src/library.cpp b/src/library.cpp index 7c60fa8aa..b28533a4a 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -151,6 +152,10 @@ bool Library::addBook(const Book& book) auto& newEntry = mp_impl->m_books[book.getId()]; static_cast(newEntry) = book; newEntry.lastUpdatedRevision = mp_impl->m_revision; + size_t new_cache_size = std::ceil(mp_impl->getBookCount(true, true)*0.1); + if (getEnvVar("ARCHIVE_CACHE_SIZE", -1) <= 0) { + mp_impl->mp_archiveCache->setMaxSize(new_cache_size); + } return true; } } @@ -184,6 +189,12 @@ bool Library::removeBookById(const std::string& id) std::lock_guard lock(m_mutex); mp_impl->m_bookDB.delete_document("Q" + id); dropCache(id); + // We do not change the cache size here + // Most of the time, the book is remove in case of library refresh, it is + // often associated with addBook calls (which will properly set the cache size) + // Having a too big cache is not a problem here (or it would have been before) + // (And setMaxSize doesn't actually reduce the cache size, extra cached items + // will be removed in put or getOrPut). return mp_impl->m_books.erase(id) == 1; } diff --git a/src/tools/concurrent_cache.h b/src/tools/concurrent_cache.h index 1b5175b2e..4c5c324aa 100644 --- a/src/tools/concurrent_cache.h +++ b/src/tools/concurrent_cache.h @@ -1,3 +1,4 @@ + /* * Copyright (C) 2021 Matthieu Gautier * Copyright (C) 2020 Veloman Yunkan @@ -84,6 +85,11 @@ public: // types return impl_.drop(key); } + size_t setMaxSize(size_t new_size) { + std::unique_lock l(lock_); + return impl_.setMaxSize(new_size); + } + private: // data Impl impl_; std::mutex lock_; diff --git a/src/tools/lrucache.h b/src/tools/lrucache.h index bd90c3128..08fa1b4d8 100644 --- a/src/tools/lrucache.h +++ b/src/tools/lrucache.h @@ -138,12 +138,18 @@ public: // functions return _cache_items_map.size(); } + size_t setMaxSize(size_t new_size) { + size_t previous = _max_size; + _max_size = new_size; + return previous; + } + private: // functions void putMissing(const key_t& key, const value_t& value) { assert(_cache_items_map.find(key) == _cache_items_map.end()); _cache_items_list.push_front(key_value_pair_t(key, value)); _cache_items_map[key] = _cache_items_list.begin(); - if (_cache_items_map.size() > _max_size) { + while (_cache_items_map.size() > _max_size) { _cache_items_map.erase(_cache_items_list.back().first); _cache_items_list.pop_back(); }