github.com/gogf/gf@v1.16.9/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 concurrent-safe/unsafe switch feature.
     9  package glist
    10  
    11  import (
    12  	"bytes"
    13  	"container/list"
    14  	"github.com/gogf/gf/internal/json"
    15  	"github.com/gogf/gf/util/gconv"
    16  
    17  	"github.com/gogf/gf/internal/rwmutex"
    18  )
    19  
    20  type (
    21  	// List is a doubly linked list containing a concurrent-safe/unsafe switch.
    22  	// The switch should be set when its initialization and cannot be changed then.
    23  	List struct {
    24  		mu   rwmutex.RWMutex
    25  		list *list.List
    26  	}
    27  	// Element the item type of the list.
    28  	Element = list.Element
    29  )
    30  
    31  // New creates and returns a new empty doubly linked list.
    32  func New(safe ...bool) *List {
    33  	return &List{
    34  		mu:   rwmutex.Create(safe...),
    35  		list: list.New(),
    36  	}
    37  }
    38  
    39  // NewFrom creates and returns a list from a copy of given slice <array>.
    40  // The parameter <safe> is used to specify whether using list in concurrent-safety,
    41  // which is false in default.
    42  func NewFrom(array []interface{}, safe ...bool) *List {
    43  	l := list.New()
    44  	for _, v := range array {
    45  		l.PushBack(v)
    46  	}
    47  	return &List{
    48  		mu:   rwmutex.Create(safe...),
    49  		list: l,
    50  	}
    51  }
    52  
    53  // PushFront inserts a new element <e> with value <v> at the front of list <l> and returns <e>.
    54  func (l *List) PushFront(v interface{}) (e *Element) {
    55  	l.mu.Lock()
    56  	if l.list == nil {
    57  		l.list = list.New()
    58  	}
    59  	e = l.list.PushFront(v)
    60  	l.mu.Unlock()
    61  	return
    62  }
    63  
    64  // PushBack inserts a new element <e> with value <v> at the back of list <l> and returns <e>.
    65  func (l *List) PushBack(v interface{}) (e *Element) {
    66  	l.mu.Lock()
    67  	if l.list == nil {
    68  		l.list = list.New()
    69  	}
    70  	e = l.list.PushBack(v)
    71  	l.mu.Unlock()
    72  	return
    73  }
    74  
    75  // PushFronts inserts multiple new elements with values <values> at the front of list <l>.
    76  func (l *List) PushFronts(values []interface{}) {
    77  	l.mu.Lock()
    78  	if l.list == nil {
    79  		l.list = list.New()
    80  	}
    81  	for _, v := range values {
    82  		l.list.PushFront(v)
    83  	}
    84  	l.mu.Unlock()
    85  }
    86  
    87  // PushBacks inserts multiple new elements with values <values> at the back of list <l>.
    88  func (l *List) PushBacks(values []interface{}) {
    89  	l.mu.Lock()
    90  	if l.list == nil {
    91  		l.list = list.New()
    92  	}
    93  	for _, v := range values {
    94  		l.list.PushBack(v)
    95  	}
    96  	l.mu.Unlock()
    97  }
    98  
    99  // PopBack removes the element from back of <l> and returns the value of the element.
   100  func (l *List) PopBack() (value interface{}) {
   101  	l.mu.Lock()
   102  	defer l.mu.Unlock()
   103  	if l.list == nil {
   104  		l.list = list.New()
   105  		return
   106  	}
   107  	if e := l.list.Back(); e != nil {
   108  		value = l.list.Remove(e)
   109  	}
   110  	return
   111  }
   112  
   113  // PopFront removes the element from front of <l> and returns the value of the element.
   114  func (l *List) PopFront() (value interface{}) {
   115  	l.mu.Lock()
   116  	defer l.mu.Unlock()
   117  	if l.list == nil {
   118  		l.list = list.New()
   119  		return
   120  	}
   121  	if e := l.list.Front(); e != nil {
   122  		value = l.list.Remove(e)
   123  	}
   124  	return
   125  }
   126  
   127  // PopBacks removes <max> elements from back of <l>
   128  // and returns values of the removed elements as slice.
   129  func (l *List) PopBacks(max int) (values []interface{}) {
   130  	l.mu.Lock()
   131  	defer l.mu.Unlock()
   132  	if l.list == nil {
   133  		l.list = list.New()
   134  		return
   135  	}
   136  	length := l.list.Len()
   137  	if length > 0 {
   138  		if max > 0 && max < length {
   139  			length = max
   140  		}
   141  		values = make([]interface{}, length)
   142  		for i := 0; i < length; i++ {
   143  			values[i] = l.list.Remove(l.list.Back())
   144  		}
   145  	}
   146  	return
   147  }
   148  
   149  // PopFronts removes <max> elements from front of <l>
   150  // and returns values of the removed elements as slice.
   151  func (l *List) PopFronts(max int) (values []interface{}) {
   152  	l.mu.Lock()
   153  	defer l.mu.Unlock()
   154  	if l.list == nil {
   155  		l.list = list.New()
   156  		return
   157  	}
   158  	length := l.list.Len()
   159  	if length > 0 {
   160  		if max > 0 && max < length {
   161  			length = max
   162  		}
   163  		values = make([]interface{}, length)
   164  		for i := 0; i < length; i++ {
   165  			values[i] = l.list.Remove(l.list.Front())
   166  		}
   167  	}
   168  	return
   169  }
   170  
   171  // PopBackAll removes all elements from back of <l>
   172  // and returns values of the removed elements as slice.
   173  func (l *List) PopBackAll() []interface{} {
   174  	return l.PopBacks(-1)
   175  }
   176  
   177  // PopFrontAll removes all elements from front of <l>
   178  // and returns values of the removed elements as slice.
   179  func (l *List) PopFrontAll() []interface{} {
   180  	return l.PopFronts(-1)
   181  }
   182  
   183  // FrontAll copies and returns values of all elements from front of <l> as slice.
   184  func (l *List) FrontAll() (values []interface{}) {
   185  	l.mu.RLock()
   186  	defer l.mu.RUnlock()
   187  	if l.list == nil {
   188  		return
   189  	}
   190  	length := l.list.Len()
   191  	if length > 0 {
   192  		values = make([]interface{}, length)
   193  		for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
   194  			values[i] = e.Value
   195  		}
   196  	}
   197  	return
   198  }
   199  
   200  // BackAll copies and returns values of all elements from back of <l> as slice.
   201  func (l *List) BackAll() (values []interface{}) {
   202  	l.mu.RLock()
   203  	defer l.mu.RUnlock()
   204  	if l.list == nil {
   205  		return
   206  	}
   207  	length := l.list.Len()
   208  	if length > 0 {
   209  		values = make([]interface{}, length)
   210  		for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
   211  			values[i] = e.Value
   212  		}
   213  	}
   214  	return
   215  }
   216  
   217  // FrontValue returns value of the first element of <l> or nil if the list is empty.
   218  func (l *List) FrontValue() (value interface{}) {
   219  	l.mu.RLock()
   220  	defer l.mu.RUnlock()
   221  	if l.list == nil {
   222  		return
   223  	}
   224  	if e := l.list.Front(); e != nil {
   225  		value = e.Value
   226  	}
   227  	return
   228  }
   229  
   230  // BackValue returns value of the last element of <l> or nil if the list is empty.
   231  func (l *List) BackValue() (value interface{}) {
   232  	l.mu.RLock()
   233  	defer l.mu.RUnlock()
   234  	if l.list == nil {
   235  		return
   236  	}
   237  	if e := l.list.Back(); e != nil {
   238  		value = e.Value
   239  	}
   240  	return
   241  }
   242  
   243  // Front returns the first element of list <l> or nil if the list is empty.
   244  func (l *List) Front() (e *Element) {
   245  	l.mu.RLock()
   246  	defer l.mu.RUnlock()
   247  	if l.list == nil {
   248  		return
   249  	}
   250  	e = l.list.Front()
   251  	return
   252  }
   253  
   254  // Back returns the last element of list <l> or nil if the list is empty.
   255  func (l *List) Back() (e *Element) {
   256  	l.mu.RLock()
   257  	defer l.mu.RUnlock()
   258  	if l.list == nil {
   259  		return
   260  	}
   261  	e = l.list.Back()
   262  	return
   263  }
   264  
   265  // Len returns the number of elements of list <l>.
   266  // The complexity is O(1).
   267  func (l *List) Len() (length int) {
   268  	l.mu.RLock()
   269  	defer l.mu.RUnlock()
   270  	if l.list == nil {
   271  		return
   272  	}
   273  	length = l.list.Len()
   274  	return
   275  }
   276  
   277  // Size is alias of Len.
   278  func (l *List) Size() int {
   279  	return l.Len()
   280  }
   281  
   282  // MoveBefore moves element <e> to its new position before <p>.
   283  // If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified.
   284  // The element and <p> must not be nil.
   285  func (l *List) MoveBefore(e, p *Element) {
   286  	l.mu.Lock()
   287  	defer l.mu.Unlock()
   288  	if l.list == nil {
   289  		l.list = list.New()
   290  	}
   291  	l.list.MoveBefore(e, p)
   292  }
   293  
   294  // MoveAfter moves element <e> to its new position after <p>.
   295  // If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified.
   296  // The element and <p> must not be nil.
   297  func (l *List) MoveAfter(e, p *Element) {
   298  	l.mu.Lock()
   299  	defer l.mu.Unlock()
   300  	if l.list == nil {
   301  		l.list = list.New()
   302  	}
   303  	l.list.MoveAfter(e, p)
   304  }
   305  
   306  // MoveToFront moves element <e> to the front of list <l>.
   307  // If <e> is not an element of <l>, the list is not modified.
   308  // The element must not be nil.
   309  func (l *List) MoveToFront(e *Element) {
   310  	l.mu.Lock()
   311  	defer l.mu.Unlock()
   312  	if l.list == nil {
   313  		l.list = list.New()
   314  	}
   315  	l.list.MoveToFront(e)
   316  }
   317  
   318  // MoveToBack moves element <e> to the back of list <l>.
   319  // If <e> is not an element of <l>, the list is not modified.
   320  // The element must not be nil.
   321  func (l *List) MoveToBack(e *Element) {
   322  	l.mu.Lock()
   323  	defer l.mu.Unlock()
   324  	if l.list == nil {
   325  		l.list = list.New()
   326  	}
   327  	l.list.MoveToBack(e)
   328  }
   329  
   330  // PushBackList inserts a copy of an other list at the back of list <l>.
   331  // The lists <l> and <other> may be the same, but they must not be nil.
   332  func (l *List) PushBackList(other *List) {
   333  	if l != other {
   334  		other.mu.RLock()
   335  		defer other.mu.RUnlock()
   336  	}
   337  	l.mu.Lock()
   338  	defer l.mu.Unlock()
   339  	if l.list == nil {
   340  		l.list = list.New()
   341  	}
   342  	l.list.PushBackList(other.list)
   343  }
   344  
   345  // PushFrontList inserts a copy of an other list at the front of list <l>.
   346  // The lists <l> and <other> may be the same, but they must not be nil.
   347  func (l *List) PushFrontList(other *List) {
   348  	if l != other {
   349  		other.mu.RLock()
   350  		defer other.mu.RUnlock()
   351  	}
   352  	l.mu.Lock()
   353  	defer l.mu.Unlock()
   354  	if l.list == nil {
   355  		l.list = list.New()
   356  	}
   357  	l.list.PushFrontList(other.list)
   358  }
   359  
   360  // InsertAfter inserts a new element <e> with value <v> immediately after <p> and returns <e>.
   361  // If <p> is not an element of <l>, the list is not modified.
   362  // The <p> must not be nil.
   363  func (l *List) InsertAfter(p *Element, v interface{}) (e *Element) {
   364  	l.mu.Lock()
   365  	defer l.mu.Unlock()
   366  	if l.list == nil {
   367  		l.list = list.New()
   368  	}
   369  	e = l.list.InsertAfter(v, p)
   370  	return
   371  }
   372  
   373  // InsertBefore inserts a new element <e> with value <v> immediately before <p> and returns <e>.
   374  // If <p> is not an element of <l>, the list is not modified.
   375  // The <p> must not be nil.
   376  func (l *List) InsertBefore(p *Element, v interface{}) (e *Element) {
   377  	l.mu.Lock()
   378  	defer l.mu.Unlock()
   379  	if l.list == nil {
   380  		l.list = list.New()
   381  	}
   382  	e = l.list.InsertBefore(v, p)
   383  	return
   384  }
   385  
   386  // Remove removes <e> from <l> if <e> is an element of list <l>.
   387  // It returns the element value e.Value.
   388  // The element must not be nil.
   389  func (l *List) Remove(e *Element) (value interface{}) {
   390  	l.mu.Lock()
   391  	defer l.mu.Unlock()
   392  	if l.list == nil {
   393  		l.list = list.New()
   394  	}
   395  	value = l.list.Remove(e)
   396  	return
   397  }
   398  
   399  // Removes removes multiple elements <es> from <l> if <es> are elements of list <l>.
   400  func (l *List) Removes(es []*Element) {
   401  	l.mu.Lock()
   402  	defer l.mu.Unlock()
   403  	if l.list == nil {
   404  		l.list = list.New()
   405  	}
   406  	for _, e := range es {
   407  		l.list.Remove(e)
   408  	}
   409  	return
   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  // See 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  	return "[" + l.Join(",") + "]"
   507  }
   508  
   509  // MarshalJSON implements the interface MarshalJSON for json.Marshal.
   510  func (l *List) MarshalJSON() ([]byte, error) {
   511  	return json.Marshal(l.FrontAll())
   512  }
   513  
   514  // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
   515  func (l *List) UnmarshalJSON(b []byte) error {
   516  	l.mu.Lock()
   517  	defer l.mu.Unlock()
   518  	if l.list == nil {
   519  		l.list = list.New()
   520  	}
   521  	var array []interface{}
   522  	if err := json.UnmarshalUseNumber(b, &array); err != nil {
   523  		return err
   524  	}
   525  	l.PushBacks(array)
   526  	return nil
   527  }
   528  
   529  // UnmarshalValue is an interface implement which sets any type of value for list.
   530  func (l *List) UnmarshalValue(value interface{}) (err error) {
   531  	l.mu.Lock()
   532  	defer l.mu.Unlock()
   533  	if l.list == nil {
   534  		l.list = list.New()
   535  	}
   536  	var array []interface{}
   537  	switch value.(type) {
   538  	case string, []byte:
   539  		err = json.UnmarshalUseNumber(gconv.Bytes(value), &array)
   540  	default:
   541  		array = gconv.SliceAny(value)
   542  	}
   543  	l.PushBacks(array)
   544  	return err
   545  }