package lfu import ( "sync/atomic" ) type List[T any] struct { root atomic.Pointer[Element[T]] len atomic.Int32 } func (l *List[T]) First() *Element[T] { if l.len.Load() == 0 { return nil } root := l.root.Load() return root.next.Load() } func (l *List[T]) Last() *Element[T] { if l.len.Load() == 0 { return nil } root := l.root.Load() return root.prev.Load() } func (l *List[T]) PushFront(v T) *Element[T] { root := l.root.Load() return l.InsertValueAfter(v, root) } func (l *List[T]) PushBack(v T) *Element[T] { root := l.root.Load() return l.InsertValueAfter(v, root) } func (l *List[T]) Remove(e *Element[T]) { if e.list.Load() == l { l.remove(e) } } func (l *List[T]) Len() int { return int(l.len.Load()) } func (l *List[T]) insertAfter(e *Element[T], at *Element[T]) *Element[T] { e.prev.Store(at) e.next.Store(at.next.Load()) prev := e.prev.Load() if prev != nil { prev.next.Store(e) } next := e.next.Load() if next != nil { next.prev.Store(e) } e.list.Store(l) l.len.Add(1) return e } func (l *List[T]) InsertValueAfter(v T, at *Element[T]) *Element[T] { e := NewElement[T](v) return l.insertAfter(e, at) } func (l *List[T]) remove(e *Element[T]) { prev := e.prev.Load() if prev != nil { prev.next.Store(e.next.Load()) } next := e.next.Load() if next != nil { next.prev.Store(e.prev.Load()) } e.next.Store(nil) e.prev.Store(nil) e.list.Store(nil) l.len.Add(-1) } func NewList[T any]() *List[T] { root := NewElement(*new(T)) root.next.Store(root) root.prev.Store(root) list := &List[T]{} root.list.Store(list) atomic := atomic.Pointer[Element[T]]{} atomic.Store(root) list.root = atomic return list } type Element[T any] struct { prev atomic.Pointer[Element[T]] next atomic.Pointer[Element[T]] list atomic.Pointer[List[T]] value atomic.Pointer[T] } func (e *Element[T]) Next() *Element[T] { l := e.list.Load() if l == nil { return nil } n := e.next.Load() r := l.root.Load() if n == r { return nil } return n } func (e *Element[T]) Prev() *Element[T] { l := e.list.Load() if l == nil { return nil } p := e.prev.Load() r := l.root.Load() if p == r { return nil } return p } func (e *Element[T]) Value() T { return *e.value.Load() } func NewElement[T any](v T) *Element[T] { value := atomic.Pointer[T]{} value.Store(&v) return &Element[T]{ value: value, prev: atomic.Pointer[Element[T]]{}, next: atomic.Pointer[Element[T]]{}, list: atomic.Pointer[List[T]]{}, } }