github.com/daeuniverse/quic-go@v0.0.0-20240413031024-943f218e0810/internal/utils/linkedlist/linkedlist.go (about)

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