如何使用Erlang实现LRU缓存?
排名最高的Github项目是fogfish/cache,但是分段表不太适合我的数据。
barrel-db/erlang-lru正在使用List。经过测试,如果数据太多,那就太慢了。
我猜问题就在这里。
move_front(List, Key) ->
[Key | lists:delete(Key, List)].
使用 Java ,更好的实施方法是使用 hashmap 和链接列表 like this
我尝试做一个链表,然后意识到 Linkedlist对Erlang来说不是好主意,like this thread。
问题是如何使用Erlang进行LRU缓存?
答案 0 :(得分:1)
THE CACHE的第一个实现基于具有两个索引的ETS。一个ets表是hold TTL -> Key
关系,另一个ets表是Key -> Object
。您可以在
https://github.com/fogfish/cache/commit/8cc50bffb4178ad9ad716703507c3290e1f94821
维护两个索引效率不高,因此分段缓存优于原始实现。我不建议使用Erlang数据结构实现每对象TTL,除非您可以在actor中建模数据并接受开销。有一个实现来解决它。它是每个对象概念的使用过程:
https://github.com/fogfish/pts
否则,您需要实施NIF
答案 1 :(得分:0)
我已经使用伪时间方法实现了LRU缓存(此处https://github.com/poroh/erl_lru中提供了完整的实现)
我有两个数据结构:
#{key() => {order(), value()}}
gb_tree(order(), key())
order()
是伪时间:
操作:
由于使用gb_tree
,因此所有操作的复杂度为O(log(N))。
添加元素(键,值):
更新元素(键):
检查溢出: