58 #ifndef AGS_SHARED_UTIL_RESOURCE_CACHE_H 59 #define AGS_SHARED_UTIL_RESOURCE_CACHE_H 61 #include "common/std/list.h" 62 #include "common/std/map.h" 63 #include "ags/shared/util/string.h" 70 typename TSize = size_t,
typename HashFn = std::hash<TKey> >
77 kCacheItem_Locked = 0x0001,
82 kCacheItem_External = 0x0002,
86 : _maxSize(max_size), _sectionLocked(_mru.
end()) {}
89 inline size_t GetMaxCacheSize()
const {
return _maxSize; }
91 inline size_t GetCacheSize()
const {
return _cacheSize; }
93 inline size_t GetLockedSize()
const {
return _lockedSize; }
95 inline size_t GetExternalSize()
const {
return _externalSize; }
98 void SetMaxCacheSize(TSize size) {
104 bool Exists(
const TKey &key)
const {
105 return _storage.find(key) != _storage.end();
110 const TValue &Get(
const TKey &key) {
111 auto it = _storage.find(key);
112 if (it == _storage.end())
116 const auto &item = it->second;
117 if ((item.Flags & kCacheItem_Locked) == 0)
118 _mru.splice(_mru.
begin(), _mru, item.MruIt);
125 void Put(
const TKey &key,
const TValue &value, uint32_t flags = 0u) {
128 auto it = _storage.find(key);
129 if (it != _storage.end()) {
133 PutImpl(key, TValue(value), flags);
136 void Put(
const TKey &key, TValue &&value, uint32_t flags = 0u) {
139 auto it = _storage.find(key);
140 if (it != _storage.end()) {
149 void Lock(
const TKey &key) {
150 auto it = _storage.find(key);
151 if (it == _storage.end())
153 auto &item = it->second;
154 if ((item.Flags & kCacheItem_Locked) != 0)
158 item.Flags |= kCacheItem_Locked;
159 _mru.splice(_sectionLocked, _mru, item.MruIt);
160 _sectionLocked = item.MruIt;
161 _lockedSize += item.Size;
166 void Release(
const TKey &key) {
167 auto it = _storage.find(key);
168 if (it == _storage.end())
171 auto &item = it->second;
172 if ((item.Flags & kCacheItem_External) != 0)
174 if ((item.Flags & kCacheItem_Locked) == 0)
178 item.Flags &= ~kCacheItem_Locked;
179 if (_sectionLocked == item.MruIt)
180 _sectionLocked = std::next(item.MruIt);
181 _mru.splice(_mru.
begin(), _mru, item.MruIt);
182 _lockedSize -= item.Size;
186 void Dispose(
const TKey &key) {
187 auto it = _storage.find(key);
188 if (it == _storage.end())
194 TValue Remove(
const TKey &key) {
195 auto it = _storage.find(key);
196 if (it == _storage.end())
198 TValue value =
std::move(it->second.Value);
204 void DisposeFreeItems() {
205 for (
auto mru_it = _sectionLocked; mru_it != _mru.
end(); ++mru_it) {
206 auto it = _storage.find(*mru_it);
207 assert(it != _storage.end());
208 auto &item = it->second;
209 _cacheSize -= item.Size;
219 _sectionLocked = _mru.
end();
243 TItem(
const TMruIt &mru_it,
const TValue &value,
const TSize size, uint32_t flags)
244 : MruIt(mru_it), Value(value), Size(size), Flags(flags) {}
245 TItem(
const TMruIt &mru_it, TValue &&value,
const TSize size, uint32_t flags)
246 : MruIt(mru_it), Value(
std::move(value)), Size(size), Flags(flags) {}
247 TItem &operator=(
const TItem &item) =
default;
253 virtual TSize CalcSize(
const TValue &item) = 0;
259 void PutImpl(
const TKey &key, TValue &&value, uint32_t flags) {
261 TSize size = CalcSize(value);
265 if ((flags & kCacheItem_External) == 0) {
267 if (_cacheSize + size > _maxSize)
272 flags |= kCacheItem_Locked;
273 _externalSize += size;
277 TMruIt mru_it = _mru.end();
279 if ((flags & kCacheItem_External) == 0) {
280 if ((flags & kCacheItem_Locked) == 0) {
282 mru_it = _mru.insert(_mru.begin(), key);
285 mru_it = _mru.insert(_sectionLocked, key);
286 _sectionLocked = mru_it;
294 void RemoveImpl(
typename TStorage::iterator it) {
295 auto &item = it->second;
297 if ((item.Flags & kCacheItem_External) == 0) {
298 TMruIt mru_it = item.MruIt;
299 if (_sectionLocked == mru_it)
300 _sectionLocked = std::next(mru_it);
301 _cacheSize -= item.Size;
302 if ((item.Flags & kCacheItem_Locked) != 0)
303 _lockedSize -= item.Size;
306 _externalSize -= item.Size;
311 void DisposeOldest() {
312 assert(_mru.begin() != _sectionLocked);
313 if (_mru.begin() == _sectionLocked)
316 auto mru_it = std::prev(_sectionLocked);
317 auto it = _storage.find(*mru_it);
318 assert(it != _storage.end());
319 auto &item = it->second;
320 assert((item.Flags & (kCacheItem_Locked | kCacheItem_External)) == 0);
321 _cacheSize -= item.Size;
326 void FreeMem(
size_t space) {
329 while ((_mru.begin() != _sectionLocked) && (_cacheSize + space > _maxSize)) {
337 TSize _cacheSize = 0u;
340 TSize _lockedSize = 0u;
343 TSize _externalSize = 0u;
355 TMruIt _sectionLocked;
366 #endif // AGS_SHARED_UTIL_RESOURCE_CACHE_H Definition: achievements_tables.h:27
void clear(bool shrinkArray=0)
Definition: hashmap.h:427
Definition: resource_cache.h:234
Definition: lobject.h:323
iterator end()
Definition: list.h:279
iterator begin()
Definition: list.h:266
Definition: resource_cache.h:71
void clear()
Definition: list.h:245
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
Definition: geometry.h:148
void erase(iterator entry)
Definition: hashmap.h:710
Definition: list_intern.h:54
iterator erase(iterator pos)
Definition: list.h:112