// 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) } }
// delete removes a watcher from the group. func (wg *watcherGroup) delete(wa *watcher) bool { if _, ok := wg.watchers[wa]; !ok { return false } wg.watchers.delete(wa) if wa.end == nil { wg.keyWatchers.delete(wa) return true } ivl := adt.NewStringAffineInterval(string(wa.key), string(wa.end)) iv := wg.ranges.Find(ivl) if iv == nil { return false } ws := iv.Val.(watcherSet) delete(ws, wa) if len(ws) == 0 { // remove interval missing watchers if ok := wg.ranges.Delete(ivl); !ok { panic("could not remove watcher from interval tree") } } return true }
// add puts a watcher in the group. func (wg *watcherGroup) add(wa *watcher) { wg.watchers.add(wa) if wa.end == nil { wg.keyWatchers.add(wa) return } // interval already registered? ivl := adt.NewStringAffineInterval(string(wa.key), string(wa.end)) if iv := wg.ranges.Find(ivl); iv != nil { iv.Val.(watcherSet).add(wa) return } // not registered, put in interval tree ws := make(watcherSet) ws.add(wa) wg.ranges.Insert(ivl, ws) }
// 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) }