mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +02:00
libutil: Add LRUCache::getOrNullptr
For heavier objects it doesn't make sense to return a std::optional with the copy of the data, when it can be used by const reference.
This commit is contained in:
parent
67535263a5
commit
4711720efe
1 changed files with 35 additions and 11 deletions
|
@ -33,6 +33,18 @@ private:
|
|||
Data data;
|
||||
LRU lru;
|
||||
|
||||
/**
|
||||
* Move this item to the back of the LRU list.
|
||||
*/
|
||||
void promote(LRU::iterator it)
|
||||
{
|
||||
/* Think of std::list iterators as stable pointers to the list node,
|
||||
* which never get invalidated. Thus, we can reuse the same lru list
|
||||
* element and just splice it to the back of the list without the need
|
||||
* to update its value in the key -> list iterator map. */
|
||||
lru.splice(/*pos=*/lru.end(), /*other=*/lru, it);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
LRUCache(size_t capacity)
|
||||
|
@ -83,7 +95,9 @@ public:
|
|||
/**
|
||||
* Look up an item in the cache. If it exists, it becomes the most
|
||||
* recently used item.
|
||||
* */
|
||||
*
|
||||
* @returns corresponding cache entry, std::nullopt if it's not in the cache
|
||||
*/
|
||||
template<typename K>
|
||||
std::optional<Value> get(const K & key)
|
||||
{
|
||||
|
@ -91,20 +105,30 @@ public:
|
|||
if (i == data.end())
|
||||
return {};
|
||||
|
||||
/**
|
||||
* Move this item to the back of the LRU list.
|
||||
*
|
||||
* Think of std::list iterators as stable pointers to the list node,
|
||||
* which never get invalidated. Thus, we can reuse the same lru list
|
||||
* element and just splice it to the back of the list without the need
|
||||
* to update its value in the key -> list iterator map.
|
||||
*/
|
||||
auto & [it, value] = i->second;
|
||||
lru.splice(/*pos=*/lru.end(), /*other=*/lru, it.it);
|
||||
|
||||
promote(it.it);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an item in the cache. If it exists, it becomes the most
|
||||
* recently used item.
|
||||
*
|
||||
* @returns mutable pointer to the corresponding cache entry, nullptr if
|
||||
* it's not in the cache
|
||||
*/
|
||||
template<typename K>
|
||||
Value * getOrNullptr(const K & key)
|
||||
{
|
||||
auto i = data.find(key);
|
||||
if (i == data.end())
|
||||
return nullptr;
|
||||
|
||||
auto & [it, value] = i->second;
|
||||
promote(it.it);
|
||||
return &value;
|
||||
}
|
||||
|
||||
size_t size() const noexcept
|
||||
{
|
||||
return data.size();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue