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