@@ -281,11 +281,10 @@ class ResizableLRUCache : protected impl::LRUCacheBase<Key, Value, MapHash, MapE
281
281
using assoc_t = typename base_t ::list_value_t ;
282
282
283
283
// Constructor
284
- ResizableLRUCache (const uint32_t capacity, disposal_func_t && _df = disposal_func_t (), MapHash&& _hash = MapHash(), MapEquals&& _equals = MapEquals()) :
285
- base_t (capacity, std::move(_hash), std::move(_equals), std::move(_df)),
284
+ ResizableLRUCache (uint32_t capacity, disposal_func_t && _df = disposal_func_t (), MapHash&& _hash = MapHash(), MapEquals&& _equals = MapEquals()) :
285
+ base_t (capacity, std::move(_hash), std::move(_equals), std::move(_df)), m_capacity(capacity),
286
286
m_shortcut_map (capacity >> 2 , WrapHash{ this }, WrapEquals{ this }) // 4x less buckets than capacity seems reasonable
287
287
{
288
- assert (capacity > 1 );
289
288
m_shortcut_map.reserve (capacity);
290
289
}
291
290
ResizableLRUCache () = delete;
@@ -301,10 +300,29 @@ class ResizableLRUCache : protected impl::LRUCacheBase<Key, Value, MapHash, MapE
301
300
stringStream << " k: '" << node->data .first << " ', v: '" << node->data .second << " '\t prev: " << node->prev << " | curr: " << nodeAddr << " | next: " << node->next ;
302
301
logger->log (stringStream.str ());
303
302
nodeAddr = node->prev ;
304
- node = base_t ::m_list.get (node->prev );
305
303
}
306
304
}
307
305
306
+ /* *
307
+ * @brief Returns a string representing the elements currently in the cache in LRU order
308
+ *
309
+ * @param [in] newCapacity New number of elements to hold. MUST be greater than current list capacity.
310
+ */
311
+ inline std::string getState ()
312
+ {
313
+ std::ostringstream stringStream;
314
+ auto nodeAddr = base_t ::m_list.getLastAddress ();
315
+ while (nodeAddr != invalid_iterator)
316
+ {
317
+ auto node = base_t ::m_list.get (nodeAddr);
318
+ stringStream << " {" << node->data .first << " , " << node->data .second << " }" ;
319
+ nodeAddr = node->prev ;
320
+ if (nodeAddr != invalid_iterator)
321
+ stringStream << " , " ;
322
+ }
323
+ return stringStream.str ();
324
+ }
325
+
308
326
template <typename K, typename V, std::invocable<const Value&> EvictionCallback> requires std::is_constructible_v<Value, V> // && (std::is_same_v<Value,V> || std::is_assignable_v<Value,V>) // is_assignable_v<int, int&> returns false :(
309
327
inline Value* insert (K&& k, V&& v, EvictionCallback&& evictCallback)
310
328
{
@@ -390,6 +408,8 @@ class ResizableLRUCache : protected impl::LRUCacheBase<Key, Value, MapHash, MapE
390
408
*/
391
409
inline bool grow (uint32_t newCapacity)
392
410
{
411
+ if (newCapacity <= m_capacity)
412
+ return false ;
393
413
m_shortcut_map.reserve (newCapacity);
394
414
return base_t ::m_list.grow (newCapacity);
395
415
}
@@ -409,6 +429,7 @@ class ResizableLRUCache : protected impl::LRUCacheBase<Key, Value, MapHash, MapE
409
429
410
430
protected:
411
431
unordered_set<uint32_t , WrapHash, WrapEquals> m_shortcut_map;
432
+ uint32_t m_capacity;
412
433
};
413
434
414
435
} // namespace core
0 commit comments