inet.af/netstack@v0.0.0-20220214151720-7585b01ddccf/state/deferred_list.go (about)

     1  package state
     2  
     3  // List is an intrusive list. Entries can be added to or removed from the list
     4  // in O(1) time and with no additional memory allocations.
     5  //
     6  // The zero value for List is an empty list ready to use.
     7  //
     8  // To iterate over a list (where l is a List):
     9  //      for e := l.Front(); e != nil; e = e.Next() {
    10  // 		// do something with e.
    11  //      }
    12  //
    13  // +stateify savable
    14  type deferredList struct {
    15  	head *objectEncodeState
    16  	tail *objectEncodeState
    17  }
    18  
    19  // Reset resets list l to the empty state.
    20  func (l *deferredList) Reset() {
    21  	l.head = nil
    22  	l.tail = nil
    23  }
    24  
    25  // Empty returns true iff the list is empty.
    26  //
    27  //go:nosplit
    28  func (l *deferredList) Empty() bool {
    29  	return l.head == nil
    30  }
    31  
    32  // Front returns the first element of list l or nil.
    33  //
    34  //go:nosplit
    35  func (l *deferredList) Front() *objectEncodeState {
    36  	return l.head
    37  }
    38  
    39  // Back returns the last element of list l or nil.
    40  //
    41  //go:nosplit
    42  func (l *deferredList) Back() *objectEncodeState {
    43  	return l.tail
    44  }
    45  
    46  // Len returns the number of elements in the list.
    47  //
    48  // NOTE: This is an O(n) operation.
    49  //
    50  //go:nosplit
    51  func (l *deferredList) Len() (count int) {
    52  	for e := l.Front(); e != nil; e = (deferredMapper{}.linkerFor(e)).Next() {
    53  		count++
    54  	}
    55  	return count
    56  }
    57  
    58  // PushFront inserts the element e at the front of list l.
    59  //
    60  //go:nosplit
    61  func (l *deferredList) PushFront(e *objectEncodeState) {
    62  	linker := deferredMapper{}.linkerFor(e)
    63  	linker.SetNext(l.head)
    64  	linker.SetPrev(nil)
    65  	if l.head != nil {
    66  		deferredMapper{}.linkerFor(l.head).SetPrev(e)
    67  	} else {
    68  		l.tail = e
    69  	}
    70  
    71  	l.head = e
    72  }
    73  
    74  // PushBack inserts the element e at the back of list l.
    75  //
    76  //go:nosplit
    77  func (l *deferredList) PushBack(e *objectEncodeState) {
    78  	linker := deferredMapper{}.linkerFor(e)
    79  	linker.SetNext(nil)
    80  	linker.SetPrev(l.tail)
    81  	if l.tail != nil {
    82  		deferredMapper{}.linkerFor(l.tail).SetNext(e)
    83  	} else {
    84  		l.head = e
    85  	}
    86  
    87  	l.tail = e
    88  }
    89  
    90  // PushBackList inserts list m at the end of list l, emptying m.
    91  //
    92  //go:nosplit
    93  func (l *deferredList) PushBackList(m *deferredList) {
    94  	if l.head == nil {
    95  		l.head = m.head
    96  		l.tail = m.tail
    97  	} else if m.head != nil {
    98  		deferredMapper{}.linkerFor(l.tail).SetNext(m.head)
    99  		deferredMapper{}.linkerFor(m.head).SetPrev(l.tail)
   100  
   101  		l.tail = m.tail
   102  	}
   103  	m.head = nil
   104  	m.tail = nil
   105  }
   106  
   107  // InsertAfter inserts e after b.
   108  //
   109  //go:nosplit
   110  func (l *deferredList) InsertAfter(b, e *objectEncodeState) {
   111  	bLinker := deferredMapper{}.linkerFor(b)
   112  	eLinker := deferredMapper{}.linkerFor(e)
   113  
   114  	a := bLinker.Next()
   115  
   116  	eLinker.SetNext(a)
   117  	eLinker.SetPrev(b)
   118  	bLinker.SetNext(e)
   119  
   120  	if a != nil {
   121  		deferredMapper{}.linkerFor(a).SetPrev(e)
   122  	} else {
   123  		l.tail = e
   124  	}
   125  }
   126  
   127  // InsertBefore inserts e before a.
   128  //
   129  //go:nosplit
   130  func (l *deferredList) InsertBefore(a, e *objectEncodeState) {
   131  	aLinker := deferredMapper{}.linkerFor(a)
   132  	eLinker := deferredMapper{}.linkerFor(e)
   133  
   134  	b := aLinker.Prev()
   135  	eLinker.SetNext(a)
   136  	eLinker.SetPrev(b)
   137  	aLinker.SetPrev(e)
   138  
   139  	if b != nil {
   140  		deferredMapper{}.linkerFor(b).SetNext(e)
   141  	} else {
   142  		l.head = e
   143  	}
   144  }
   145  
   146  // Remove removes e from l.
   147  //
   148  //go:nosplit
   149  func (l *deferredList) Remove(e *objectEncodeState) {
   150  	linker := deferredMapper{}.linkerFor(e)
   151  	prev := linker.Prev()
   152  	next := linker.Next()
   153  
   154  	if prev != nil {
   155  		deferredMapper{}.linkerFor(prev).SetNext(next)
   156  	} else if l.head == e {
   157  		l.head = next
   158  	}
   159  
   160  	if next != nil {
   161  		deferredMapper{}.linkerFor(next).SetPrev(prev)
   162  	} else if l.tail == e {
   163  		l.tail = prev
   164  	}
   165  
   166  	linker.SetNext(nil)
   167  	linker.SetPrev(nil)
   168  }
   169  
   170  // Entry is a default implementation of Linker. Users can add anonymous fields
   171  // of this type to their structs to make them automatically implement the
   172  // methods needed by List.
   173  //
   174  // +stateify savable
   175  type deferredEntry struct {
   176  	next *objectEncodeState
   177  	prev *objectEncodeState
   178  }
   179  
   180  // Next returns the entry that follows e in the list.
   181  //
   182  //go:nosplit
   183  func (e *deferredEntry) Next() *objectEncodeState {
   184  	return e.next
   185  }
   186  
   187  // Prev returns the entry that precedes e in the list.
   188  //
   189  //go:nosplit
   190  func (e *deferredEntry) Prev() *objectEncodeState {
   191  	return e.prev
   192  }
   193  
   194  // SetNext assigns 'entry' as the entry that follows e in the list.
   195  //
   196  //go:nosplit
   197  func (e *deferredEntry) SetNext(elem *objectEncodeState) {
   198  	e.next = elem
   199  }
   200  
   201  // SetPrev assigns 'entry' as the entry that precedes e in the list.
   202  //
   203  //go:nosplit
   204  func (e *deferredEntry) SetPrev(elem *objectEncodeState) {
   205  	e.prev = elem
   206  }