github.com/grafana/pyroscope@v1.18.0/pkg/metastore/index/tombstones/tombstone_queue.go (about)

     1  package tombstones
     2  
     3  import (
     4  	metastorev1 "github.com/grafana/pyroscope/api/gen/proto/go/metastore/v1"
     5  	"github.com/grafana/pyroscope/pkg/metastore/index/tombstones/store"
     6  )
     7  
     8  type tombstoneQueue struct{ head, tail *tombstones }
     9  
    10  // The only requirement to tombstoneKey is that it must be
    11  // unique and must be received from the raft log.
    12  type tombstoneKey string
    13  
    14  func (k *tombstoneKey) set(t *metastorev1.Tombstones) bool {
    15  	switch {
    16  	case t.Blocks != nil:
    17  		*k = tombstoneKey(t.Blocks.Name)
    18  	case t.Shard != nil:
    19  		*k = tombstoneKey(t.Shard.Name)
    20  	}
    21  	return len(*k) > 0
    22  }
    23  
    24  type tombstones struct {
    25  	store.TombstoneEntry
    26  	next, prev *tombstones
    27  }
    28  
    29  func newTombstoneQueue() *tombstoneQueue { return &tombstoneQueue{} }
    30  
    31  func (q *tombstoneQueue) push(e *tombstones) {
    32  	if q.tail != nil {
    33  		q.tail.next = e
    34  		e.prev = q.tail
    35  	} else if q.head == nil {
    36  		q.head = e
    37  	} else {
    38  		panic("bug: queue has head but tail is nil")
    39  	}
    40  	q.tail = e
    41  }
    42  
    43  func (q *tombstoneQueue) delete(e *tombstones) *tombstones {
    44  	if e.prev != nil {
    45  		e.prev.next = e.next
    46  	} else if e == q.head {
    47  		// This is the head.
    48  		q.head = e.next
    49  	} else {
    50  		panic("bug: attempting to delete a tombstone that is not in the queue")
    51  	}
    52  	if e.next != nil {
    53  		e.next.prev = e.prev
    54  	} else if e == q.tail {
    55  		// This is the tail.
    56  		q.tail = e.prev
    57  	} else {
    58  		panic("bug: attempting to delete a tombstone that is not in the queue")
    59  	}
    60  	e.next = nil
    61  	e.prev = nil
    62  	return e
    63  }
    64  
    65  type tombstoneIter struct {
    66  	head    *tombstones
    67  	current *tombstones
    68  	before  int64
    69  }
    70  
    71  func (t *tombstoneIter) Next() bool {
    72  	if t.head == nil {
    73  		return false
    74  	}
    75  	if t.current == nil {
    76  		t.current = t.head
    77  	} else {
    78  		t.current = t.current.next
    79  	}
    80  	return t.current != nil && t.current.AppendedAt < t.before
    81  }
    82  
    83  func (t *tombstoneIter) At() *metastorev1.Tombstones { return t.current.Tombstones }
    84  
    85  func (t *tombstoneIter) Err() error   { return nil }
    86  func (t *tombstoneIter) Close() error { return nil }