Skip to content

Commit

Permalink
Move the ringlist into own package
Browse files Browse the repository at this point in the history
  • Loading branch information
mgnsk committed Apr 30, 2023
1 parent c544e6e commit 680ba5c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 11 deletions.
8 changes: 7 additions & 1 deletion backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ package evcache
import (
"sync"
"time"

"github.com/mgnsk/evcache/v3/ringlist"
)

type recordList[V any] struct {
ringlist.List[record[V], *record[V]]
}

type backend[K comparable, V any] struct {
list RingList[record[V], *record[V]]
list recordList[V]
timer *time.Timer
done chan struct{}
sync.Map
Expand Down
4 changes: 4 additions & 0 deletions ringlist/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*
Package ringlist implements a circular doubly linked list.
*/
package ringlist
44 changes: 44 additions & 0 deletions ringlist/element.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ringlist

// Element is a list element.
type Element[V any] struct {
Value V
next, prev *Element[V]
}

// NewElement creates a list element.
func NewElement[V any](v V) *Element[V] {
e := &Element[V]{
Value: v,
}
e.next = e
e.prev = e
return e
}

// Next returns the next element or nil.
func (e *Element[V]) Next() *Element[V] {
return e.next
}

// Prev returns the previous element or nil.
func (e *Element[V]) Prev() *Element[V] {
return e.prev
}

// Link inserts an element after this element.
func (e *Element[V]) Link(s *Element[V]) {
n := e.next
e.next = s
s.prev = e
n.prev = s
s.next = n
}

// Unlink unlinks this element.
func (e *Element[V]) Unlink() {
e.prev.next = e.next
e.next.prev = e.prev
e.next = e
e.prev = e
}
26 changes: 16 additions & 10 deletions ringlist.go → ringlist/ringlist.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
package evcache
package ringlist

// ListElement is the constraint for a list element.
// ElementList is a built in list type that uses the Element type as its element.
// The zero value is a ready to use empty list.
type ElementList[V any] struct {
List[Element[V], *Element[V]]
}

// ListElement is the constraint for a generic list element.
type ListElement[E any] interface {
Link(E)
Unlink()
Next() E
Prev() E
}

// RingList is a circular doubly linked list.
// List is a generic circular doubly linked list.
// The zero value is a ready to use empty list.
type RingList[T any, E interface {
type List[T any, E interface {
*T
ListElement[E]
}] struct {
Expand All @@ -19,25 +25,25 @@ type RingList[T any, E interface {
}

// Len returns the number of elements in the list.
func (l RingList[T, E]) Len() int {
func (l *List[T, E]) Len() int {
return l.len
}

// Front returns the first element of the list or nil.
func (l *RingList[T, E]) Front() E {
func (l *List[T, E]) Front() E {
if l.len == 0 {
return nil
}
return l.tail.Next()
}

// Back returns the last element of the list or nil.
func (l *RingList[T, E]) Back() E {
func (l *List[T, E]) Back() E {
return l.tail
}

// PushBack inserts a new element v at the back of the list.
func (l *RingList[T, E]) PushBack(e E) {
// PushBack inserts a new element at the back of the list.
func (l *List[T, E]) PushBack(e E) {
if l.tail != nil {
l.tail.Link(e)
}
Expand All @@ -46,7 +52,7 @@ func (l *RingList[T, E]) PushBack(e E) {
}

// Remove an element from the list.
func (l *RingList[T, E]) Remove(e E) {
func (l *List[T, E]) Remove(e E) {
if e == l.tail {
if l.len == 1 {
l.tail = nil
Expand Down

0 comments on commit 680ba5c

Please sign in to comment.