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