github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/container/sortlist/list/list.go (about) 1 package list 2 3 import ( 4 "time" 5 ) 6 7 // Element is an element of a linked list. 8 type Element struct { 9 // Next and previous pointers in the doubly-linked list of elements. 10 // To simplify the implementation, internally a list l is implemented 11 // as a ring, such that &l.root is both the next element of the last 12 // list element (l.Back()) and the previous element of the first list 13 // element (l.Front()). 14 next, prev *Element 15 16 // The list to which this element belongs. 17 list *List 18 19 // The value stored with this element. 20 Value interface{} 21 22 Score []byte 23 // 节点插入时间 a Unix time, the number of seconds elapsed 24 InsertTime int64 25 } 26 27 // Next returns the next list element or nil. 28 func (e *Element) Next() *Element { 29 if p := e.next; e.list != nil && p != &e.list.root { 30 return p 31 } 32 return nil 33 } 34 35 // Prev returns the previous list element or nil. 36 func (e *Element) Prev() *Element { 37 if p := e.prev; e.list != nil && p != &e.list.root { 38 return p 39 } 40 return nil 41 } 42 43 // List represents a doubly linked list. 44 // The zero value for List is an empty list ready to use. 45 type List struct { 46 root Element // sentinel list element, only &root, root.prev, and root.next are used 47 len int // current list length excluding (this) sentinel element 48 } 49 50 // Init initializes or clears list l. 51 func (l *List) Init() *List { 52 l.root.next = &l.root 53 l.root.prev = &l.root 54 l.len = 0 55 return l 56 } 57 58 // New returns an initialized list. 59 func New() *List { return new(List).Init() } 60 61 // Len returns the number of elements of list l. 62 // The complexity is O(1). 63 func (l *List) Len() int { return l.len } 64 65 // Front returns the first element of list l or nil if the list is empty. 66 func (l *List) Front() *Element { 67 if l.len == 0 { 68 return nil 69 } 70 return l.root.next 71 } 72 73 // Back returns the last element of list l or nil if the list is empty. 74 func (l *List) Back() *Element { 75 if l.len == 0 { 76 return nil 77 } 78 return l.root.prev 79 } 80 81 // lazyInit lazily initializes a zero List value. 82 func (l *List) lazyInit() { 83 if l.root.next == nil { 84 l.Init() 85 } 86 } 87 88 // insert inserts e after at, increments l.len, and returns e. 89 func (l *List) insert(e, at *Element) *Element { 90 n := at.next 91 at.next = e 92 e.prev = at 93 e.next = n 94 n.prev = e 95 e.list = l 96 l.len++ 97 return e 98 } 99 100 // insertValue is a convenience wrapper for insert(&Element{Value: v}, at). 101 func (l *List) insertValue(v interface{}, score []byte, at *Element) *Element { 102 now := time.Now().Unix() 103 return l.insert(&Element{Value: v, Score: score, InsertTime: now}, at) 104 } 105 106 // remove removes e from its list, decrements l.len, and returns e. 107 func (l *List) remove(e *Element) *Element { 108 e.prev.next = e.next 109 e.next.prev = e.prev 110 e.next = nil // avoid memory leaks 111 e.prev = nil // avoid memory leaks 112 e.list = nil 113 l.len-- 114 return e 115 } 116 117 // move moves e to next to at and returns e. 118 func (l *List) move(e, at *Element) *Element { 119 if e == at { 120 return e 121 } 122 e.prev.next = e.next 123 e.next.prev = e.prev 124 125 n := at.next 126 at.next = e 127 e.prev = at 128 e.next = n 129 n.prev = e 130 131 return e 132 } 133 134 // Remove removes e from l if e is an element of list l. 135 // It returns the element value e.Value. 136 // The element must not be nil. 137 func (l *List) Remove(e *Element) interface{} { 138 if e.list == l { 139 // if e.list == l, l must have been initialized when e was inserted 140 // in l or l == nil (e is a zero Element) and l.remove will crash 141 l.remove(e) 142 } 143 return e.Value 144 } 145 146 // PushFront inserts a new element e with value v at the front of list l and returns e. 147 func (l *List) PushFront(v interface{}, score []byte) *Element { 148 l.lazyInit() 149 return l.insertValue(v, score, &l.root) 150 } 151 152 // PushBack inserts a new element e with value v at the back of list l and returns e. 153 func (l *List) PushBack(v interface{}, score []byte) *Element { 154 l.lazyInit() 155 return l.insertValue(v, score, l.root.prev) 156 } 157 158 // InsertBefore inserts a new element e with value v immediately before mark and returns e. 159 // If mark is not an element of l, the list is not modified. 160 // The mark must not be nil. 161 func (l *List) InsertBefore(v interface{}, score []byte, mark *Element) *Element { 162 if mark.list != l { 163 return nil 164 } 165 // see comment in List.Remove about initialization of l 166 return l.insertValue(v, score, mark.prev) 167 } 168 169 // InsertAfter inserts a new element e with value v immediately after mark and returns e. 170 // If mark is not an element of l, the list is not modified. 171 // The mark must not be nil. 172 func (l *List) InsertAfter(v interface{}, score []byte, mark *Element) *Element { 173 if mark.list != l { 174 return nil 175 } 176 // see comment in List.Remove about initialization of l 177 return l.insertValue(v, score, mark) 178 } 179 180 // MoveToFront moves element e to the front of list l. 181 // If e is not an element of l, the list is not modified. 182 // The element must not be nil. 183 func (l *List) MoveToFront(e *Element) { 184 if e.list != l || l.root.next == e { 185 return 186 } 187 // see comment in List.Remove about initialization of l 188 l.move(e, &l.root) 189 } 190 191 // MoveToBack moves element e to the back of list l. 192 // If e is not an element of l, the list is not modified. 193 // The element must not be nil. 194 func (l *List) MoveToBack(e *Element) { 195 if e.list != l || l.root.prev == e { 196 return 197 } 198 // see comment in List.Remove about initialization of l 199 l.move(e, l.root.prev) 200 } 201 202 // MoveBefore moves element e to its new position before mark. 203 // If e or mark is not an element of l, or e == mark, the list is not modified. 204 // The element and mark must not be nil. 205 func (l *List) MoveBefore(e, mark *Element) { 206 if e.list != l || e == mark || mark.list != l { 207 return 208 } 209 l.move(e, mark.prev) 210 } 211 212 // MoveAfter moves element e to its new position after mark. 213 // If e or mark is not an element of l, or e == mark, the list is not modified. 214 // The element and mark must not be nil. 215 func (l *List) MoveAfter(e, mark *Element) { 216 if e.list != l || e == mark || mark.list != l { 217 return 218 } 219 l.move(e, mark) 220 } 221 222 // PushBackList inserts a copy of an other list at the back of list l. 223 // The lists l and other may be the same. They must not be nil. 224 func (l *List) PushBackList(other *List) { 225 l.lazyInit() 226 for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { 227 l.insertValue(e.Value, e.Score, l.root.prev) 228 } 229 } 230 231 // PushFrontList inserts a copy of an other list at the front of list l. 232 // The lists l and other may be the same. They must not be nil. 233 func (l *List) PushFrontList(other *List) { 234 l.lazyInit() 235 for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { 236 l.insertValue(e.Value, e.Score, &l.root) 237 } 238 } 239 240 // param:offset 从头到尾的偏移量 241 // param:count 数量 242 func (l *List) Range(offset int, count int) []*Element { 243 if offset < 0 || count < 0 { 244 return nil 245 } 246 res := make([]*Element, count) 247 if offset < (l.len >> 1) { 248 // 若offset在左侧,从头到尾遍历 249 e := l.Front() 250 for i := 0; i < offset && e != nil; i++ { 251 e = e.Next() 252 } 253 for i := 0; i < count; i++ { 254 res[i] = e 255 e = e.Next() 256 } 257 } else { 258 // 若offset在右侧,从尾到头遍历,重置offset为从尾到头的偏移量 259 offset = l.len - (offset + count) 260 e := l.Back() 261 for i := 0; i < offset && e != nil; i++ { 262 e = e.Prev() 263 } 264 for i := 0; i < count; i++ { 265 res[count-i-1] = e 266 e = e.Prev() 267 } 268 } 269 return res 270 } 271 272 func (l *List) RangeByScore(min string, max string) []*Element { 273 res := make([]*Element, 0, l.len) 274 for e := l.Front(); e != nil && string(e.Score) <= max; e = e.Next() { 275 if string(e.Score) >= min { 276 res = append(res, e) 277 } 278 } 279 return res 280 }