github.com/decred/dcrlnd@v0.7.6/channeldb/reject_cache.go (about)

     1  package channeldb
     2  
     3  // rejectFlags is a compact representation of various metadata stored by the
     4  // reject cache about a particular channel.
     5  type rejectFlags uint8
     6  
     7  const (
     8  	// rejectFlagExists is a flag indicating whether the channel exists,
     9  	// i.e. the channel is open and has a recent channel update. If this
    10  	// flag is not set, the channel is either a zombie or unknown.
    11  	rejectFlagExists rejectFlags = 1 << iota
    12  
    13  	// rejectFlagZombie is a flag indicating whether the channel is a
    14  	// zombie, i.e. the channel is open but has no recent channel updates.
    15  	rejectFlagZombie
    16  )
    17  
    18  // packRejectFlags computes the rejectFlags corresponding to the passed boolean
    19  // values indicating whether the edge exists or is a zombie.
    20  func packRejectFlags(exists, isZombie bool) rejectFlags {
    21  	var flags rejectFlags
    22  	if exists {
    23  		flags |= rejectFlagExists
    24  	}
    25  	if isZombie {
    26  		flags |= rejectFlagZombie
    27  	}
    28  
    29  	return flags
    30  }
    31  
    32  // unpack returns the booleans packed into the rejectFlags. The first indicates
    33  // if the edge exists in our graph, the second indicates if the edge is a
    34  // zombie.
    35  func (f rejectFlags) unpack() (bool, bool) {
    36  	return f&rejectFlagExists == rejectFlagExists,
    37  		f&rejectFlagZombie == rejectFlagZombie
    38  }
    39  
    40  // rejectCacheEntry caches frequently accessed information about a channel,
    41  // including the timestamps of its latest edge policies and whether or not the
    42  // channel exists in the graph.
    43  type rejectCacheEntry struct {
    44  	upd1Time int64
    45  	upd2Time int64
    46  	flags    rejectFlags
    47  }
    48  
    49  // rejectCache is an in-memory cache used to improve the performance of
    50  // HasChannelEdge. It caches information about the whether or channel exists, as
    51  // well as the most recent timestamps for each policy (if they exists).
    52  type rejectCache struct {
    53  	n     int
    54  	edges map[uint64]rejectCacheEntry
    55  }
    56  
    57  // newRejectCache creates a new rejectCache with maximum capacity of n entries.
    58  func newRejectCache(n int) *rejectCache {
    59  	return &rejectCache{
    60  		n:     n,
    61  		edges: make(map[uint64]rejectCacheEntry, n),
    62  	}
    63  }
    64  
    65  // get returns the entry from the cache for chanid, if it exists.
    66  func (c *rejectCache) get(chanid uint64) (rejectCacheEntry, bool) {
    67  	entry, ok := c.edges[chanid]
    68  	return entry, ok
    69  }
    70  
    71  // insert adds the entry to the reject cache. If an entry for chanid already
    72  // exists, it will be replaced with the new entry. If the entry doesn't exists,
    73  // it will be inserted to the cache, performing a random eviction if the cache
    74  // is at capacity.
    75  func (c *rejectCache) insert(chanid uint64, entry rejectCacheEntry) {
    76  	// If entry exists, replace it.
    77  	if _, ok := c.edges[chanid]; ok {
    78  		c.edges[chanid] = entry
    79  		return
    80  	}
    81  
    82  	// Otherwise, evict an entry at random and insert.
    83  	if len(c.edges) == c.n {
    84  		for id := range c.edges {
    85  			delete(c.edges, id)
    86  			break
    87  		}
    88  	}
    89  	c.edges[chanid] = entry
    90  }
    91  
    92  // remove deletes an entry for chanid from the cache, if it exists.
    93  func (c *rejectCache) remove(chanid uint64) {
    94  	delete(c.edges, chanid)
    95  }