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:
parent
5713fcd770
commit
4113a171be
@ -18,7 +18,7 @@ namespace crucible {
|
|||||||
public:
|
public:
|
||||||
using Key = tuple<Arguments...>;
|
using Key = tuple<Arguments...>;
|
||||||
using Func = function<Return(Arguments...)>;
|
using Func = function<Return(Arguments...)>;
|
||||||
using Time = unsigned;
|
using Time = size_t;
|
||||||
using Value = pair<Time, Return>;
|
using Value = pair<Time, Return>;
|
||||||
private:
|
private:
|
||||||
Func m_fn;
|
Func m_fn;
|
||||||
@ -28,7 +28,7 @@ namespace crucible {
|
|||||||
size_t m_max_size;
|
size_t m_max_size;
|
||||||
mutex m_mutex;
|
mutex m_mutex;
|
||||||
|
|
||||||
void check_overflow();
|
bool check_overflow();
|
||||||
public:
|
public:
|
||||||
LRUCache(Func f = Func(), size_t max_size = 100);
|
LRUCache(Func f = Func(), size_t max_size = 100);
|
||||||
|
|
||||||
@ -52,21 +52,24 @@ namespace crucible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class Return, class... Arguments>
|
template <class Return, class... Arguments>
|
||||||
void
|
bool
|
||||||
LRUCache<Return, Arguments...>::check_overflow()
|
LRUCache<Return, Arguments...>::check_overflow()
|
||||||
{
|
{
|
||||||
if (m_map.size() <= m_max_size) return;
|
if (m_map.size() <= m_max_size) {
|
||||||
vector<pair<Key, Time>> map_contents;
|
return false;
|
||||||
map_contents.reserve(m_map.size());
|
|
||||||
for (auto i : m_map) {
|
|
||||||
map_contents.push_back(make_pair(i.first, i.second.first));
|
|
||||||
}
|
}
|
||||||
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;
|
return a.second < b.second;
|
||||||
});
|
});
|
||||||
for (size_t i = 0; i < map_contents.size() / 2; ++i) {
|
for (size_t i = 0; i < key_times.size() / 2; ++i) {
|
||||||
m_map.erase(map_contents[i].first);
|
m_map.erase(key_times[i].first);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Return, class... Arguments>
|
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
|
// We hold a lock on this key so we are the ones to insert it
|
||||||
THROW_CHECK0(runtime_error, inserted);
|
THROW_CHECK0(runtime_error, inserted);
|
||||||
|
|
||||||
// Release key lock and clean out overflow
|
// Release key lock, keep the cache lock
|
||||||
key_lock.unlock();
|
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
|
// Release key lock and clean out overflow
|
||||||
key_lock.unlock();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user