PCB Environment 2
Loading...
Searching...
No Matches
ActionCache.hpp
1#ifndef GYM_PCB_RL_ACTIONCACHE_H
2#define GYM_PCB_RL_ACTIONCACHE_H
3
4#include "RL/Action.hpp"
5#include <list>
6#include <map>
7
8template<class Data> class ActionCache
9{
10public:
11 ActionCache(uint size, uint maxOversize) : mSize(size), mTriggerSize(size + maxOversize) { }
12 using Ref = Action::CacheRef;
13 using List = std::list<std::pair<Ref, Data>>;
14 Data *load(Ref);
15 void store(Ref, const Data&);
16 void clear();
17 void shrink();
18private:
19 std::map<Ref, typename List::iterator> mLUT;
20 List mLRU;
21 uint mSize;
22 uint mTriggerSize;
23};
24
25template<class Data> Data *ActionCache<Data>::load(ActionCache::Ref ref)
26{
27 auto M = mLUT.find(ref);
28 if (M == mLUT.end())
29 return 0;
30 mLRU.splice(mLRU.end(), mLRU, M->second);
31 return &M->second->second;
32}
33
34template<class Data> void ActionCache<Data>::store(ActionCache::Ref ref, const Data &data)
35{
36 auto M = mLUT.find(ref);
37 if (M != mLUT.end()) {
38 M->second->second = data;
39 } else {
40 mLRU.emplace_back(ref, data);
41 mLUT[ref] = --mLRU.end();
42 }
43 if (mLRU.size() >= mTriggerSize)
44 shrink();
45}
46
47template<class Data> void ActionCache<Data>::shrink()
48{
49 if (mLRU.size() <= mSize)
50 return;
51 uint N = mLRU.size() - mSize;
52 for (auto I = mLRU.begin(); I != mLRU.end() && N; --N) {
53 mLUT.erase(I->first);
54 I = mLRU.erase(I);
55 }
56}
57
58template<class Data> void ActionCache<Data>::clear()
59{
60 mLUT.clear();
61 mLRU.clear();
62}
63
64#endif // GYM_PCB_RL_ACTIONCACHE_H