github.com/MeteorsLiu/simpleMQ@v1.0.3/generic/list.go (about)

     1  package generic
     2  
     3  // Copyright 2009 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // Package list implements a doubly linked list.
     8  //
     9  // To iterate over a list (where l is a *List[T]):
    10  //
    11  //	for e := l.Front(); e != nil; e = e.Next() {
    12  //		// do something with e.Value
    13  //	}
    14  
    15  // Element[T] is an element of a linked list.
    16  type Element[T any] struct {
    17  	// Next and previous pointers in the doubly-linked list of elements.
    18  	// To simplify the implementation, internally a list l is implemented
    19  	// as a ring, such that &l.root is both the next element of the last
    20  	// list element (l.Back()) and the previous element of the first list
    21  	// element (l.Front()).
    22  	next, prev *Element[T]
    23  
    24  	// The list to which this element belongs.
    25  	list *List[T]
    26  
    27  	// The value stored with this element.
    28  	Value T
    29  }
    30  
    31  // Next returns the next list element or nil.
    32  func (e *Element[T]) Next() *Element[T] {
    33  	if p := e.next; e.list != nil && p != &e.list.root {
    34  		return p
    35  	}
    36  	return nil
    37  }
    38  
    39  // Prev returns the previous list element or nil.
    40  func (e *Element[T]) Prev() *Element[T] {
    41  	if p := e.prev; e.list != nil && p != &e.list.root {
    42  		return p
    43  	}
    44  	return nil
    45  }
    46  
    47  // List represents a doubly linked list.
    48  // The zero value for List is an empty list ready to use.
    49  type List[T any] struct {
    50  	root Element[T] // sentinel list element, only &root, root.prev, and root.next are used
    51  	len  int        // current list length excluding (this) sentinel element
    52  }
    53  
    54  // Init initializes or clears list l.
    55  func (l *List[T]) Init() *List[T] {
    56  	l.root.next = &l.root
    57  	l.root.prev = &l.root
    58  	l.len = 0
    59  	return l
    60  }
    61  
    62  // New returns an initialized list.
    63  func New[T any]() *List[T] { return new(List[T]).Init() }
    64  
    65  // Len returns the number of elements of list l.
    66  // The complexity is O(1).
    67  func (l *List[T]) Len() int { return l.len }
    68  
    69  // Front returns the first element of list l or nil if the list is empty.
    70  func (l *List[T]) Front() *Element[T] {
    71  	if l.len == 0 {
    72  		return nil
    73  	}
    74  	return l.root.next
    75  }
    76  
    77  // Back returns the last element of list l or nil if the list is empty.
    78  func (l *List[T]) Back() *Element[T] {
    79  	if l.len == 0 {
    80  		return nil
    81  	}
    82  	return l.root.prev
    83  }
    84  
    85  // lazyInit lazily initializes a zero List value.
    86  func (l *List[T]) lazyInit() {
    87  	if l.root.next == nil {
    88  		l.Init()
    89  	}
    90  }
    91  
    92  // insert inserts e after at, increments l.len, and returns e.
    93  func (l *List[T]) insert(e, at *Element[T]) *Element[T] {
    94  	e.prev = at
    95  	e.next = at.next
    96  	e.prev.next = e
    97  	e.next.prev = e
    98  	e.list = l
    99  	l.len++
   100  	return e
   101  }
   102  
   103  // insertValue is a convenience wrapper for insert(&Element[T]{Value: v}, at).
   104  func (l *List[T]) insertValue(v T, at *Element[T]) *Element[T] {
   105  	return l.insert(&Element[T]{Value: v}, at)
   106  }
   107  
   108  // remove removes e from its list, decrements l.len
   109  func (l *List[T]) remove(e *Element[T]) {
   110  	e.prev.next = e.next
   111  	e.next.prev = e.prev
   112  	e.next = nil // avoid memory leaks
   113  	e.prev = nil // avoid memory leaks
   114  	e.list = nil
   115  	l.len--
   116  }
   117  
   118  // move moves e to next to at.
   119  func (l *List[T]) move(e, at *Element[T]) {
   120  	if e == at {
   121  		return
   122  	}
   123  	e.prev.next = e.next
   124  	e.next.prev = e.prev
   125  
   126  	e.prev = at
   127  	e.next = at.next
   128  	e.prev.next = e
   129  	e.next.prev = e
   130  }
   131  
   132  // Remove removes e from l if e is an element of list l.
   133  // It returns the element value e.Value.
   134  // The element must not be nil.
   135  func (l *List[T]) Remove(e *Element[T]) any {
   136  	if e.list == l {
   137  		// if e.list == l, l must have been initialized when e was inserted
   138  		// in l or l == nil (e is a zero Element[T]) and l.remove will crash
   139  		l.remove(e)
   140  	}
   141  	return e.Value
   142  }
   143  
   144  // PushFront inserts a new element e with value v at the front of list l and returns e.
   145  func (l *List[T]) PushFront(v T) *Element[T] {
   146  	l.lazyInit()
   147  	return l.insertValue(v, &l.root)
   148  }
   149  
   150  // PushBack inserts a new element e with value v at the back of list l and returns e.
   151  func (l *List[T]) PushBack(v T) *Element[T] {
   152  	l.lazyInit()
   153  	return l.insertValue(v, l.root.prev)
   154  }
   155  
   156  // InsertBefore inserts a new element e with value v immediately before mark and returns e.
   157  // If mark is not an element of l, the list is not modified.
   158  // The mark must not be nil.
   159  func (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T] {
   160  	if mark.list != l {
   161  		return nil
   162  	}
   163  	// see comment in List.Remove about initialization of l
   164  	return l.insertValue(v, mark.prev)
   165  }
   166  
   167  // InsertAfter inserts a new element e with value v immediately after mark and returns e.
   168  // If mark is not an element of l, the list is not modified.
   169  // The mark must not be nil.
   170  func (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T] {
   171  	if mark.list != l {
   172  		return nil
   173  	}
   174  	// see comment in List.Remove about initialization of l
   175  	return l.insertValue(v, mark)
   176  }
   177  
   178  // MoveToFront moves element e to the front of list l.
   179  // If e is not an element of l, the list is not modified.
   180  // The element must not be nil.
   181  func (l *List[T]) MoveToFront(e *Element[T]) {
   182  	if e.list != l || l.root.next == e {
   183  		return
   184  	}
   185  	// see comment in List.Remove about initialization of l
   186  	l.move(e, &l.root)
   187  }
   188  
   189  // MoveToBack moves element e to the back of list l.
   190  // If e is not an element of l, the list is not modified.
   191  // The element must not be nil.
   192  func (l *List[T]) MoveToBack(e *Element[T]) {
   193  	if e.list != l || l.root.prev == e {
   194  		return
   195  	}
   196  	// see comment in List.Remove about initialization of l
   197  	l.move(e, l.root.prev)
   198  }
   199  
   200  // MoveBefore moves element e to its new position before mark.
   201  // If e or mark is not an element of l, or e == mark, the list is not modified.
   202  // The element and mark must not be nil.
   203  func (l *List[T]) MoveBefore(e, mark *Element[T]) {
   204  	if e.list != l || e == mark || mark.list != l {
   205  		return
   206  	}
   207  	l.move(e, mark.prev)
   208  }
   209  
   210  // MoveAfter moves element e to its new position after mark.
   211  // If e or mark is not an element of l, or e == mark, the list is not modified.
   212  // The element and mark must not be nil.
   213  func (l *List[T]) MoveAfter(e, mark *Element[T]) {
   214  	if e.list != l || e == mark || mark.list != l {
   215  		return
   216  	}
   217  	l.move(e, mark)
   218  }
   219  
   220  // PushBackList inserts a copy of another list at the back of list l.
   221  // The lists l and other may be the same. They must not be nil.
   222  func (l *List[T]) PushBackList(other *List[T]) {
   223  	l.lazyInit()
   224  	for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
   225  		l.insertValue(e.Value, l.root.prev)
   226  	}
   227  }
   228  
   229  // PushFrontList inserts a copy of another list at the front of list l.
   230  // The lists l and other may be the same. They must not be nil.
   231  func (l *List[T]) PushFrontList(other *List[T]) {
   232  	l.lazyInit()
   233  	for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {
   234  		l.insertValue(e.Value, &l.root)
   235  	}
   236  }