| 210 | } |
| 211 | |
| 212 | func (g *Group) Get(ctx context.Context, key string, dest Sink) error { |
| 213 | g.peersOnce.Do(g.initPeers) |
| 214 | g.Stats.Gets.Add(1) |
| 215 | if dest == nil { |
| 216 | return errors.New("groupcache: nil dest Sink") |
| 217 | } |
| 218 | value, cacheHit := g.lookupCache(key) |
| 219 | |
| 220 | if cacheHit { |
| 221 | g.Stats.CacheHits.Add(1) |
| 222 | return setSinkView(dest, value) |
| 223 | } |
| 224 | |
| 225 | // Optimization to avoid double unmarshalling or copying: keep |
| 226 | // track of whether the dest was already populated. One caller |
| 227 | // (if local) will set this; the losers will not. The common |
| 228 | // case will likely be one caller. |
| 229 | destPopulated := false |
| 230 | value, destPopulated, err := g.load(ctx, key, dest) |
| 231 | if err != nil { |
| 232 | return err |
| 233 | } |
| 234 | if destPopulated { |
| 235 | return nil |
| 236 | } |
| 237 | return setSinkView(dest, value) |
| 238 | } |
| 239 | |
| 240 | // load loads key either by invoking the getter locally or by sending it to another machine. |
| 241 | func (g *Group) load(ctx context.Context, key string, dest Sink) (value ByteView, destPopulated bool, err error) { |