diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-01-09 14:23:23 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-12 16:16:53 -0700 |
commit | d91f8ce17a6fc165fafd9dc921911233a69c34d2 (patch) | |
tree | 808a86b8f2309fe344b4cb0af62101b8a3b8b59a /lib/containers | |
parent | 1d7f5446dc37687f078269af3c63af7d7ebbfab4 (diff) |
tree-wide: Migrate to the new ARCache
Diffstat (limited to 'lib/containers')
-rw-r--r-- | lib/containers/arcache.go | 2 | ||||
-rw-r--r-- | lib/containers/lru.go | 78 | ||||
-rw-r--r-- | lib/containers/lrucache.go | 2 | ||||
-rw-r--r-- | lib/containers/maputil.go | 32 | ||||
-rw-r--r-- | lib/containers/sortedmap.go | 9 |
5 files changed, 45 insertions, 78 deletions
diff --git a/lib/containers/arcache.go b/lib/containers/arcache.go index ad551e9..1dc3b7e 100644 --- a/lib/containers/arcache.go +++ b/lib/containers/arcache.go @@ -53,6 +53,8 @@ type ARCache[K comparable, V any] struct { noopChecker //nolint:unused // False positive; it is used. } +var _ Map[int, string] = (*ARCache[int, string])(nil) + //nolint:unused // False positive; it is used. type noopChecker struct{} diff --git a/lib/containers/lru.go b/lib/containers/lru.go deleted file mode 100644 index aa372ed..0000000 --- a/lib/containers/lru.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package containers - -import ( - lru "github.com/hashicorp/golang-lru" -) - -// LRUCache is a least-recently-used(ish) cache. A zero LRUCache is -// not usable; it must be initialized with NewLRUCache. -type LRUCache[K comparable, V any] struct { - inner *lru.ARCCache -} - -func NewLRUCache[K comparable, V any](size int) *LRUCache[K, V] { - c := new(LRUCache[K, V]) - c.inner, _ = lru.NewARC(size) - return c -} - -func (c *LRUCache[K, V]) Add(key K, value V) { - c.inner.Add(key, value) -} - -func (c *LRUCache[K, V]) Contains(key K) bool { - return c.inner.Contains(key) -} - -func (c *LRUCache[K, V]) Get(key K) (value V, ok bool) { - _value, ok := c.inner.Get(key) - if ok { - //nolint:forcetypeassert // Typed wrapper around untyped lib. - value = _value.(V) - } - return value, ok -} - -func (c *LRUCache[K, V]) Keys() []K { - untyped := c.inner.Keys() - typed := make([]K, len(untyped)) - for i := range untyped { - //nolint:forcetypeassert // Typed wrapper around untyped lib. - typed[i] = untyped[i].(K) - } - return typed -} - -func (c *LRUCache[K, V]) Len() int { - return c.inner.Len() -} - -func (c *LRUCache[K, V]) Peek(key K) (value V, ok bool) { - _value, ok := c.inner.Peek(key) - if ok { - //nolint:forcetypeassert // Typed wrapper around untyped lib. - value = _value.(V) - } - return value, ok -} - -func (c *LRUCache[K, V]) Purge() { - c.inner.Purge() -} - -func (c *LRUCache[K, V]) Remove(key K) { - c.inner.Remove(key) -} - -func (c *LRUCache[K, V]) GetOrElse(key K, fn func() V) V { - var value V - var ok bool - for value, ok = c.Get(key); !ok; value, ok = c.Get(key) { - c.Add(key, fn()) - } - return value -} diff --git a/lib/containers/lrucache.go b/lib/containers/lrucache.go index e7a8d62..94094b9 100644 --- a/lib/containers/lrucache.go +++ b/lib/containers/lrucache.go @@ -36,6 +36,8 @@ type lruCache[K comparable, V any] struct { byName map[K]*LinkedListEntry[lruEntry[K, V]] } +var _ Map[int, string] = (*lruCache[int, string])(nil) + func (c *lruCache[K, V]) rem(entry *LinkedListEntry[lruEntry[K, V]]) { k, v := entry.Value.key, entry.Value.val delete(c.byName, entry.Value.key) diff --git a/lib/containers/maputil.go b/lib/containers/maputil.go new file mode 100644 index 0000000..4d49d2a --- /dev/null +++ b/lib/containers/maputil.go @@ -0,0 +1,32 @@ +// Copyright (C) 2023 Luke Shumaker <lukeshu@lukeshu.com> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package containers + +type Map[K comparable, V any] interface { + Store(K, V) + Load(K) (V, bool) + Has(K) bool + Delete(K) + Len() int +} + +type RangeMap[K comparable, V any] interface { + Map[K, V] + Range(func(K, V) bool) +} + +type SubrangeMap[K comparable, V any] interface { + RangeMap[K, V] + Subrange(rangeFn func(K, V) int, handleFn func(K, V) bool) +} + +func LoadOrElse[K comparable, V any](m Map[K, V], k K, vFn func(K) V) V { + if v, ok := m.Load(k); ok { + return v + } + v := vFn(k) + m.Store(k, v) + return v +} diff --git a/lib/containers/sortedmap.go b/lib/containers/sortedmap.go index d104274..ebce685 100644 --- a/lib/containers/sortedmap.go +++ b/lib/containers/sortedmap.go @@ -17,6 +17,8 @@ type SortedMap[K Ordered[K], V any] struct { inner RBTree[orderedKV[K, V]] } +var _ SubrangeMap[NativeOrdered[int], string] = (*SortedMap[NativeOrdered[int], string])(nil) + func (m *SortedMap[K, V]) Delete(key K) { m.inner.Delete(m.inner.Search(func(kv orderedKV[K, V]) int { return key.Compare(kv.K) @@ -34,6 +36,13 @@ func (m *SortedMap[K, V]) Load(key K) (value V, ok bool) { return node.Value.V, true } +func (m *SortedMap[K, V]) Has(key K) bool { + node := m.inner.Search(func(kv orderedKV[K, V]) int { + return key.Compare(kv.K) + }) + return node != nil +} + func (m *SortedMap[K, V]) Store(key K, value V) { m.inner.Insert(orderedKV[K, V]{ K: key, |