Eric Mastro acd03ff831 feat: reorg project to add nimble build system
Project has been updated to use nimble as a build system. All required dependencies have been added.

All nim-eth mirrored files were added to a private folder in the libp2pdht module. A libp2pdht/discv5 module was added to alias the nim-eth modules (which will change over time).

Test have been updated to use status-im/asynctest. This PR uses a branch of asynctest that supports async suite before/after. This seemed like the only the tests would work without throwing gcsafe errors.

All tests working.
2022-02-25 09:10:43 +11:00

42 lines
1.2 KiB
Nim

import std/[tables, lists, options]
{.push raises: [Defect].}
type
LRUCache*[K, V] = object of RootObj
list: DoublyLinkedList[(K, V)] # Head is MRU k:v and tail is LRU k:v
table: Table[K, DoublyLinkedNode[(K, V)]] # DoublyLinkedNode is alraedy ref
capacity: int
func init*[K, V](T: type LRUCache[K, V], capacity: int): LRUCache[K, V] =
LRUCache[K, V](capacity: capacity) # Table and list init is done default
func get*[K, V](lru: var LRUCache[K, V], key: K): Option[V] =
let node = lru.table.getOrDefault(key, nil)
if node.isNil:
return none(V)
lru.list.remove(node)
lru.list.prepend(node)
return some(node.value[1])
func put*[K, V](lru: var LRUCache[K, V], key: K, value: V) =
let node = lru.table.getOrDefault(key, nil)
if not node.isNil:
lru.list.remove(node)
else:
if lru.table.len >= lru.capacity:
lru.table.del(lru.list.tail.value[0])
lru.list.remove(lru.list.tail)
lru.list.prepend((key, value))
lru.table[key] = lru.list.head
func del*[K, V](lru: var LRUCache[K, V], key: K) =
var node: DoublyLinkedNode[(K, V)]
if lru.table.pop(key, node):
lru.list.remove(node)
func len*[K, V](lru: LRUCache[K, V]): int =
lru.table.len