github.com/zhongdalu/gf@v1.0.0/g/container/glist/glist.go (about)

     1  // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). 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/zhongdalu/gf.
     6  //
     7  
     8  // Package glist provides a concurrent-safe/unsafe doubly linked list.
     9  package glist
    10  
    11  import (
    12  	"container/list"
    13  	"github.com/zhongdalu/gf/g/internal/rwmutex"
    14  )
    15  
    16  type (
    17  	List struct {
    18  		mu   *rwmutex.RWMutex
    19  		list *list.List
    20  	}
    21  
    22  	Element = list.Element
    23  )
    24  
    25  // New creates and returns a new empty doubly linked list.
    26  func New(unsafe ...bool) *List {
    27  	return &List{
    28  		mu:   rwmutex.New(unsafe...),
    29  		list: list.New(),
    30  	}
    31  }
    32  
    33  // PushFront inserts a new element <e> with value <v> at the front of list <l> and returns <e>.
    34  func (l *List) PushFront(v interface{}) (e *Element) {
    35  	l.mu.Lock()
    36  	e = l.list.PushFront(v)
    37  	l.mu.Unlock()
    38  	return
    39  }
    40  
    41  // PushBack inserts a new element <e> with value <v> at the back of list <l> and returns <e>.
    42  func (l *List) PushBack(v interface{}) (e *Element) {
    43  	l.mu.Lock()
    44  	e = l.list.PushBack(v)
    45  	l.mu.Unlock()
    46  	return
    47  }
    48  
    49  // PushFronts inserts multiple new elements with values <values> at the front of list <l>.
    50  func (l *List) PushFronts(values []interface{}) {
    51  	l.mu.Lock()
    52  	for _, v := range values {
    53  		l.list.PushFront(v)
    54  	}
    55  	l.mu.Unlock()
    56  }
    57  
    58  // PushBacks inserts multiple new elements with values <values> at the back of list <l>.
    59  func (l *List) PushBacks(values []interface{}) {
    60  	l.mu.Lock()
    61  	for _, v := range values {
    62  		l.list.PushBack(v)
    63  	}
    64  	l.mu.Unlock()
    65  }
    66  
    67  // PopBack removes the element from back of <l> and returns the value of the element.
    68  func (l *List) PopBack() (value interface{}) {
    69  	l.mu.Lock()
    70  	if e := l.list.Back(); e != nil {
    71  		value = l.list.Remove(e)
    72  	}
    73  	l.mu.Unlock()
    74  	return
    75  }
    76  
    77  // PopFront removes the element from front of <l> and returns the value of the element.
    78  func (l *List) PopFront() (value interface{}) {
    79  	l.mu.Lock()
    80  	if e := l.list.Front(); e != nil {
    81  		value = l.list.Remove(e)
    82  	}
    83  	l.mu.Unlock()
    84  	return
    85  }
    86  
    87  // PopBacks removes <max> elements from back of <l>
    88  // and returns values of the removed elements as slice.
    89  func (l *List) PopBacks(max int) (values []interface{}) {
    90  	l.mu.Lock()
    91  	length := l.list.Len()
    92  	if length > 0 {
    93  		if max > 0 && max < length {
    94  			length = max
    95  		}
    96  		values = make([]interface{}, length)
    97  		for i := 0; i < length; i++ {
    98  			values[i] = l.list.Remove(l.list.Back())
    99  		}
   100  	}
   101  	l.mu.Unlock()
   102  	return
   103  }
   104  
   105  // PopFronts removes <max> elements from front of <l>
   106  // and returns values of the removed elements as slice.
   107  func (l *List) PopFronts(max int) (values []interface{}) {
   108  	l.mu.Lock()
   109  	length := l.list.Len()
   110  	if length > 0 {
   111  		if max > 0 && max < length {
   112  			length = max
   113  		}
   114  		values = make([]interface{}, length)
   115  		for i := 0; i < length; i++ {
   116  			values[i] = l.list.Remove(l.list.Front())
   117  		}
   118  	}
   119  	l.mu.Unlock()
   120  	return
   121  }
   122  
   123  // PopBackAll removes all elements from back of <l>
   124  // and returns values of the removed elements as slice.
   125  func (l *List) PopBackAll() []interface{} {
   126  	return l.PopBacks(-1)
   127  }
   128  
   129  // PopFrontAll removes all elements from front of <l>
   130  // and returns values of the removed elements as slice.
   131  func (l *List) PopFrontAll() []interface{} {
   132  	return l.PopFronts(-1)
   133  }
   134  
   135  // FrontAll copies and returns values of all elements from front of <l> as slice.
   136  func (l *List) FrontAll() (values []interface{}) {
   137  	l.mu.RLock()
   138  	length := l.list.Len()
   139  	if length > 0 {
   140  		values = make([]interface{}, length)
   141  		for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
   142  			values[i] = e.Value
   143  		}
   144  	}
   145  	l.mu.RUnlock()
   146  	return
   147  }
   148  
   149  // BackAll copies and returns values of all elements from back of <l> as slice.
   150  func (l *List) BackAll() (values []interface{}) {
   151  	l.mu.RLock()
   152  	length := l.list.Len()
   153  	if length > 0 {
   154  		values = make([]interface{}, length)
   155  		for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
   156  			values[i] = e.Value
   157  		}
   158  	}
   159  	l.mu.RUnlock()
   160  	return
   161  }
   162  
   163  // FrontValue returns value of the first element of <l> or nil if the list is empty.
   164  func (l *List) FrontValue() (value interface{}) {
   165  	l.mu.RLock()
   166  	if e := l.list.Front(); e != nil {
   167  		value = e.Value
   168  	}
   169  	l.mu.RUnlock()
   170  	return
   171  }
   172  
   173  // BackValue returns value of the last element of <l> or nil if the list is empty.
   174  func (l *List) BackValue() (value interface{}) {
   175  	l.mu.RLock()
   176  	if e := l.list.Back(); e != nil {
   177  		value = e.Value
   178  	}
   179  	l.mu.RUnlock()
   180  	return
   181  }
   182  
   183  // Front returns the first element of list <l> or nil if the list is empty.
   184  func (l *List) Front() (e *Element) {
   185  	l.mu.RLock()
   186  	e = l.list.Front()
   187  	l.mu.RUnlock()
   188  	return
   189  }
   190  
   191  // Back returns the last element of list <l> or nil if the list is empty.
   192  func (l *List) Back() (e *Element) {
   193  	l.mu.RLock()
   194  	e = l.list.Back()
   195  	l.mu.RUnlock()
   196  	return
   197  }
   198  
   199  // Len returns the number of elements of list <l>.
   200  // The complexity is O(1).
   201  func (l *List) Len() (length int) {
   202  	l.mu.RLock()
   203  	length = l.list.Len()
   204  	l.mu.RUnlock()
   205  	return
   206  }
   207  
   208  // Size is alias of Len.
   209  func (l *List) Size() int {
   210  	return l.Len()
   211  }
   212  
   213  // MoveBefore moves element <e> to its new position before <p>.
   214  // If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified.
   215  // The element and <p> must not be nil.
   216  func (l *List) MoveBefore(e, p *Element) {
   217  	l.mu.Lock()
   218  	l.list.MoveBefore(e, p)
   219  	l.mu.Unlock()
   220  }
   221  
   222  // MoveAfter moves element <e> to its new position after <p>.
   223  // If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified.
   224  // The element and <p> must not be nil.
   225  func (l *List) MoveAfter(e, p *Element) {
   226  	l.mu.Lock()
   227  	l.list.MoveAfter(e, p)
   228  	l.mu.Unlock()
   229  }
   230  
   231  // MoveToFront moves element <e> to the front of list <l>.
   232  // If <e> is not an element of <l>, the list is not modified.
   233  // The element must not be nil.
   234  func (l *List) MoveToFront(e *Element) {
   235  	l.mu.Lock()
   236  	l.list.MoveToFront(e)
   237  	l.mu.Unlock()
   238  }
   239  
   240  // MoveToBack moves element <e> to the back of list <l>.
   241  // If <e> is not an element of <l>, the list is not modified.
   242  // The element must not be nil.
   243  func (l *List) MoveToBack(e *Element) {
   244  	l.mu.Lock()
   245  	l.list.MoveToBack(e)
   246  	l.mu.Unlock()
   247  }
   248  
   249  // PushBackList inserts a copy of an other list at the back of list <l>.
   250  // The lists <l> and <other> may be the same, but they must not be nil.
   251  func (l *List) PushBackList(other *List) {
   252  	if l != other {
   253  		other.mu.RLock()
   254  		defer other.mu.RUnlock()
   255  	}
   256  	l.mu.Lock()
   257  	l.list.PushBackList(other.list)
   258  	l.mu.Unlock()
   259  }
   260  
   261  // PushFrontList inserts a copy of an other list at the front of list <l>.
   262  // The lists <l> and <other> may be the same, but they must not be nil.
   263  func (l *List) PushFrontList(other *List) {
   264  	if l != other {
   265  		other.mu.RLock()
   266  		defer other.mu.RUnlock()
   267  	}
   268  	l.mu.Lock()
   269  	l.list.PushFrontList(other.list)
   270  	l.mu.Unlock()
   271  }
   272  
   273  // InsertAfter inserts a new element <e> with value <v> immediately after <p> and returns <e>.
   274  // If <p> is not an element of <l>, the list is not modified.
   275  // The <p> must not be nil.
   276  func (l *List) InsertAfter(v interface{}, p *Element) (e *Element) {
   277  	l.mu.Lock()
   278  	e = l.list.InsertAfter(v, p)
   279  	l.mu.Unlock()
   280  	return
   281  }
   282  
   283  // InsertBefore inserts a new element <e> with value <v> immediately before <p> and returns <e>.
   284  // If <p> is not an element of <l>, the list is not modified.
   285  // The <p> must not be nil.
   286  func (l *List) InsertBefore(v interface{}, p *Element) (e *Element) {
   287  	l.mu.Lock()
   288  	e = l.list.InsertBefore(v, p)
   289  	l.mu.Unlock()
   290  	return
   291  }
   292  
   293  // Remove removes <e> from <l> if <e> is an element of list <l>.
   294  // It returns the element value e.Value.
   295  // The element must not be nil.
   296  func (l *List) Remove(e *Element) (value interface{}) {
   297  	l.mu.Lock()
   298  	value = l.list.Remove(e)
   299  	l.mu.Unlock()
   300  	return
   301  }
   302  
   303  // Removes removes multiple elements <es> from <l> if <es> are elements of list <l>.
   304  func (l *List) Removes(es []*Element) {
   305  	l.mu.Lock()
   306  	for _, e := range es {
   307  		l.list.Remove(e)
   308  	}
   309  	l.mu.Unlock()
   310  	return
   311  }
   312  
   313  // RemoveAll removes all elements from list <l>.
   314  func (l *List) RemoveAll() {
   315  	l.mu.Lock()
   316  	l.list = list.New()
   317  	l.mu.Unlock()
   318  }
   319  
   320  // See RemoveAll().
   321  func (l *List) Clear() {
   322  	l.RemoveAll()
   323  }
   324  
   325  // RLockFunc locks reading with given callback function <f> within RWMutex.RLock.
   326  func (l *List) RLockFunc(f func(list *list.List)) {
   327  	l.mu.RLock()
   328  	defer l.mu.RUnlock()
   329  	f(l.list)
   330  }
   331  
   332  // LockFunc locks writing with given callback function <f> within RWMutex.Lock.
   333  func (l *List) LockFunc(f func(list *list.List)) {
   334  	l.mu.Lock()
   335  	defer l.mu.Unlock()
   336  	f(l.list)
   337  }
   338  
   339  // Iterator is alias of IteratorAsc.
   340  func (l *List) Iterator(f func(e *Element) bool) {
   341  	l.IteratorAsc(f)
   342  }
   343  
   344  // IteratorAsc iterates the list in ascending order with given callback function <f>.
   345  // If <f> returns true, then it continues iterating; or false to stop.
   346  func (l *List) IteratorAsc(f func(e *Element) bool) {
   347  	l.mu.RLock()
   348  	length := l.list.Len()
   349  	if length > 0 {
   350  		for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
   351  			if !f(e) {
   352  				break
   353  			}
   354  		}
   355  	}
   356  	l.mu.RUnlock()
   357  }
   358  
   359  // IteratorDesc iterates the list in descending order with given callback function <f>.
   360  // If <f> returns true, then it continues iterating; or false to stop.
   361  func (l *List) IteratorDesc(f func(e *Element) bool) {
   362  	l.mu.RLock()
   363  	length := l.list.Len()
   364  	if length > 0 {
   365  		for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
   366  			if !f(e) {
   367  				break
   368  			}
   369  		}
   370  	}
   371  	l.mu.RUnlock()
   372  }