github.com/djordje200179/extendedlibrary/datastructures@v1.7.1-0.20240227175559-d09520a92dd4/cols/synclist/list.go (about) 1 package synclist 2 3 import ( 4 "github.com/djordje200179/extendedlibrary/datastructures/iter" 5 "sync/atomic" 6 ) 7 8 // List is a lock-free singly linked list. 9 // It is safe to use it concurrently from multiple goroutines. 10 // The zero value is ready to use. Do not copy a non-zero List. 11 type List[T any] struct { 12 head atomic.Pointer[Node[T]] 13 } 14 15 // New creates an empty List. 16 func New[T any]() *List[T] { 17 return new(List[T]) 18 } 19 20 // NewFromIterable creates a List from the specified iter.Iterable in 21 // reverse order. List.Reverse can be used to restore the original order. 22 func NewFromIterable[T any](iterable iter.Iterable[T]) *List[T] { 23 list := New[T]() 24 25 for it := iterable.Iterator(); it.Valid(); it.Move() { 26 list.Prepend(it.Get()) 27 } 28 29 return list 30 } 31 32 // Prepend adds the specified value to the beginning of the List. 33 func (list *List[T]) Prepend(value T) { 34 node := &Node[T]{Value: value} 35 36 node.next = list.head.Swap(node) 37 } 38 39 // Clear removes all elements from the List. 40 func (list *List[T]) Clear() { 41 list.head.Store(nil) 42 } 43 44 // Reverse reverses the order of the elements in the List. 45 // This method is not thread-safe. It is meant to be used after 46 // all concurrent operations on the List have finished. 47 func (list *List[T]) Reverse() { 48 var prev *Node[T] 49 50 curr := list.head.Load() 51 for curr != nil { 52 next := curr.next 53 54 curr.next = prev 55 56 prev = curr 57 curr = next 58 } 59 60 list.head.Store(prev) 61 } 62 63 // Iterator returns an iterator over the elements in the List. 64 func (list *List[T]) Iterator() iter.Iterator[T] { 65 return &Iterator[T]{curr: list.head.Load()} 66 } 67 68 // Stream streams the elements of the List. 69 func (list *List[T]) Stream(yield func(T) bool) { 70 for curr := list.head.Load(); curr != nil; curr = curr.next { 71 if !yield(curr.Value) { 72 break 73 } 74 } 75 } 76 77 // Head returns the first element in the List. 78 func (list *List[T]) Head() *Node[T] { 79 return list.head.Load() 80 }