...

Source file src/github.com/jellydator/ttlcache/v3/expiration_queue.go

Documentation: github.com/jellydator/ttlcache/v3

     1  package ttlcache
     2  
     3  import (
     4  	"container/heap"
     5  	"container/list"
     6  )
     7  
     8  // expirationQueue stores items that are ordered by their expiration
     9  // timestamps. The 0th item is closest to its expiration.
    10  type expirationQueue[K comparable, V any] []*list.Element
    11  
    12  // newExpirationQueue creates and initializes a new expiration queue.
    13  func newExpirationQueue[K comparable, V any]() expirationQueue[K, V] {
    14  	q := make(expirationQueue[K, V], 0)
    15  	heap.Init(&q)
    16  	return q
    17  }
    18  
    19  // isEmpty checks if the queue is empty.
    20  func (q expirationQueue[K, V]) isEmpty() bool {
    21  	return q.Len() == 0
    22  }
    23  
    24  // update updates an existing item's value and position in the queue.
    25  func (q *expirationQueue[K, V]) update(elem *list.Element) {
    26  	heap.Fix(q, elem.Value.(*Item[K, V]).queueIndex)
    27  }
    28  
    29  // push pushes a new item into the queue and updates the order of its
    30  // elements.
    31  func (q *expirationQueue[K, V]) push(elem *list.Element) {
    32  	heap.Push(q, elem)
    33  }
    34  
    35  // remove removes an item from the queue and updates the order of its
    36  // elements.
    37  func (q *expirationQueue[K, V]) remove(elem *list.Element) {
    38  	heap.Remove(q, elem.Value.(*Item[K, V]).queueIndex)
    39  }
    40  
    41  // Len returns the total number of items in the queue.
    42  func (q expirationQueue[K, V]) Len() int {
    43  	return len(q)
    44  }
    45  
    46  // Less checks if the item at the i position expires sooner than
    47  // the one at the j position.
    48  func (q expirationQueue[K, V]) Less(i, j int) bool {
    49  	item1, item2 := q[i].Value.(*Item[K, V]), q[j].Value.(*Item[K, V])
    50  	if item1.expiresAt.IsZero() {
    51  		return false
    52  	}
    53  
    54  	if item2.expiresAt.IsZero() {
    55  		return true
    56  	}
    57  
    58  	return item1.expiresAt.Before(item2.expiresAt)
    59  }
    60  
    61  // Swap switches the places of two queue items.
    62  func (q expirationQueue[K, V]) Swap(i, j int) {
    63  	q[i], q[j] = q[j], q[i]
    64  	q[i].Value.(*Item[K, V]).queueIndex = i
    65  	q[j].Value.(*Item[K, V]).queueIndex = j
    66  }
    67  
    68  // Push appends a new item to the item slice.
    69  func (q *expirationQueue[K, V]) Push(x interface{}) {
    70  	elem := x.(*list.Element)
    71  	elem.Value.(*Item[K, V]).queueIndex = len(*q)
    72  	*q = append(*q, elem)
    73  }
    74  
    75  // Pop removes and returns the last item.
    76  func (q *expirationQueue[K, V]) Pop() interface{} {
    77  	old := *q
    78  	i := len(old) - 1
    79  	elem := old[i]
    80  	elem.Value.(*Item[K, V]).queueIndex = -1
    81  	old[i] = nil // avoid memory leak
    82  	*q = old[:i]
    83  
    84  	return elem
    85  }
    86  

View as plain text