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 }