mirror of
https://github.com/NixOS/nix.git
synced 2025-11-23 02:39:37 +01:00
Move /src to /subprojects
This will facilitate breaking up Nix into multiple packages for each component with Meson.
This commit is contained in:
parent
4db9487823
commit
84e2963f8e
737 changed files with 504 additions and 505 deletions
104
subprojects/libutil/lru-cache.hh
Normal file
104
subprojects/libutil/lru-cache.hh
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#pragma once
|
||||
///@file
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <optional>
|
||||
|
||||
namespace nix {
|
||||
|
||||
/**
|
||||
* A simple least-recently used cache. Not thread-safe.
|
||||
*/
|
||||
template<typename Key, typename Value>
|
||||
class LRUCache
|
||||
{
|
||||
private:
|
||||
|
||||
size_t capacity;
|
||||
|
||||
// Stupid wrapper to get around circular dependency between Data
|
||||
// and LRU.
|
||||
struct LRUIterator;
|
||||
|
||||
using Data = std::map<Key, std::pair<LRUIterator, Value>>;
|
||||
using LRU = std::list<typename Data::iterator>;
|
||||
|
||||
struct LRUIterator { typename LRU::iterator it; };
|
||||
|
||||
Data data;
|
||||
LRU lru;
|
||||
|
||||
public:
|
||||
|
||||
LRUCache(size_t capacity) : capacity(capacity) { }
|
||||
|
||||
/**
|
||||
* Insert or upsert an item in the cache.
|
||||
*/
|
||||
void upsert(const Key & key, const Value & value)
|
||||
{
|
||||
if (capacity == 0) return;
|
||||
|
||||
erase(key);
|
||||
|
||||
if (data.size() >= capacity) {
|
||||
/**
|
||||
* Retire the oldest item.
|
||||
*/
|
||||
auto oldest = lru.begin();
|
||||
data.erase(*oldest);
|
||||
lru.erase(oldest);
|
||||
}
|
||||
|
||||
auto res = data.emplace(key, std::make_pair(LRUIterator(), value));
|
||||
assert(res.second);
|
||||
auto & i(res.first);
|
||||
|
||||
auto j = lru.insert(lru.end(), i);
|
||||
|
||||
i->second.first.it = j;
|
||||
}
|
||||
|
||||
bool erase(const Key & key)
|
||||
{
|
||||
auto i = data.find(key);
|
||||
if (i == data.end()) return false;
|
||||
lru.erase(i->second.first.it);
|
||||
data.erase(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an item in the cache. If it exists, it becomes the most
|
||||
* recently used item.
|
||||
* */
|
||||
std::optional<Value> get(const Key & key)
|
||||
{
|
||||
auto i = data.find(key);
|
||||
if (i == data.end()) return {};
|
||||
|
||||
/**
|
||||
* Move this item to the back of the LRU list.
|
||||
*/
|
||||
lru.erase(i->second.first.it);
|
||||
auto j = lru.insert(lru.end(), i);
|
||||
i->second.first.it = j;
|
||||
|
||||
return i->second.second;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return data.size();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data.clear();
|
||||
lru.clear();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue