From 792b8b9bff09a5ed7cc98bc12b0c3d991e019b6f Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Thu, 3 Oct 2024 09:52:26 +0200 Subject: [PATCH] discv5: migrate to minilru As it happens, the two share the exact same interface (even the test suite removed in this PR passes) - `minilru` has an edge on efficiency however, avoiding the doubly linked list node allocations etc --- eth.nimble | 3 +- eth/p2p/discoveryv5/lru.nim | 45 +---------- eth/p2p/discoveryv5/sessions.nim | 6 +- tests/p2p/all_discv5_tests.nim | 1 - tests/p2p/test_lru.nim | 134 ------------------------------- 5 files changed, 9 insertions(+), 180 deletions(-) delete mode 100644 tests/p2p/test_lru.nim diff --git a/eth.nimble b/eth.nimble index c2d1acf0..1cd29d02 100644 --- a/eth.nimble +++ b/eth.nimble @@ -19,7 +19,8 @@ requires "nim >= 1.6.0", "confutils", "testutils", "unittest2", - "results" + "results", + "minilru" let nimc = getEnv("NIMC", "nim") # Which nim compiler to use let lang = getEnv("NIMLANG", "c") # Which backend (c/cpp/js) diff --git a/eth/p2p/discoveryv5/lru.nim b/eth/p2p/discoveryv5/lru.nim index 77ad5f5f..4ec557c8 100644 --- a/eth/p2p/discoveryv5/lru.nim +++ b/eth/p2p/discoveryv5/lru.nim @@ -6,46 +6,9 @@ # at your option. This file may not be copied, modified, or distributed except according to those terms. # -{.push raises: [].} - -import std/[tables, lists], results - -export results - -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 already 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 +{.deprecated: "Use minilru directly".} -func get*[K, V](lru: var LRUCache[K, V], key: K): Opt[V] = - let node = lru.table.getOrDefault(key, nil) - if node.isNil: - return Opt.none(V) - - lru.list.remove(node) - lru.list.prepend(node) - return Opt.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) +{.push raises: [].} -func len*[K, V](lru: LRUCache[K, V]): int = - lru.table.len +import minilru +export minilru diff --git a/eth/p2p/discoveryv5/sessions.nim b/eth/p2p/discoveryv5/sessions.nim index 3df12d04..ae4385cc 100644 --- a/eth/p2p/discoveryv5/sessions.nim +++ b/eth/p2p/discoveryv5/sessions.nim @@ -14,9 +14,9 @@ import std/net, stint, stew/endians2, - node, lru + ./node, minilru -export lru +export minilru const aesKeySize* = 128 div 8 @@ -28,7 +28,7 @@ type AesKey* = array[aesKeySize, byte] SessionKey* = array[keySize, byte] SessionValue* = array[sizeof(AesKey) + sizeof(AesKey), byte] - Sessions* = LRUCache[SessionKey, SessionValue] + Sessions* = LruCache[SessionKey, SessionValue] func makeKey(id: NodeId, address: Address): SessionKey = var pos = 0 diff --git a/tests/p2p/all_discv5_tests.nim b/tests/p2p/all_discv5_tests.nim index b20317bf..95a81dca 100644 --- a/tests/p2p/all_discv5_tests.nim +++ b/tests/p2p/all_discv5_tests.nim @@ -3,7 +3,6 @@ import ./test_enr, ./test_hkdf, - ./test_lru, ./test_ip_vote, ./test_routing_table, ./test_discoveryv5_encoding, diff --git a/tests/p2p/test_lru.nim b/tests/p2p/test_lru.nim deleted file mode 100644 index 26ec5f4a..00000000 --- a/tests/p2p/test_lru.nim +++ /dev/null @@ -1,134 +0,0 @@ -{.used.} - -import - std/options, - unittest2, - ../../eth/p2p/discoveryv5/lru - -suite "LRUCache": - const - capacity = 10 - target = 4 - test "LRU value gets removed": - var lru = LRUCache[int, int].init(capacity = capacity) - - # Fully fill the LRU - for i in 0..