github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/pkg/ilist/interface_list.go (about)

     1  package ilist
     2  
     3  // Linker is the interface that objects must implement if they want to be added
     4  // to and/or removed from List objects.
     5  //
     6  // N.B. When substituted in a template instantiation, Linker doesn't need to
     7  // be an interface, and in most cases won't be.
     8  type Linker interface {
     9  	Next() Element
    10  	Prev() Element
    11  	SetNext(Element)
    12  	SetPrev(Element)
    13  }
    14  
    15  // Element the item that is used at the API level.
    16  //
    17  // N.B. Like Linker, this is unlikely to be an interface in most cases.
    18  type Element interface {
    19  	Linker
    20  }
    21  
    22  // ElementMapper provides an identity mapping by default.
    23  //
    24  // This can be replaced to provide a struct that maps elements to linker
    25  // objects, if they are not the same. An ElementMapper is not typically
    26  // required if: Linker is left as is, Element is left as is, or Linker and
    27  // Element are the same type.
    28  type ElementMapper struct{}
    29  
    30  // linkerFor maps an Element to a Linker.
    31  //
    32  // This default implementation should be inlined.
    33  //
    34  //go:nosplit
    35  func (ElementMapper) linkerFor(elem Element) Linker { return elem }
    36  
    37  // List is an intrusive list. Entries can be added to or removed from the list
    38  // in O(1) time and with no additional memory allocations.
    39  //
    40  // The zero value for List is an empty list ready to use.
    41  //
    42  // To iterate over a list (where l is a List):
    43  //
    44  //	for e := l.Front(); e != nil; e = e.Next() {
    45  //		// do something with e.
    46  //	}
    47  //
    48  // +stateify savable
    49  type List struct {
    50  	head Element
    51  	tail Element
    52  }
    53  
    54  // Reset resets list l to the empty state.
    55  func (l *List) Reset() {
    56  	l.head = nil
    57  	l.tail = nil
    58  }
    59  
    60  // Empty returns true iff the list is empty.
    61  //
    62  //go:nosplit
    63  func (l *List) Empty() bool {
    64  	return l.head == nil
    65  }
    66  
    67  // Front returns the first element of list l or nil.
    68  //
    69  //go:nosplit
    70  func (l *List) Front() Element {
    71  	return l.head
    72  }
    73  
    74  // Back returns the last element of list l or nil.
    75  //
    76  //go:nosplit
    77  func (l *List) Back() Element {
    78  	return l.tail
    79  }
    80  
    81  // Len returns the number of elements in the list.
    82  //
    83  // NOTE: This is an O(n) operation.
    84  //
    85  //go:nosplit
    86  func (l *List) Len() (count int) {
    87  	for e := l.Front(); e != nil; e = (ElementMapper{}.linkerFor(e)).Next() {
    88  		count++
    89  	}
    90  	return count
    91  }
    92  
    93  // PushFront inserts the element e at the front of list l.
    94  //
    95  //go:nosplit
    96  func (l *List) PushFront(e Element) {
    97  	linker := ElementMapper{}.linkerFor(e)
    98  	linker.SetNext(l.head)
    99  	linker.SetPrev(nil)
   100  	if l.head != nil {
   101  		ElementMapper{}.linkerFor(l.head).SetPrev(e)
   102  	} else {
   103  		l.tail = e
   104  	}
   105  
   106  	l.head = e
   107  }
   108  
   109  // PushFrontList inserts list m at the start of list l, emptying m.
   110  //
   111  //go:nosplit
   112  func (l *List) PushFrontList(m *List) {
   113  	if l.head == nil {
   114  		l.head = m.head
   115  		l.tail = m.tail
   116  	} else if m.head != nil {
   117  		ElementMapper{}.linkerFor(l.head).SetPrev(m.tail)
   118  		ElementMapper{}.linkerFor(m.tail).SetNext(l.head)
   119  
   120  		l.head = m.head
   121  	}
   122  	m.head = nil
   123  	m.tail = nil
   124  }
   125  
   126  // PushBack inserts the element e at the back of list l.
   127  //
   128  //go:nosplit
   129  func (l *List) PushBack(e Element) {
   130  	linker := ElementMapper{}.linkerFor(e)
   131  	linker.SetNext(nil)
   132  	linker.SetPrev(l.tail)
   133  	if l.tail != nil {
   134  		ElementMapper{}.linkerFor(l.tail).SetNext(e)
   135  	} else {
   136  		l.head = e
   137  	}
   138  
   139  	l.tail = e
   140  }
   141  
   142  // PushBackList inserts list m at the end of list l, emptying m.
   143  //
   144  //go:nosplit
   145  func (l *List) PushBackList(m *List) {
   146  	if l.head == nil {
   147  		l.head = m.head
   148  		l.tail = m.tail
   149  	} else if m.head != nil {
   150  		ElementMapper{}.linkerFor(l.tail).SetNext(m.head)
   151  		ElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
   152  
   153  		l.tail = m.tail
   154  	}
   155  	m.head = nil
   156  	m.tail = nil
   157  }
   158  
   159  // InsertAfter inserts e after b.
   160  //
   161  //go:nosplit
   162  func (l *List) InsertAfter(b, e Element) {
   163  	bLinker := ElementMapper{}.linkerFor(b)
   164  	eLinker := ElementMapper{}.linkerFor(e)
   165  
   166  	a := bLinker.Next()
   167  
   168  	eLinker.SetNext(a)
   169  	eLinker.SetPrev(b)
   170  	bLinker.SetNext(e)
   171  
   172  	if a != nil {
   173  		ElementMapper{}.linkerFor(a).SetPrev(e)
   174  	} else {
   175  		l.tail = e
   176  	}
   177  }
   178  
   179  // InsertBefore inserts e before a.
   180  //
   181  //go:nosplit
   182  func (l *List) InsertBefore(a, e Element) {
   183  	aLinker := ElementMapper{}.linkerFor(a)
   184  	eLinker := ElementMapper{}.linkerFor(e)
   185  
   186  	b := aLinker.Prev()
   187  	eLinker.SetNext(a)
   188  	eLinker.SetPrev(b)
   189  	aLinker.SetPrev(e)
   190  
   191  	if b != nil {
   192  		ElementMapper{}.linkerFor(b).SetNext(e)
   193  	} else {
   194  		l.head = e
   195  	}
   196  }
   197  
   198  // Remove removes e from l.
   199  //
   200  //go:nosplit
   201  func (l *List) Remove(e Element) {
   202  	linker := ElementMapper{}.linkerFor(e)
   203  	prev := linker.Prev()
   204  	next := linker.Next()
   205  
   206  	if prev != nil {
   207  		ElementMapper{}.linkerFor(prev).SetNext(next)
   208  	} else if l.head == e {
   209  		l.head = next
   210  	}
   211  
   212  	if next != nil {
   213  		ElementMapper{}.linkerFor(next).SetPrev(prev)
   214  	} else if l.tail == e {
   215  		l.tail = prev
   216  	}
   217  
   218  	linker.SetNext(nil)
   219  	linker.SetPrev(nil)
   220  }
   221  
   222  // Entry is a default implementation of Linker. Users can add anonymous fields
   223  // of this type to their structs to make them automatically implement the
   224  // methods needed by List.
   225  //
   226  // +stateify savable
   227  type Entry struct {
   228  	next Element
   229  	prev Element
   230  }
   231  
   232  // Next returns the entry that follows e in the list.
   233  //
   234  //go:nosplit
   235  func (e *Entry) Next() Element {
   236  	return e.next
   237  }
   238  
   239  // Prev returns the entry that precedes e in the list.
   240  //
   241  //go:nosplit
   242  func (e *Entry) Prev() Element {
   243  	return e.prev
   244  }
   245  
   246  // SetNext assigns 'entry' as the entry that follows e in the list.
   247  //
   248  //go:nosplit
   249  func (e *Entry) SetNext(elem Element) {
   250  	e.next = elem
   251  }
   252  
   253  // SetPrev assigns 'entry' as the entry that precedes e in the list.
   254  //
   255  //go:nosplit
   256  func (e *Entry) SetPrev(elem Element) {
   257  	e.prev = elem
   258  }