1
0
mirror of https://github.com/Zygo/bees.git synced 2025-05-17 21:35:45 +02:00

crucible: cache: clean up use of iterators

check_overflow() will invalidate iterators if it decides there are too
many cache entries.

If items are deleted from the cache, search for the inserted item again
to ensure the iterator is valid.

Increase size of timestamp to size_t.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
Zygo Blaxell 2017-01-23 21:12:34 -05:00
parent 5713fcd770
commit 4113a171be

View File

@ -18,7 +18,7 @@ namespace crucible {
public:
using Key = tuple<Arguments...>;
using Func = function<Return(Arguments...)>;
using Time = unsigned;
using Time = size_t;
using Value = pair<Time, Return>;
private:
Func m_fn;
@ -28,7 +28,7 @@ namespace crucible {
size_t m_max_size;
mutex m_mutex;
void check_overflow();
bool check_overflow();
public:
LRUCache(Func f = Func(), size_t max_size = 100);
@ -52,21 +52,24 @@ namespace crucible {
}
template <class Return, class... Arguments>
void
bool
LRUCache<Return, Arguments...>::check_overflow()
{
if (m_map.size() <= m_max_size) return;
vector<pair<Key, Time>> map_contents;
map_contents.reserve(m_map.size());
for (auto i : m_map) {
map_contents.push_back(make_pair(i.first, i.second.first));
if (m_map.size() <= m_max_size) {
return false;
}
sort(map_contents.begin(), map_contents.end(), [](const pair<Key, Time> &a, const pair<Key, Time> &b) {
vector<pair<Key, Time>> key_times;
key_times.reserve(m_map.size());
for (auto i : m_map) {
key_times.push_back(make_pair(i.first, i.second.first));
}
sort(key_times.begin(), key_times.end(), [](const pair<Key, Time> &a, const pair<Key, Time> &b) {
return a.second < b.second;
});
for (size_t i = 0; i < map_contents.size() / 2; ++i) {
m_map.erase(map_contents[i].first);
for (size_t i = 0; i < key_times.size() / 2; ++i) {
m_map.erase(key_times[i].first);
}
return true;
}
template <class Return, class... Arguments>
@ -141,9 +144,14 @@ namespace crucible {
// We hold a lock on this key so we are the ones to insert it
THROW_CHECK0(runtime_error, inserted);
// Release key lock and clean out overflow
// Release key lock, keep the cache lock
key_lock.unlock();
check_overflow();
// Check to see if we have too many items and reduce if so.
if (check_overflow()) {
// Reset iterator
found = m_map.find(k);
}
}
}
@ -207,7 +215,12 @@ namespace crucible {
// Release key lock and clean out overflow
key_lock.unlock();
check_overflow();
// Check to see if we have too many items and reduce if so.
if (check_overflow()) {
// Reset iterator
found = m_map.find(k);
}
}
}