package peer import ( "time" "go.mau.fi/mautrix-telegram/pkg/gotd/tg" ) type nodeData struct { key string value tg.InputPeerClass expiresAt time.Time } type linkedNode struct { next, prev *linkedNode nodeData } // linkedList is a doubly linked list implementation. // This implementation is highly inspired by container/list, but type safe. type linkedList struct { root linkedNode len int } // Front returns the first element of list l or nil if the list is empty. func (l *linkedList) Front() *linkedNode { if l.len == 0 { return nil } return l.root.next } // Back returns the last element of list l or nil if the list is empty. func (l *linkedList) Back() *linkedNode { if l.len == 0 { return nil } return l.root.prev } // insert inserts e after at, increments l.len, and returns e. func (l *linkedList) insert(e, at *linkedNode) *linkedNode { e.prev = at e.next = at.next e.prev.next = e e.next.prev = e l.len++ return e } func (l *linkedList) insertValue(v nodeData, at *linkedNode) *linkedNode { e := new(linkedNode) e.nodeData = v return l.insert(e, at) } // PushFront inserts a new element e with value v at the front of list l and returns e. func (l *linkedList) PushFront(v nodeData) *linkedNode { l.lazyInit() return l.insertValue(v, &l.root) } // lazyInit lazily initializes a zero List value. func (l *linkedList) lazyInit() { if l.root.next == nil { l.root.next = &l.root l.root.prev = &l.root l.len = 0 } } // remove removes e from its list, decrements l.len, and returns e. func (l *linkedList) remove(e *linkedNode) nodeData { e.prev.next = e.next e.next.prev = e.prev e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks l.len-- value := e.nodeData return value } // move moves e to next to at and returns e. func (l *linkedList) move(e, at *linkedNode) *linkedNode { if e == at { return e } e.prev.next = e.next e.next.prev = e.prev e.prev = at e.next = at.next e.prev.next = e e.next.prev = e return e } // Remove removes e from l if e is an element of list l. // It returns the element value e.Value. // The element must not be nil. func (l *linkedList) Remove(e *linkedNode) nodeData { return l.remove(e) } // MoveToFront moves element e to the front of list l. // If e is not an element of l, the list is not modified. // The element must not be nil. func (l *linkedList) MoveToFront(e *linkedNode) { if l.root.next == e { return } // see comment in List.Remove about initialization of l l.move(e, &l.root) }