github.com/MeteorsLiu/simpleMQ@v1.0.3/generic/list.go (about) 1 package generic 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // Package list implements a doubly linked list. 8 // 9 // To iterate over a list (where l is a *List[T]): 10 // 11 // for e := l.Front(); e != nil; e = e.Next() { 12 // // do something with e.Value 13 // } 14 15 // Element[T] is an element of a linked list. 16 type Element[T any] struct { 17 // Next and previous pointers in the doubly-linked list of elements. 18 // To simplify the implementation, internally a list l is implemented 19 // as a ring, such that &l.root is both the next element of the last 20 // list element (l.Back()) and the previous element of the first list 21 // element (l.Front()). 22 next, prev *Element[T] 23 24 // The list to which this element belongs. 25 list *List[T] 26 27 // The value stored with this element. 28 Value T 29 } 30 31 // Next returns the next list element or nil. 32 func (e *Element[T]) Next() *Element[T] { 33 if p := e.next; e.list != nil && p != &e.list.root { 34 return p 35 } 36 return nil 37 } 38 39 // Prev returns the previous list element or nil. 40 func (e *Element[T]) Prev() *Element[T] { 41 if p := e.prev; e.list != nil && p != &e.list.root { 42 return p 43 } 44 return nil 45 } 46 47 // List represents a doubly linked list. 48 // The zero value for List is an empty list ready to use. 49 type List[T any] struct { 50 root Element[T] // sentinel list element, only &root, root.prev, and root.next are used 51 len int // current list length excluding (this) sentinel element 52 } 53 54 // Init initializes or clears list l. 55 func (l *List[T]) Init() *List[T] { 56 l.root.next = &l.root 57 l.root.prev = &l.root 58 l.len = 0 59 return l 60 } 61 62 // New returns an initialized list. 63 func New[T any]() *List[T] { return new(List[T]).Init() } 64 65 // Len returns the number of elements of list l. 66 // The complexity is O(1). 67 func (l *List[T]) Len() int { return l.len } 68 69 // Front returns the first element of list l or nil if the list is empty. 70 func (l *List[T]) Front() *Element[T] { 71 if l.len == 0 { 72 return nil 73 } 74 return l.root.next 75 } 76 77 // Back returns the last element of list l or nil if the list is empty. 78 func (l *List[T]) Back() *Element[T] { 79 if l.len == 0 { 80 return nil 81 } 82 return l.root.prev 83 } 84 85 // lazyInit lazily initializes a zero List value. 86 func (l *List[T]) lazyInit() { 87 if l.root.next == nil { 88 l.Init() 89 } 90 } 91 92 // insert inserts e after at, increments l.len, and returns e. 93 func (l *List[T]) insert(e, at *Element[T]) *Element[T] { 94 e.prev = at 95 e.next = at.next 96 e.prev.next = e 97 e.next.prev = e 98 e.list = l 99 l.len++ 100 return e 101 } 102 103 // insertValue is a convenience wrapper for insert(&Element[T]{Value: v}, at). 104 func (l *List[T]) insertValue(v T, at *Element[T]) *Element[T] { 105 return l.insert(&Element[T]{Value: v}, at) 106 } 107 108 // remove removes e from its list, decrements l.len 109 func (l *List[T]) remove(e *Element[T]) { 110 e.prev.next = e.next 111 e.next.prev = e.prev 112 e.next = nil // avoid memory leaks 113 e.prev = nil // avoid memory leaks 114 e.list = nil 115 l.len-- 116 } 117 118 // move moves e to next to at. 119 func (l *List[T]) move(e, at *Element[T]) { 120 if e == at { 121 return 122 } 123 e.prev.next = e.next 124 e.next.prev = e.prev 125 126 e.prev = at 127 e.next = at.next 128 e.prev.next = e 129 e.next.prev = e 130 } 131 132 // Remove removes e from l if e is an element of list l. 133 // It returns the element value e.Value. 134 // The element must not be nil. 135 func (l *List[T]) Remove(e *Element[T]) any { 136 if e.list == l { 137 // if e.list == l, l must have been initialized when e was inserted 138 // in l or l == nil (e is a zero Element[T]) and l.remove will crash 139 l.remove(e) 140 } 141 return e.Value 142 } 143 144 // PushFront inserts a new element e with value v at the front of list l and returns e. 145 func (l *List[T]) PushFront(v T) *Element[T] { 146 l.lazyInit() 147 return l.insertValue(v, &l.root) 148 } 149 150 // PushBack inserts a new element e with value v at the back of list l and returns e. 151 func (l *List[T]) PushBack(v T) *Element[T] { 152 l.lazyInit() 153 return l.insertValue(v, l.root.prev) 154 } 155 156 // InsertBefore inserts a new element e with value v immediately before mark and returns e. 157 // If mark is not an element of l, the list is not modified. 158 // The mark must not be nil. 159 func (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T] { 160 if mark.list != l { 161 return nil 162 } 163 // see comment in List.Remove about initialization of l 164 return l.insertValue(v, mark.prev) 165 } 166 167 // InsertAfter inserts a new element e with value v immediately after mark and returns e. 168 // If mark is not an element of l, the list is not modified. 169 // The mark must not be nil. 170 func (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T] { 171 if mark.list != l { 172 return nil 173 } 174 // see comment in List.Remove about initialization of l 175 return l.insertValue(v, mark) 176 } 177 178 // MoveToFront moves element e to the front of list l. 179 // If e is not an element of l, the list is not modified. 180 // The element must not be nil. 181 func (l *List[T]) MoveToFront(e *Element[T]) { 182 if e.list != l || l.root.next == e { 183 return 184 } 185 // see comment in List.Remove about initialization of l 186 l.move(e, &l.root) 187 } 188 189 // MoveToBack moves element e to the back of list l. 190 // If e is not an element of l, the list is not modified. 191 // The element must not be nil. 192 func (l *List[T]) MoveToBack(e *Element[T]) { 193 if e.list != l || l.root.prev == e { 194 return 195 } 196 // see comment in List.Remove about initialization of l 197 l.move(e, l.root.prev) 198 } 199 200 // MoveBefore moves element e to its new position before mark. 201 // If e or mark is not an element of l, or e == mark, the list is not modified. 202 // The element and mark must not be nil. 203 func (l *List[T]) MoveBefore(e, mark *Element[T]) { 204 if e.list != l || e == mark || mark.list != l { 205 return 206 } 207 l.move(e, mark.prev) 208 } 209 210 // MoveAfter moves element e to its new position after mark. 211 // If e or mark is not an element of l, or e == mark, the list is not modified. 212 // The element and mark must not be nil. 213 func (l *List[T]) MoveAfter(e, mark *Element[T]) { 214 if e.list != l || e == mark || mark.list != l { 215 return 216 } 217 l.move(e, mark) 218 } 219 220 // PushBackList inserts a copy of another list at the back of list l. 221 // The lists l and other may be the same. They must not be nil. 222 func (l *List[T]) PushBackList(other *List[T]) { 223 l.lazyInit() 224 for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { 225 l.insertValue(e.Value, l.root.prev) 226 } 227 } 228 229 // PushFrontList inserts a copy of another list at the front of list l. 230 // The lists l and other may be the same. They must not be nil. 231 func (l *List[T]) PushFrontList(other *List[T]) { 232 l.lazyInit() 233 for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { 234 l.insertValue(e.Value, &l.root) 235 } 236 }