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  }