Files
gf/container/glist/glist.go

546 lines
12 KiB
Go
Raw Normal View History

// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
2017-12-29 16:03:30 +08:00
//
// This Source Code Form is subject to the terms of the MIT License.
2018-12-30 11:08:07 +08:00
// If a copy of the MIT was not distributed with l file,
// You can obtain one at https://github.com/gogf/gf.
2017-12-29 16:03:30 +08:00
//
2017-12-31 18:19:58 +08:00
2020-05-22 12:04:58 +08:00
// Package glist provides most commonly used doubly linked list container which also supports concurrent-safe/unsafe switch feature.
2017-11-23 10:21:28 +08:00
package glist
import (
"bytes"
2019-06-19 09:06:52 +08:00
"container/list"
"encoding/json"
"github.com/gogf/gf/util/gconv"
2019-07-29 21:01:19 +08:00
"github.com/gogf/gf/internal/rwmutex"
2017-11-23 10:21:28 +08:00
)
type (
2020-05-22 12:04:58 +08:00
// List is a doubly linked list containing a concurrent-safe/unsafe switch.
// The switch should be set when its initialization and cannot be changed then.
List struct {
mu rwmutex.RWMutex
2020-06-04 20:13:33 +08:00
list *list.List
}
2020-05-22 12:04:58 +08:00
// Element the item type of the list.
Element = list.Element
)
2019-01-09 12:54:37 +08:00
// New creates and returns a new empty doubly linked list.
func New(safe ...bool) *List {
2019-06-19 09:06:52 +08:00
return &List{
mu: rwmutex.Create(safe...),
2020-06-04 20:13:33 +08:00
list: list.New(),
2019-06-19 09:06:52 +08:00
}
2017-11-23 10:21:28 +08:00
}
// NewFrom creates and returns a list from a copy of given slice <array>.
2019-11-30 18:33:51 +08:00
// The parameter <safe> is used to specify whether using list in concurrent-safety,
// which is false in default.
func NewFrom(array []interface{}, safe ...bool) *List {
2020-06-04 20:13:33 +08:00
l := list.New()
for _, v := range array {
l.PushBack(v)
}
return &List{
mu: rwmutex.Create(safe...),
list: l,
}
}
// PushFront inserts a new element <e> with value <v> at the front of list <l> and returns <e>.
2019-01-09 12:54:37 +08:00
func (l *List) PushFront(v interface{}) (e *Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
e = l.list.PushFront(v)
l.mu.Unlock()
return
2017-11-23 10:21:28 +08:00
}
// PushBack inserts a new element <e> with value <v> at the back of list <l> and returns <e>.
2019-01-09 12:54:37 +08:00
func (l *List) PushBack(v interface{}) (e *Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
e = l.list.PushBack(v)
l.mu.Unlock()
return
2017-11-23 10:21:28 +08:00
}
// PushFronts inserts multiple new elements with values <values> at the front of list <l>.
func (l *List) PushFronts(values []interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
l.list = list.New()
}
2019-01-06 16:43:42 +08:00
for _, v := range values {
2019-06-19 09:06:52 +08:00
l.list.PushFront(v)
2019-01-06 16:43:42 +08:00
}
2019-06-19 09:06:52 +08:00
l.mu.Unlock()
2017-11-23 10:21:28 +08:00
}
// PushBacks inserts multiple new elements with values <values> at the back of list <l>.
func (l *List) PushBacks(values []interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
for _, v := range values {
l.list.PushBack(v)
}
l.mu.Unlock()
2017-11-23 10:21:28 +08:00
}
// PopBack removes the element from back of <l> and returns the value of the element.
2019-01-09 12:54:37 +08:00
func (l *List) PopBack() (value interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
return
}
2019-01-09 12:54:37 +08:00
if e := l.list.Back(); e != nil {
2019-06-19 09:06:52 +08:00
value = l.list.Remove(e)
2017-11-23 10:21:28 +08:00
}
2019-01-09 12:54:37 +08:00
return
2017-11-23 10:21:28 +08:00
}
// PopFront removes the element from front of <l> and returns the value of the element.
2019-01-09 12:54:37 +08:00
func (l *List) PopFront() (value interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
return
}
2019-06-19 09:06:52 +08:00
if e := l.list.Front(); e != nil {
value = l.list.Remove(e)
}
return
}
// PopBacks removes <max> elements from back of <l>
// and returns values of the removed elements as slice.
func (l *List) PopBacks(max int) (values []interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
return
}
2019-06-19 09:06:52 +08:00
length := l.list.Len()
if length > 0 {
if max > 0 && max < length {
length = max
}
values = make([]interface{}, length)
for i := 0; i < length; i++ {
values[i] = l.list.Remove(l.list.Back())
}
}
return
2017-11-23 10:21:28 +08:00
}
// PopFronts removes <max> elements from front of <l>
// and returns values of the removed elements as slice.
func (l *List) PopFronts(max int) (values []interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
return
}
2019-06-19 09:06:52 +08:00
length := l.list.Len()
if length > 0 {
if max > 0 && max < length {
length = max
}
values = make([]interface{}, length)
for i := 0; i < length; i++ {
values[i] = l.list.Remove(l.list.Front())
}
}
return
}
2017-11-23 10:21:28 +08:00
// PopBackAll removes all elements from back of <l>
// and returns values of the removed elements as slice.
2018-12-30 11:08:07 +08:00
func (l *List) PopBackAll() []interface{} {
return l.PopBacks(-1)
2017-11-23 10:21:28 +08:00
}
// PopFrontAll removes all elements from front of <l>
// and returns values of the removed elements as slice.
2018-12-30 11:08:07 +08:00
func (l *List) PopFrontAll() []interface{} {
2019-06-19 09:06:52 +08:00
return l.PopFronts(-1)
}
// FrontAll copies and returns values of all elements from front of <l> as slice.
2019-01-09 12:54:37 +08:00
func (l *List) FrontAll() (values []interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.RLock()
2020-06-04 20:13:33 +08:00
defer l.mu.RUnlock()
if l.list == nil {
return
}
2019-06-19 09:06:52 +08:00
length := l.list.Len()
if length > 0 {
values = make([]interface{}, length)
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
values[i] = e.Value
}
}
return
2017-11-23 10:21:28 +08:00
}
// BackAll copies and returns values of all elements from back of <l> as slice.
2019-01-09 12:54:37 +08:00
func (l *List) BackAll() (values []interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.RLock()
2020-06-04 20:13:33 +08:00
defer l.mu.RUnlock()
if l.list == nil {
return
}
2019-01-09 12:54:37 +08:00
length := l.list.Len()
if length > 0 {
2019-06-19 09:06:52 +08:00
values = make([]interface{}, length)
for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
values[i] = e.Value
}
}
2019-01-09 12:54:37 +08:00
return
2017-11-23 10:21:28 +08:00
}
// FrontValue returns value of the first element of <l> or nil if the list is empty.
func (l *List) FrontValue() (value interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.RLock()
2020-06-04 20:13:33 +08:00
defer l.mu.RUnlock()
if l.list == nil {
return
}
2019-06-19 09:06:52 +08:00
if e := l.list.Front(); e != nil {
value = e.Value
}
return
2017-11-23 10:21:28 +08:00
}
// BackValue returns value of the last element of <l> or nil if the list is empty.
func (l *List) BackValue() (value interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.RLock()
2020-06-04 20:13:33 +08:00
defer l.mu.RUnlock()
if l.list == nil {
return
}
2019-06-19 09:06:52 +08:00
if e := l.list.Back(); e != nil {
value = e.Value
}
return
2017-11-23 10:21:28 +08:00
}
// Front returns the first element of list <l> or nil if the list is empty.
2019-01-09 12:54:37 +08:00
func (l *List) Front() (e *Element) {
2019-06-19 09:06:52 +08:00
l.mu.RLock()
2020-06-04 20:13:33 +08:00
defer l.mu.RUnlock()
if l.list == nil {
return
}
2019-06-19 09:06:52 +08:00
e = l.list.Front()
return
2017-11-23 10:21:28 +08:00
}
// Back returns the last element of list <l> or nil if the list is empty.
2019-01-09 12:54:37 +08:00
func (l *List) Back() (e *Element) {
2019-06-19 09:06:52 +08:00
l.mu.RLock()
2020-06-04 20:13:33 +08:00
defer l.mu.RUnlock()
if l.list == nil {
return
}
2019-06-19 09:06:52 +08:00
e = l.list.Back()
return
2017-11-23 10:21:28 +08:00
}
// Len returns the number of elements of list <l>.
// The complexity is O(1).
2019-01-09 12:54:37 +08:00
func (l *List) Len() (length int) {
2019-06-19 09:06:52 +08:00
l.mu.RLock()
2020-06-04 20:13:33 +08:00
defer l.mu.RUnlock()
if l.list == nil {
return
}
2019-06-19 09:06:52 +08:00
length = l.list.Len()
2019-01-09 12:54:37 +08:00
return
2019-01-01 19:43:31 +08:00
}
2019-06-15 18:30:09 +08:00
// Size is alias of Len.
2019-06-01 15:11:32 +08:00
func (l *List) Size() int {
return l.Len()
}
// MoveBefore moves element <e> to its new position before <p>.
// If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified.
// The element and <p> must not be nil.
2019-01-03 19:11:54 +08:00
func (l *List) MoveBefore(e, p *Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
l.list.MoveBefore(e, p)
2019-01-01 19:43:31 +08:00
}
// MoveAfter moves element <e> to its new position after <p>.
// If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified.
// The element and <p> must not be nil.
2019-01-03 19:11:54 +08:00
func (l *List) MoveAfter(e, p *Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
l.list.MoveAfter(e, p)
2019-01-01 19:43:31 +08:00
}
// MoveToFront moves element <e> to the front of list <l>.
// If <e> is not an element of <l>, the list is not modified.
// The element must not be nil.
2019-01-01 19:43:31 +08:00
func (l *List) MoveToFront(e *Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
l.list.MoveToFront(e)
2019-01-01 19:43:31 +08:00
}
// MoveToBack moves element <e> to the back of list <l>.
// If <e> is not an element of <l>, the list is not modified.
// The element must not be nil.
2019-01-01 19:43:31 +08:00
func (l *List) MoveToBack(e *Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
l.list.MoveToBack(e)
2019-01-01 19:43:31 +08:00
}
// PushBackList inserts a copy of an other list at the back of list <l>.
// The lists <l> and <other> may be the same, but they must not be nil.
2019-01-01 19:43:31 +08:00
func (l *List) PushBackList(other *List) {
2019-06-19 09:06:52 +08:00
if l != other {
other.mu.RLock()
defer other.mu.RUnlock()
}
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
l.list.PushBackList(other.list)
2019-01-01 19:43:31 +08:00
}
// PushFrontList inserts a copy of an other list at the front of list <l>.
// The lists <l> and <other> may be the same, but they must not be nil.
2019-01-01 19:43:31 +08:00
func (l *List) PushFrontList(other *List) {
2019-06-19 09:06:52 +08:00
if l != other {
other.mu.RLock()
defer other.mu.RUnlock()
}
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
l.list.PushFrontList(other.list)
2017-11-23 10:21:28 +08:00
}
2018-12-30 11:08:07 +08:00
// InsertAfter inserts a new element <e> with value <v> immediately after <p> and returns <e>.
// If <p> is not an element of <l>, the list is not modified.
// The <p> must not be nil.
func (l *List) InsertAfter(p *Element, v interface{}) (e *Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
e = l.list.InsertAfter(v, p)
return
2019-01-09 12:54:37 +08:00
}
// InsertBefore inserts a new element <e> with value <v> immediately before <p> and returns <e>.
// If <p> is not an element of <l>, the list is not modified.
// The <p> must not be nil.
func (l *List) InsertBefore(p *Element, v interface{}) (e *Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
e = l.list.InsertBefore(v, p)
return
2019-01-09 12:54:37 +08:00
}
// Remove removes <e> from <l> if <e> is an element of list <l>.
// It returns the element value e.Value.
// The element must not be nil.
2019-01-09 12:54:37 +08:00
func (l *List) Remove(e *Element) (value interface{}) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
value = l.list.Remove(e)
return
2019-01-09 12:54:37 +08:00
}
// Removes removes multiple elements <es> from <l> if <es> are elements of list <l>.
func (l *List) Removes(es []*Element) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
defer l.mu.Unlock()
if l.list == nil {
l.list = list.New()
}
2019-06-19 09:06:52 +08:00
for _, e := range es {
l.list.Remove(e)
}
return
2019-01-11 13:46:40 +08:00
}
// RemoveAll removes all elements from list <l>.
2019-01-09 12:54:37 +08:00
func (l *List) RemoveAll() {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
2020-06-04 20:13:33 +08:00
l.list = list.New()
2019-06-19 09:06:52 +08:00
l.mu.Unlock()
2019-01-09 12:54:37 +08:00
}
// See RemoveAll().
func (l *List) Clear() {
l.RemoveAll()
}
// RLockFunc locks reading with given callback function <f> within RWMutex.RLock.
2019-01-09 12:54:37 +08:00
func (l *List) RLockFunc(f func(list *list.List)) {
2019-06-19 09:06:52 +08:00
l.mu.RLock()
defer l.mu.RUnlock()
2020-06-04 20:13:33 +08:00
if l.list != nil {
f(l.list)
}
2019-01-09 12:54:37 +08:00
}
// LockFunc locks writing with given callback function <f> within RWMutex.Lock.
2019-01-09 12:54:37 +08:00
func (l *List) LockFunc(f func(list *list.List)) {
2019-06-19 09:06:52 +08:00
l.mu.Lock()
defer l.mu.Unlock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
l.list = list.New()
}
f(l.list)
2019-05-12 20:43:52 +08:00
}
// Iterator is alias of IteratorAsc.
2019-06-19 09:06:52 +08:00
func (l *List) Iterator(f func(e *Element) bool) {
2019-05-12 20:43:52 +08:00
l.IteratorAsc(f)
}
// IteratorAsc iterates the list readonly in ascending order with given callback function <f>.
2019-05-12 20:43:52 +08:00
// If <f> returns true, then it continues iterating; or false to stop.
2019-06-19 09:06:52 +08:00
func (l *List) IteratorAsc(f func(e *Element) bool) {
2019-05-12 20:43:52 +08:00
l.mu.RLock()
defer l.mu.RUnlock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
return
}
2019-05-12 20:43:52 +08:00
length := l.list.Len()
if length > 0 {
2019-06-19 09:06:52 +08:00
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
2019-05-12 20:43:52 +08:00
if !f(e) {
break
}
}
}
}
// IteratorDesc iterates the list readonly in descending order with given callback function <f>.
2019-05-12 20:43:52 +08:00
// If <f> returns true, then it continues iterating; or false to stop.
2019-06-19 09:06:52 +08:00
func (l *List) IteratorDesc(f func(e *Element) bool) {
2019-05-12 20:43:52 +08:00
l.mu.RLock()
defer l.mu.RUnlock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
return
}
2019-05-12 20:43:52 +08:00
length := l.list.Len()
if length > 0 {
2019-06-19 09:06:52 +08:00
for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
2019-05-12 20:43:52 +08:00
if !f(e) {
break
}
}
}
2019-06-19 09:06:52 +08:00
}
// Join joins list elements with a string <glue>.
func (l *List) Join(glue string) string {
l.mu.RLock()
defer l.mu.RUnlock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
return ""
}
buffer := bytes.NewBuffer(nil)
length := l.list.Len()
if length > 0 {
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
2020-06-04 20:13:33 +08:00
buffer.WriteString(gconv.String(e.Value))
if i != length-1 {
buffer.WriteString(glue)
}
}
}
return buffer.String()
}
// String returns current list as a string.
func (l *List) String() string {
return "[" + l.Join(",") + "]"
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (l *List) MarshalJSON() ([]byte, error) {
return json.Marshal(l.FrontAll())
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (l *List) UnmarshalJSON(b []byte) error {
l.mu.Lock()
defer l.mu.Unlock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
l.list = list.New()
}
var array []interface{}
if err := json.Unmarshal(b, &array); err != nil {
return err
}
l.PushBacks(array)
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for list.
func (l *List) UnmarshalValue(value interface{}) (err error) {
l.mu.Lock()
defer l.mu.Unlock()
2020-06-04 20:13:33 +08:00
if l.list == nil {
l.list = list.New()
}
var array []interface{}
switch value.(type) {
case string, []byte:
err = json.Unmarshal(gconv.Bytes(value), &array)
default:
array = gconv.SliceAny(value)
}
l.PushBacks(array)
return err
}