github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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 // for e := l.Front(); e != nil; e = e.Next() { 59 // // do something with e. 60 // } 61 // 62 // +stateify savable 63 type List struct { 64 head Element 65 tail Element 66 } 67 68 // Reset resets list l to the empty state. 69 func (l *List) Reset() { 70 l.head = nil 71 l.tail = nil 72 } 73 74 // Empty returns true iff the list is empty. 75 // 76 //go:nosplit 77 func (l *List) Empty() bool { 78 return l.head == nil 79 } 80 81 // Front returns the first element of list l or nil. 82 // 83 //go:nosplit 84 func (l *List) Front() Element { 85 return l.head 86 } 87 88 // Back returns the last element of list l or nil. 89 // 90 //go:nosplit 91 func (l *List) Back() Element { 92 return l.tail 93 } 94 95 // Len returns the number of elements in the list. 96 // 97 // NOTE: This is an O(n) operation. 98 // 99 //go:nosplit 100 func (l *List) Len() (count int) { 101 for e := l.Front(); e != nil; e = (ElementMapper{}.linkerFor(e)).Next() { 102 count++ 103 } 104 return count 105 } 106 107 // PushFront inserts the element e at the front of list l. 108 // 109 //go:nosplit 110 func (l *List) PushFront(e Element) { 111 linker := ElementMapper{}.linkerFor(e) 112 linker.SetNext(l.head) 113 linker.SetPrev(nil) 114 if l.head != nil { 115 ElementMapper{}.linkerFor(l.head).SetPrev(e) 116 } else { 117 l.tail = e 118 } 119 120 l.head = e 121 } 122 123 // PushBack inserts the element e at the back of list l. 124 // 125 //go:nosplit 126 func (l *List) PushBack(e Element) { 127 linker := ElementMapper{}.linkerFor(e) 128 linker.SetNext(nil) 129 linker.SetPrev(l.tail) 130 if l.tail != nil { 131 ElementMapper{}.linkerFor(l.tail).SetNext(e) 132 } else { 133 l.head = e 134 } 135 136 l.tail = e 137 } 138 139 // PushBackList inserts list m at the end of list l, emptying m. 140 // 141 //go:nosplit 142 func (l *List) PushBackList(m *List) { 143 if l.head == nil { 144 l.head = m.head 145 l.tail = m.tail 146 } else if m.head != nil { 147 ElementMapper{}.linkerFor(l.tail).SetNext(m.head) 148 ElementMapper{}.linkerFor(m.head).SetPrev(l.tail) 149 150 l.tail = m.tail 151 } 152 m.head = nil 153 m.tail = nil 154 } 155 156 // InsertAfter inserts e after b. 157 // 158 //go:nosplit 159 func (l *List) InsertAfter(b, e Element) { 160 bLinker := ElementMapper{}.linkerFor(b) 161 eLinker := ElementMapper{}.linkerFor(e) 162 163 a := bLinker.Next() 164 165 eLinker.SetNext(a) 166 eLinker.SetPrev(b) 167 bLinker.SetNext(e) 168 169 if a != nil { 170 ElementMapper{}.linkerFor(a).SetPrev(e) 171 } else { 172 l.tail = e 173 } 174 } 175 176 // InsertBefore inserts e before a. 177 // 178 //go:nosplit 179 func (l *List) InsertBefore(a, e Element) { 180 aLinker := ElementMapper{}.linkerFor(a) 181 eLinker := ElementMapper{}.linkerFor(e) 182 183 b := aLinker.Prev() 184 eLinker.SetNext(a) 185 eLinker.SetPrev(b) 186 aLinker.SetPrev(e) 187 188 if b != nil { 189 ElementMapper{}.linkerFor(b).SetNext(e) 190 } else { 191 l.head = e 192 } 193 } 194 195 // Remove removes e from l. 196 // 197 //go:nosplit 198 func (l *List) Remove(e Element) { 199 linker := ElementMapper{}.linkerFor(e) 200 prev := linker.Prev() 201 next := linker.Next() 202 203 if prev != nil { 204 ElementMapper{}.linkerFor(prev).SetNext(next) 205 } else if l.head == e { 206 l.head = next 207 } 208 209 if next != nil { 210 ElementMapper{}.linkerFor(next).SetPrev(prev) 211 } else if l.tail == e { 212 l.tail = prev 213 } 214 215 linker.SetNext(nil) 216 linker.SetPrev(nil) 217 } 218 219 // Entry is a default implementation of Linker. Users can add anonymous fields 220 // of this type to their structs to make them automatically implement the 221 // methods needed by List. 222 // 223 // +stateify savable 224 type Entry struct { 225 next Element 226 prev Element 227 } 228 229 // Next returns the entry that follows e in the list. 230 // 231 //go:nosplit 232 func (e *Entry) Next() Element { 233 return e.next 234 } 235 236 // Prev returns the entry that precedes e in the list. 237 // 238 //go:nosplit 239 func (e *Entry) Prev() Element { 240 return e.prev 241 } 242 243 // SetNext assigns 'entry' as the entry that follows e in the list. 244 // 245 //go:nosplit 246 func (e *Entry) SetNext(elem Element) { 247 e.next = elem 248 } 249 250 // SetPrev assigns 'entry' as the entry that precedes e in the list. 251 // 252 //go:nosplit 253 func (e *Entry) SetPrev(elem Element) { 254 e.prev = elem 255 }