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  }