reject_cache.go 2.9 KB

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