github.com/zhongdalu/gf@v1.0.0/g/container/glist/glist.go (about) 1 // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with l file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 // 7 8 // Package glist provides a concurrent-safe/unsafe doubly linked list. 9 package glist 10 11 import ( 12 "container/list" 13 "github.com/zhongdalu/gf/g/internal/rwmutex" 14 ) 15 16 type ( 17 List struct { 18 mu *rwmutex.RWMutex 19 list *list.List 20 } 21 22 Element = list.Element 23 ) 24 25 // New creates and returns a new empty doubly linked list. 26 func New(unsafe ...bool) *List { 27 return &List{ 28 mu: rwmutex.New(unsafe...), 29 list: list.New(), 30 } 31 } 32 33 // PushFront inserts a new element <e> with value <v> at the front of list <l> and returns <e>. 34 func (l *List) PushFront(v interface{}) (e *Element) { 35 l.mu.Lock() 36 e = l.list.PushFront(v) 37 l.mu.Unlock() 38 return 39 } 40 41 // PushBack inserts a new element <e> with value <v> at the back of list <l> and returns <e>. 42 func (l *List) PushBack(v interface{}) (e *Element) { 43 l.mu.Lock() 44 e = l.list.PushBack(v) 45 l.mu.Unlock() 46 return 47 } 48 49 // PushFronts inserts multiple new elements with values <values> at the front of list <l>. 50 func (l *List) PushFronts(values []interface{}) { 51 l.mu.Lock() 52 for _, v := range values { 53 l.list.PushFront(v) 54 } 55 l.mu.Unlock() 56 } 57 58 // PushBacks inserts multiple new elements with values <values> at the back of list <l>. 59 func (l *List) PushBacks(values []interface{}) { 60 l.mu.Lock() 61 for _, v := range values { 62 l.list.PushBack(v) 63 } 64 l.mu.Unlock() 65 } 66 67 // PopBack removes the element from back of <l> and returns the value of the element. 68 func (l *List) PopBack() (value interface{}) { 69 l.mu.Lock() 70 if e := l.list.Back(); e != nil { 71 value = l.list.Remove(e) 72 } 73 l.mu.Unlock() 74 return 75 } 76 77 // PopFront removes the element from front of <l> and returns the value of the element. 78 func (l *List) PopFront() (value interface{}) { 79 l.mu.Lock() 80 if e := l.list.Front(); e != nil { 81 value = l.list.Remove(e) 82 } 83 l.mu.Unlock() 84 return 85 } 86 87 // PopBacks removes <max> elements from back of <l> 88 // and returns values of the removed elements as slice. 89 func (l *List) PopBacks(max int) (values []interface{}) { 90 l.mu.Lock() 91 length := l.list.Len() 92 if length > 0 { 93 if max > 0 && max < length { 94 length = max 95 } 96 values = make([]interface{}, length) 97 for i := 0; i < length; i++ { 98 values[i] = l.list.Remove(l.list.Back()) 99 } 100 } 101 l.mu.Unlock() 102 return 103 } 104 105 // PopFronts removes <max> elements from front of <l> 106 // and returns values of the removed elements as slice. 107 func (l *List) PopFronts(max int) (values []interface{}) { 108 l.mu.Lock() 109 length := l.list.Len() 110 if length > 0 { 111 if max > 0 && max < length { 112 length = max 113 } 114 values = make([]interface{}, length) 115 for i := 0; i < length; i++ { 116 values[i] = l.list.Remove(l.list.Front()) 117 } 118 } 119 l.mu.Unlock() 120 return 121 } 122 123 // PopBackAll removes all elements from back of <l> 124 // and returns values of the removed elements as slice. 125 func (l *List) PopBackAll() []interface{} { 126 return l.PopBacks(-1) 127 } 128 129 // PopFrontAll removes all elements from front of <l> 130 // and returns values of the removed elements as slice. 131 func (l *List) PopFrontAll() []interface{} { 132 return l.PopFronts(-1) 133 } 134 135 // FrontAll copies and returns values of all elements from front of <l> as slice. 136 func (l *List) FrontAll() (values []interface{}) { 137 l.mu.RLock() 138 length := l.list.Len() 139 if length > 0 { 140 values = make([]interface{}, length) 141 for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() { 142 values[i] = e.Value 143 } 144 } 145 l.mu.RUnlock() 146 return 147 } 148 149 // BackAll copies and returns values of all elements from back of <l> as slice. 150 func (l *List) BackAll() (values []interface{}) { 151 l.mu.RLock() 152 length := l.list.Len() 153 if length > 0 { 154 values = make([]interface{}, length) 155 for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() { 156 values[i] = e.Value 157 } 158 } 159 l.mu.RUnlock() 160 return 161 } 162 163 // FrontValue returns value of the first element of <l> or nil if the list is empty. 164 func (l *List) FrontValue() (value interface{}) { 165 l.mu.RLock() 166 if e := l.list.Front(); e != nil { 167 value = e.Value 168 } 169 l.mu.RUnlock() 170 return 171 } 172 173 // BackValue returns value of the last element of <l> or nil if the list is empty. 174 func (l *List) BackValue() (value interface{}) { 175 l.mu.RLock() 176 if e := l.list.Back(); e != nil { 177 value = e.Value 178 } 179 l.mu.RUnlock() 180 return 181 } 182 183 // Front returns the first element of list <l> or nil if the list is empty. 184 func (l *List) Front() (e *Element) { 185 l.mu.RLock() 186 e = l.list.Front() 187 l.mu.RUnlock() 188 return 189 } 190 191 // Back returns the last element of list <l> or nil if the list is empty. 192 func (l *List) Back() (e *Element) { 193 l.mu.RLock() 194 e = l.list.Back() 195 l.mu.RUnlock() 196 return 197 } 198 199 // Len returns the number of elements of list <l>. 200 // The complexity is O(1). 201 func (l *List) Len() (length int) { 202 l.mu.RLock() 203 length = l.list.Len() 204 l.mu.RUnlock() 205 return 206 } 207 208 // Size is alias of Len. 209 func (l *List) Size() int { 210 return l.Len() 211 } 212 213 // MoveBefore moves element <e> to its new position before <p>. 214 // If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified. 215 // The element and <p> must not be nil. 216 func (l *List) MoveBefore(e, p *Element) { 217 l.mu.Lock() 218 l.list.MoveBefore(e, p) 219 l.mu.Unlock() 220 } 221 222 // MoveAfter moves element <e> to its new position after <p>. 223 // If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified. 224 // The element and <p> must not be nil. 225 func (l *List) MoveAfter(e, p *Element) { 226 l.mu.Lock() 227 l.list.MoveAfter(e, p) 228 l.mu.Unlock() 229 } 230 231 // MoveToFront moves element <e> to the front of list <l>. 232 // If <e> is not an element of <l>, the list is not modified. 233 // The element must not be nil. 234 func (l *List) MoveToFront(e *Element) { 235 l.mu.Lock() 236 l.list.MoveToFront(e) 237 l.mu.Unlock() 238 } 239 240 // MoveToBack moves element <e> to the back of list <l>. 241 // If <e> is not an element of <l>, the list is not modified. 242 // The element must not be nil. 243 func (l *List) MoveToBack(e *Element) { 244 l.mu.Lock() 245 l.list.MoveToBack(e) 246 l.mu.Unlock() 247 } 248 249 // PushBackList inserts a copy of an other list at the back of list <l>. 250 // The lists <l> and <other> may be the same, but they must not be nil. 251 func (l *List) PushBackList(other *List) { 252 if l != other { 253 other.mu.RLock() 254 defer other.mu.RUnlock() 255 } 256 l.mu.Lock() 257 l.list.PushBackList(other.list) 258 l.mu.Unlock() 259 } 260 261 // PushFrontList inserts a copy of an other list at the front of list <l>. 262 // The lists <l> and <other> may be the same, but they must not be nil. 263 func (l *List) PushFrontList(other *List) { 264 if l != other { 265 other.mu.RLock() 266 defer other.mu.RUnlock() 267 } 268 l.mu.Lock() 269 l.list.PushFrontList(other.list) 270 l.mu.Unlock() 271 } 272 273 // InsertAfter inserts a new element <e> with value <v> immediately after <p> and returns <e>. 274 // If <p> is not an element of <l>, the list is not modified. 275 // The <p> must not be nil. 276 func (l *List) InsertAfter(v interface{}, p *Element) (e *Element) { 277 l.mu.Lock() 278 e = l.list.InsertAfter(v, p) 279 l.mu.Unlock() 280 return 281 } 282 283 // InsertBefore inserts a new element <e> with value <v> immediately before <p> and returns <e>. 284 // If <p> is not an element of <l>, the list is not modified. 285 // The <p> must not be nil. 286 func (l *List) InsertBefore(v interface{}, p *Element) (e *Element) { 287 l.mu.Lock() 288 e = l.list.InsertBefore(v, p) 289 l.mu.Unlock() 290 return 291 } 292 293 // Remove removes <e> from <l> if <e> is an element of list <l>. 294 // It returns the element value e.Value. 295 // The element must not be nil. 296 func (l *List) Remove(e *Element) (value interface{}) { 297 l.mu.Lock() 298 value = l.list.Remove(e) 299 l.mu.Unlock() 300 return 301 } 302 303 // Removes removes multiple elements <es> from <l> if <es> are elements of list <l>. 304 func (l *List) Removes(es []*Element) { 305 l.mu.Lock() 306 for _, e := range es { 307 l.list.Remove(e) 308 } 309 l.mu.Unlock() 310 return 311 } 312 313 // RemoveAll removes all elements from list <l>. 314 func (l *List) RemoveAll() { 315 l.mu.Lock() 316 l.list = list.New() 317 l.mu.Unlock() 318 } 319 320 // See RemoveAll(). 321 func (l *List) Clear() { 322 l.RemoveAll() 323 } 324 325 // RLockFunc locks reading with given callback function <f> within RWMutex.RLock. 326 func (l *List) RLockFunc(f func(list *list.List)) { 327 l.mu.RLock() 328 defer l.mu.RUnlock() 329 f(l.list) 330 } 331 332 // LockFunc locks writing with given callback function <f> within RWMutex.Lock. 333 func (l *List) LockFunc(f func(list *list.List)) { 334 l.mu.Lock() 335 defer l.mu.Unlock() 336 f(l.list) 337 } 338 339 // Iterator is alias of IteratorAsc. 340 func (l *List) Iterator(f func(e *Element) bool) { 341 l.IteratorAsc(f) 342 } 343 344 // IteratorAsc iterates the list in ascending order with given callback function <f>. 345 // If <f> returns true, then it continues iterating; or false to stop. 346 func (l *List) IteratorAsc(f func(e *Element) bool) { 347 l.mu.RLock() 348 length := l.list.Len() 349 if length > 0 { 350 for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() { 351 if !f(e) { 352 break 353 } 354 } 355 } 356 l.mu.RUnlock() 357 } 358 359 // IteratorDesc iterates the list in descending order with given callback function <f>. 360 // If <f> returns true, then it continues iterating; or false to stop. 361 func (l *List) IteratorDesc(f func(e *Element) bool) { 362 l.mu.RLock() 363 length := l.list.Len() 364 if length > 0 { 365 for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() { 366 if !f(e) { 367 break 368 } 369 } 370 } 371 l.mu.RUnlock() 372 }