github.com/gofiber/fiber/v2@v2.47.0/middleware/cache/heap.go (about) 1 package cache 2 3 import ( 4 "container/heap" 5 ) 6 7 type heapEntry struct { 8 key string 9 exp uint64 10 bytes uint 11 idx int 12 } 13 14 // indexedHeap is a regular min-heap that allows finding 15 // elements in constant time. It does so by handing out special indices 16 // and tracking entry movement. 17 // 18 // indexdedHeap is used for quickly finding entries with the lowest 19 // expiration timestamp and deleting arbitrary entries. 20 type indexedHeap struct { 21 // Slice the heap is built on 22 entries []heapEntry 23 // Mapping "index" to position in heap slice 24 indices []int 25 // Max index handed out 26 maxidx int 27 } 28 29 func (h indexedHeap) Len() int { 30 return len(h.entries) 31 } 32 33 func (h indexedHeap) Less(i, j int) bool { 34 return h.entries[i].exp < h.entries[j].exp 35 } 36 37 func (h indexedHeap) Swap(i, j int) { 38 h.entries[i], h.entries[j] = h.entries[j], h.entries[i] 39 h.indices[h.entries[i].idx] = i 40 h.indices[h.entries[j].idx] = j 41 } 42 43 func (h *indexedHeap) Push(x interface{}) { 44 h.pushInternal(x.(heapEntry)) //nolint:forcetypeassert // Forced type assertion required to implement the heap.Interface interface 45 } 46 47 func (h *indexedHeap) Pop() interface{} { 48 n := len(h.entries) 49 h.entries = h.entries[0 : n-1] 50 return h.entries[0:n][n-1] 51 } 52 53 func (h *indexedHeap) pushInternal(entry heapEntry) { 54 h.indices[entry.idx] = len(h.entries) 55 h.entries = append(h.entries, entry) 56 } 57 58 // Returns index to track entry 59 func (h *indexedHeap) put(key string, exp uint64, bytes uint) int { 60 idx := 0 61 if len(h.entries) < h.maxidx { 62 // Steal index from previously removed entry 63 // capacity > size is guaranteed 64 n := len(h.entries) 65 idx = h.entries[:n+1][n].idx 66 } else { 67 idx = h.maxidx 68 h.maxidx++ 69 h.indices = append(h.indices, idx) 70 } 71 // Push manually to avoid allocation 72 h.pushInternal(heapEntry{ 73 key: key, exp: exp, idx: idx, bytes: bytes, 74 }) 75 heap.Fix(h, h.Len()-1) 76 return idx 77 } 78 79 func (h *indexedHeap) removeInternal(realIdx int) (string, uint) { 80 x := heap.Remove(h, realIdx).(heapEntry) //nolint:forcetypeassert,errcheck // Forced type assertion required to implement the heap.Interface interface 81 return x.key, x.bytes 82 } 83 84 // Remove entry by index 85 func (h *indexedHeap) remove(idx int) (string, uint) { 86 return h.removeInternal(h.indices[idx]) 87 } 88 89 // Remove entry with lowest expiration time 90 func (h *indexedHeap) removeFirst() (string, uint) { 91 return h.removeInternal(0) 92 }