github.com/wangyougui/gf/v2@v2.6.5/container/glist/glist.go (about) 1 // Copyright GoFrame Author(https://goframe.org). 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/wangyougui/gf. 6 // 7 8 // Package glist provides most commonly used doubly linked list container which also supports concurrent-safe/unsafe switch feature. 9 package glist 10 11 import ( 12 "bytes" 13 "container/list" 14 15 "github.com/wangyougui/gf/v2/internal/deepcopy" 16 "github.com/wangyougui/gf/v2/internal/json" 17 "github.com/wangyougui/gf/v2/internal/rwmutex" 18 "github.com/wangyougui/gf/v2/util/gconv" 19 ) 20 21 type ( 22 // List is a doubly linked list containing a concurrent-safe/unsafe switch. 23 // The switch should be set when its initialization and cannot be changed then. 24 List struct { 25 mu rwmutex.RWMutex 26 list *list.List 27 } 28 // Element the item type of the list. 29 Element = list.Element 30 ) 31 32 // New creates and returns a new empty doubly linked list. 33 func New(safe ...bool) *List { 34 return &List{ 35 mu: rwmutex.Create(safe...), 36 list: list.New(), 37 } 38 } 39 40 // NewFrom creates and returns a list from a copy of given slice `array`. 41 // The parameter `safe` is used to specify whether using list in concurrent-safety, 42 // which is false in default. 43 func NewFrom(array []interface{}, safe ...bool) *List { 44 l := list.New() 45 for _, v := range array { 46 l.PushBack(v) 47 } 48 return &List{ 49 mu: rwmutex.Create(safe...), 50 list: l, 51 } 52 } 53 54 // PushFront inserts a new element `e` with value `v` at the front of list `l` and returns `e`. 55 func (l *List) PushFront(v interface{}) (e *Element) { 56 l.mu.Lock() 57 if l.list == nil { 58 l.list = list.New() 59 } 60 e = l.list.PushFront(v) 61 l.mu.Unlock() 62 return 63 } 64 65 // PushBack inserts a new element `e` with value `v` at the back of list `l` and returns `e`. 66 func (l *List) PushBack(v interface{}) (e *Element) { 67 l.mu.Lock() 68 if l.list == nil { 69 l.list = list.New() 70 } 71 e = l.list.PushBack(v) 72 l.mu.Unlock() 73 return 74 } 75 76 // PushFronts inserts multiple new elements with values `values` at the front of list `l`. 77 func (l *List) PushFronts(values []interface{}) { 78 l.mu.Lock() 79 if l.list == nil { 80 l.list = list.New() 81 } 82 for _, v := range values { 83 l.list.PushFront(v) 84 } 85 l.mu.Unlock() 86 } 87 88 // PushBacks inserts multiple new elements with values `values` at the back of list `l`. 89 func (l *List) PushBacks(values []interface{}) { 90 l.mu.Lock() 91 if l.list == nil { 92 l.list = list.New() 93 } 94 for _, v := range values { 95 l.list.PushBack(v) 96 } 97 l.mu.Unlock() 98 } 99 100 // PopBack removes the element from back of `l` and returns the value of the element. 101 func (l *List) PopBack() (value interface{}) { 102 l.mu.Lock() 103 defer l.mu.Unlock() 104 if l.list == nil { 105 l.list = list.New() 106 return 107 } 108 if e := l.list.Back(); e != nil { 109 value = l.list.Remove(e) 110 } 111 return 112 } 113 114 // PopFront removes the element from front of `l` and returns the value of the element. 115 func (l *List) PopFront() (value interface{}) { 116 l.mu.Lock() 117 defer l.mu.Unlock() 118 if l.list == nil { 119 l.list = list.New() 120 return 121 } 122 if e := l.list.Front(); e != nil { 123 value = l.list.Remove(e) 124 } 125 return 126 } 127 128 // PopBacks removes `max` elements from back of `l` 129 // and returns values of the removed elements as slice. 130 func (l *List) PopBacks(max int) (values []interface{}) { 131 l.mu.Lock() 132 defer l.mu.Unlock() 133 if l.list == nil { 134 l.list = list.New() 135 return 136 } 137 length := l.list.Len() 138 if length > 0 { 139 if max > 0 && max < length { 140 length = max 141 } 142 values = make([]interface{}, length) 143 for i := 0; i < length; i++ { 144 values[i] = l.list.Remove(l.list.Back()) 145 } 146 } 147 return 148 } 149 150 // PopFronts removes `max` elements from front of `l` 151 // and returns values of the removed elements as slice. 152 func (l *List) PopFronts(max int) (values []interface{}) { 153 l.mu.Lock() 154 defer l.mu.Unlock() 155 if l.list == nil { 156 l.list = list.New() 157 return 158 } 159 length := l.list.Len() 160 if length > 0 { 161 if max > 0 && max < length { 162 length = max 163 } 164 values = make([]interface{}, length) 165 for i := 0; i < length; i++ { 166 values[i] = l.list.Remove(l.list.Front()) 167 } 168 } 169 return 170 } 171 172 // PopBackAll removes all elements from back of `l` 173 // and returns values of the removed elements as slice. 174 func (l *List) PopBackAll() []interface{} { 175 return l.PopBacks(-1) 176 } 177 178 // PopFrontAll removes all elements from front of `l` 179 // and returns values of the removed elements as slice. 180 func (l *List) PopFrontAll() []interface{} { 181 return l.PopFronts(-1) 182 } 183 184 // FrontAll copies and returns values of all elements from front of `l` as slice. 185 func (l *List) FrontAll() (values []interface{}) { 186 l.mu.RLock() 187 defer l.mu.RUnlock() 188 if l.list == nil { 189 return 190 } 191 length := l.list.Len() 192 if length > 0 { 193 values = make([]interface{}, length) 194 for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() { 195 values[i] = e.Value 196 } 197 } 198 return 199 } 200 201 // BackAll copies and returns values of all elements from back of `l` as slice. 202 func (l *List) BackAll() (values []interface{}) { 203 l.mu.RLock() 204 defer l.mu.RUnlock() 205 if l.list == nil { 206 return 207 } 208 length := l.list.Len() 209 if length > 0 { 210 values = make([]interface{}, length) 211 for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() { 212 values[i] = e.Value 213 } 214 } 215 return 216 } 217 218 // FrontValue returns value of the first element of `l` or nil if the list is empty. 219 func (l *List) FrontValue() (value interface{}) { 220 l.mu.RLock() 221 defer l.mu.RUnlock() 222 if l.list == nil { 223 return 224 } 225 if e := l.list.Front(); e != nil { 226 value = e.Value 227 } 228 return 229 } 230 231 // BackValue returns value of the last element of `l` or nil if the list is empty. 232 func (l *List) BackValue() (value interface{}) { 233 l.mu.RLock() 234 defer l.mu.RUnlock() 235 if l.list == nil { 236 return 237 } 238 if e := l.list.Back(); e != nil { 239 value = e.Value 240 } 241 return 242 } 243 244 // Front returns the first element of list `l` or nil if the list is empty. 245 func (l *List) Front() (e *Element) { 246 l.mu.RLock() 247 defer l.mu.RUnlock() 248 if l.list == nil { 249 return 250 } 251 e = l.list.Front() 252 return 253 } 254 255 // Back returns the last element of list `l` or nil if the list is empty. 256 func (l *List) Back() (e *Element) { 257 l.mu.RLock() 258 defer l.mu.RUnlock() 259 if l.list == nil { 260 return 261 } 262 e = l.list.Back() 263 return 264 } 265 266 // Len returns the number of elements of list `l`. 267 // The complexity is O(1). 268 func (l *List) Len() (length int) { 269 l.mu.RLock() 270 defer l.mu.RUnlock() 271 if l.list == nil { 272 return 273 } 274 length = l.list.Len() 275 return 276 } 277 278 // Size is alias of Len. 279 func (l *List) Size() int { 280 return l.Len() 281 } 282 283 // MoveBefore moves element `e` to its new position before `p`. 284 // If `e` or `p` is not an element of `l`, or `e` == `p`, the list is not modified. 285 // The element and `p` must not be nil. 286 func (l *List) MoveBefore(e, p *Element) { 287 l.mu.Lock() 288 defer l.mu.Unlock() 289 if l.list == nil { 290 l.list = list.New() 291 } 292 l.list.MoveBefore(e, p) 293 } 294 295 // MoveAfter moves element `e` to its new position after `p`. 296 // If `e` or `p` is not an element of `l`, or `e` == `p`, the list is not modified. 297 // The element and `p` must not be nil. 298 func (l *List) MoveAfter(e, p *Element) { 299 l.mu.Lock() 300 defer l.mu.Unlock() 301 if l.list == nil { 302 l.list = list.New() 303 } 304 l.list.MoveAfter(e, p) 305 } 306 307 // MoveToFront moves element `e` to the front of list `l`. 308 // If `e` is not an element of `l`, the list is not modified. 309 // The element must not be nil. 310 func (l *List) MoveToFront(e *Element) { 311 l.mu.Lock() 312 defer l.mu.Unlock() 313 if l.list == nil { 314 l.list = list.New() 315 } 316 l.list.MoveToFront(e) 317 } 318 319 // MoveToBack moves element `e` to the back of list `l`. 320 // If `e` is not an element of `l`, the list is not modified. 321 // The element must not be nil. 322 func (l *List) MoveToBack(e *Element) { 323 l.mu.Lock() 324 defer l.mu.Unlock() 325 if l.list == nil { 326 l.list = list.New() 327 } 328 l.list.MoveToBack(e) 329 } 330 331 // PushBackList inserts a copy of an other list at the back of list `l`. 332 // The lists `l` and `other` may be the same, but they must not be nil. 333 func (l *List) PushBackList(other *List) { 334 if l != other { 335 other.mu.RLock() 336 defer other.mu.RUnlock() 337 } 338 l.mu.Lock() 339 defer l.mu.Unlock() 340 if l.list == nil { 341 l.list = list.New() 342 } 343 l.list.PushBackList(other.list) 344 } 345 346 // PushFrontList inserts a copy of an other list at the front of list `l`. 347 // The lists `l` and `other` may be the same, but they must not be nil. 348 func (l *List) PushFrontList(other *List) { 349 if l != other { 350 other.mu.RLock() 351 defer other.mu.RUnlock() 352 } 353 l.mu.Lock() 354 defer l.mu.Unlock() 355 if l.list == nil { 356 l.list = list.New() 357 } 358 l.list.PushFrontList(other.list) 359 } 360 361 // InsertAfter inserts a new element `e` with value `v` immediately after `p` and returns `e`. 362 // If `p` is not an element of `l`, the list is not modified. 363 // The `p` must not be nil. 364 func (l *List) InsertAfter(p *Element, v interface{}) (e *Element) { 365 l.mu.Lock() 366 defer l.mu.Unlock() 367 if l.list == nil { 368 l.list = list.New() 369 } 370 e = l.list.InsertAfter(v, p) 371 return 372 } 373 374 // InsertBefore inserts a new element `e` with value `v` immediately before `p` and returns `e`. 375 // If `p` is not an element of `l`, the list is not modified. 376 // The `p` must not be nil. 377 func (l *List) InsertBefore(p *Element, v interface{}) (e *Element) { 378 l.mu.Lock() 379 defer l.mu.Unlock() 380 if l.list == nil { 381 l.list = list.New() 382 } 383 e = l.list.InsertBefore(v, p) 384 return 385 } 386 387 // Remove removes `e` from `l` if `e` is an element of list `l`. 388 // It returns the element value e.Value. 389 // The element must not be nil. 390 func (l *List) Remove(e *Element) (value interface{}) { 391 l.mu.Lock() 392 defer l.mu.Unlock() 393 if l.list == nil { 394 l.list = list.New() 395 } 396 value = l.list.Remove(e) 397 return 398 } 399 400 // Removes removes multiple elements `es` from `l` if `es` are elements of list `l`. 401 func (l *List) Removes(es []*Element) { 402 l.mu.Lock() 403 defer l.mu.Unlock() 404 if l.list == nil { 405 l.list = list.New() 406 } 407 for _, e := range es { 408 l.list.Remove(e) 409 } 410 } 411 412 // RemoveAll removes all elements from list `l`. 413 func (l *List) RemoveAll() { 414 l.mu.Lock() 415 l.list = list.New() 416 l.mu.Unlock() 417 } 418 419 // Clear is alias of RemoveAll. 420 func (l *List) Clear() { 421 l.RemoveAll() 422 } 423 424 // RLockFunc locks reading with given callback function `f` within RWMutex.RLock. 425 func (l *List) RLockFunc(f func(list *list.List)) { 426 l.mu.RLock() 427 defer l.mu.RUnlock() 428 if l.list != nil { 429 f(l.list) 430 } 431 } 432 433 // LockFunc locks writing with given callback function `f` within RWMutex.Lock. 434 func (l *List) LockFunc(f func(list *list.List)) { 435 l.mu.Lock() 436 defer l.mu.Unlock() 437 if l.list == nil { 438 l.list = list.New() 439 } 440 f(l.list) 441 } 442 443 // Iterator is alias of IteratorAsc. 444 func (l *List) Iterator(f func(e *Element) bool) { 445 l.IteratorAsc(f) 446 } 447 448 // IteratorAsc iterates the list readonly in ascending order with given callback function `f`. 449 // If `f` returns true, then it continues iterating; or false to stop. 450 func (l *List) IteratorAsc(f func(e *Element) bool) { 451 l.mu.RLock() 452 defer l.mu.RUnlock() 453 if l.list == nil { 454 return 455 } 456 length := l.list.Len() 457 if length > 0 { 458 for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() { 459 if !f(e) { 460 break 461 } 462 } 463 } 464 } 465 466 // IteratorDesc iterates the list readonly in descending order with given callback function `f`. 467 // If `f` returns true, then it continues iterating; or false to stop. 468 func (l *List) IteratorDesc(f func(e *Element) bool) { 469 l.mu.RLock() 470 defer l.mu.RUnlock() 471 if l.list == nil { 472 return 473 } 474 length := l.list.Len() 475 if length > 0 { 476 for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() { 477 if !f(e) { 478 break 479 } 480 } 481 } 482 } 483 484 // Join joins list elements with a string `glue`. 485 func (l *List) Join(glue string) string { 486 l.mu.RLock() 487 defer l.mu.RUnlock() 488 if l.list == nil { 489 return "" 490 } 491 buffer := bytes.NewBuffer(nil) 492 length := l.list.Len() 493 if length > 0 { 494 for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() { 495 buffer.WriteString(gconv.String(e.Value)) 496 if i != length-1 { 497 buffer.WriteString(glue) 498 } 499 } 500 } 501 return buffer.String() 502 } 503 504 // String returns current list as a string. 505 func (l *List) String() string { 506 if l == nil { 507 return "" 508 } 509 return "[" + l.Join(",") + "]" 510 } 511 512 // MarshalJSON implements the interface MarshalJSON for json.Marshal. 513 func (l List) MarshalJSON() ([]byte, error) { 514 return json.Marshal(l.FrontAll()) 515 } 516 517 // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. 518 func (l *List) UnmarshalJSON(b []byte) error { 519 l.mu.Lock() 520 defer l.mu.Unlock() 521 if l.list == nil { 522 l.list = list.New() 523 } 524 var array []interface{} 525 if err := json.UnmarshalUseNumber(b, &array); err != nil { 526 return err 527 } 528 l.PushBacks(array) 529 return nil 530 } 531 532 // UnmarshalValue is an interface implement which sets any type of value for list. 533 func (l *List) UnmarshalValue(value interface{}) (err error) { 534 l.mu.Lock() 535 defer l.mu.Unlock() 536 if l.list == nil { 537 l.list = list.New() 538 } 539 var array []interface{} 540 switch value.(type) { 541 case string, []byte: 542 err = json.UnmarshalUseNumber(gconv.Bytes(value), &array) 543 default: 544 array = gconv.SliceAny(value) 545 } 546 l.PushBacks(array) 547 return err 548 } 549 550 // DeepCopy implements interface for deep copy of current type. 551 func (l *List) DeepCopy() interface{} { 552 if l == nil { 553 return nil 554 } 555 556 l.mu.RLock() 557 defer l.mu.RUnlock() 558 559 if l.list == nil { 560 return nil 561 } 562 var ( 563 length = l.list.Len() 564 values = make([]interface{}, length) 565 ) 566 if length > 0 { 567 for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() { 568 values[i] = deepcopy.Copy(e.Value) 569 } 570 } 571 return NewFrom(values, l.mu.IsSafe()) 572 }