lightninglabs / neutrino

Privacy-Preserving Bitcoin Light Client
MIT License
894 stars 182 forks source link

cache+neutrino: update existing Cache interface to use type parameters #261

Closed Roasbeef closed 1 year ago

Roasbeef commented 1 year ago

This change gives all LRU cache declaration a bit more context, and also added compile-time type safety. Users no longer need to cast items before inserting or retrieving from the cache. Along the way, we copied the list.List implementation from Go and updated that itself to be generic.

PR is best reviewed in order with each commit.

Roasbeef commented 1 year ago

cc @halseth

Roasbeef commented 1 year ago

Alternatively:

diff --git a/cache/lru/lru.go b/cache/lru/lru.go
index c08c825..bc3cb66 100644
--- a/cache/lru/lru.go
+++ b/cache/lru/lru.go
@@ -9,7 +9,7 @@ import (

 // elementMap is an alias for a map from a generic interface to a list.Element.
 type elementMap[K comparable, V any] struct {
-   m map[K]*Element[V]
+   m map[K]V
 }

 // Del deletes an item from the cache.
@@ -18,13 +18,13 @@ func (e *elementMap[K, V]) Del(key K) {
 }

 // Lookup attempts to lookup a value in the cache.
-func (e *elementMap[K, V]) Lookup(key K) (*Element[V], bool) {
+func (e *elementMap[K, V]) Lookup(key K) (V, bool) {
    el, ok := e.m[key]
    return el, ok
 }

 // Store attempts to store an item in the cache.
-func (e *elementMap[K, V]) Store(key K, val *Element[V]) {
+func (e *elementMap[K, V]) Store(key K, val V) {
    e.m[key] = val
 }

@@ -51,7 +51,7 @@ type Cache[K comparable, V cache.Value] struct {

    // cache is a generic cache which allows us to find an elements position
    // in the ll list from a given key.
-   cache elementMap[K, entry[K, V]]
+   cache elementMap[K, *Element[entry[K, V]]]

    // mtx is used to make sure the Cache is thread-safe.
    mtx sync.RWMutex
@@ -63,7 +63,7 @@ func NewCache[K comparable, V cache.Value](capacity uint64) *Cache[K, V] {
    return &Cache[K, V]{
        capacity: capacity,
        ll:       NewList[entry[K, V]](),
-       cache: elementMap[K, entry[K, V]]{
+       cache: elementMap[K, *Element[entry[K, V]]]{
            m: make(map[K]*Element[entry[K, V]]),
        },
    }

Then elementMap can go back to being a typedef.

Roasbeef commented 1 year ago

The linter is failing but it looks like that's a general problem with the version we use (I can create a fix in another PR)

Seems like it can't handle the new generics syntax?