package lfu import ( "sync/atomic" ) type List[T any] struct { root *Element[T] len atomic.Int32 sync *Synchronizer[*Element[T]] } func (l *List[T]) First() *Element[T] { if l.Len() == 0 { return nil } var next *Element[T] l.sync.ReadTx(l.root, func(upgrade func(func())) error { next = l.root.next return nil }) return next } func (l *List[T]) Last() *Element[T] { if l.Len() == 0 { return nil } var prev *Element[T] l.sync.ReadTx(l.root, func(upgrade func(func())) error { prev = l.root.prev return nil }) return prev } func (l *List[T]) Prev(e *Element[T]) *Element[T] { var prev *Element[T] l.sync.ReadTx(e, func(upgrade func(func())) error { prev = e.prev return nil }) return prev } func (l *List[T]) Next(e *Element[T]) *Element[T] { var next *Element[T] l.sync.ReadTx(e, func(upgrade func(func())) error { next = e.next return nil }) return next } func (l *List[T]) Value(e *Element[T]) T { var value T l.sync.ReadTx(e, func(upgrade func(func())) error { value = e.value return nil }) return value } func (l *List[T]) PushFront(v T) *Element[T] { return l.InsertValueAfter(v, l.root) } func (l *List[T]) PushBack(v T) *Element[T] { return l.InsertValueAfter(v, l.root) } func (l *List[T]) Remove(e *Element[T]) { 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] { l.sync.ReadTx(e, func(upgrade func(fn func())) error { var next *Element[T] l.sync.ReadTx(at, func(upgrade func(func())) error { next = at.next return nil }) upgrade(func() { e.prev = at e.next = next e.list = l }) if e.prev != nil { l.sync.WriteTx(e.prev, func() error { e.prev.next = e return nil }) } if e.next != nil { l.sync.WriteTx(e.next, func() error { e.next.prev = e return nil }) } return nil }) 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]) { if e == nil && e == l.root { return } l.sync.ReadTx(e, func(upgrade func(fn func())) error { if e.prev != nil { if e.prev == e { upgrade(func() { e.prev.next = e.next }) } else { l.sync.WriteTx(e.prev, func() error { e.prev.next = e.next return nil }) } } if e.next != nil { if e.next == e { upgrade(func() { e.next.prev = e.prev }) } else { l.sync.WriteTx(e.next, func() error { e.next.prev = e.prev return nil }) } } upgrade(func() { e.next = nil e.prev = nil e.list = nil }) return nil }) l.sync.Remove(e) l.len.Add(-1) } func NewList[T any]() *List[T] { root := NewElement(*new(T)) root.next = root root.prev = root list := &List[T]{ sync: NewSynchronizer[*Element[T]](), } root.list = list list.root = root return list } type Element[T any] struct { prev *Element[T] next *Element[T] list *List[T] value T } func NewElement[T any](v T) *Element[T] { element := &Element[T]{ prev: nil, next: nil, list: nil, value: v, } return element }