// Add adds the response of a request to the cache if its revision is larger than the compacted revision of the cache. func (c *cache) Add(req *pb.RangeRequest, resp *pb.RangeResponse) { key := keyFunc(req) c.mu.Lock() defer c.mu.Unlock() if req.Revision > c.compactedRev { c.lru.Add(key, resp) } // we do not need to invalidate a request with a revision specified. // so we do not need to add it into the reverse index. if req.Revision != 0 { return } var ( iv *adt.IntervalValue ivl adt.Interval ) if len(req.RangeEnd) != 0 { ivl = adt.NewStringAffineInterval(string(req.Key), string(req.RangeEnd)) } else { ivl = adt.NewStringAffinePoint(string(req.Key)) } iv = c.cachedRanges.Find(ivl) if iv == nil { c.cachedRanges.Insert(ivl, []string{key}) } else { iv.Val = append(iv.Val.([]string), key) } }
// watcherSetByKey gets the set of watchers that recieve events on the given key. func (wg *watcherGroup) watcherSetByKey(key string) watcherSet { wkeys := wg.keyWatchers[key] wranges := wg.ranges.Stab(adt.NewStringAffinePoint(key)) // zero-copy cases switch { case len(wranges) == 0: // no need to merge ranges or copy; reuse single-key set return wkeys case len(wranges) == 0 && len(wkeys) == 0: return nil case len(wranges) == 1 && len(wkeys) == 0: return wranges[0].Val.(watcherSet) } // copy case ret := make(watcherSet) ret.union(wg.keyWatchers[key]) for _, item := range wranges { ret.union(item.Val.(watcherSet)) } return ret }
// Invalidate invalidates the cache entries that intersecting with the given range from key to endkey. func (c *cache) Invalidate(key, endkey []byte) { c.mu.Lock() defer c.mu.Unlock() var ( ivs []*adt.IntervalValue ivl adt.Interval ) if len(endkey) == 0 { ivl = adt.NewStringAffinePoint(string(key)) } else { ivl = adt.NewStringAffineInterval(string(key), string(endkey)) } ivs = c.cachedRanges.Stab(ivl) for _, iv := range ivs { keys := iv.Val.([]string) for _, key := range keys { c.lru.Remove(key) } } // delete after removing all keys since it is destructive to 'ivs' c.cachedRanges.Delete(ivl) }
// contains is whether the given key has a watcher in the group. func (wg *watcherGroup) contains(key string) bool { _, ok := wg.keyWatchers[key] return ok || wg.ranges.Contains(adt.NewStringAffinePoint(key)) }