// cached returns a FileReader for the given blobref, which may
// point to either a blob representing the entire thumbnail (max
// 16MB) or a file schema blob.
//
// The ReadCloser should be closed when done reading.
541429
func (ih *ImageHandler) cached(ctx context.Context, br blob.Ref) (io.ReadCloser, error) {
	rsc, _, err := ih.Cache.Fetch(ctx, br)
	if err != nil {
		return nil, err
	}
	slurp, err := ioutil.ReadAll(rsc)
	rsc.Close()
	if err != nil {
		return nil, err
	}
	// In the common case, when the scaled image itself is less than 16 MB, it's
	// all together in one blob.
	if strings.HasPrefix(magic.MIMEType(slurp), "image/") {
		thumbCacheHitFull.Add(1)
		if imageDebug {
			log.Printf("Image Cache: hit: %v\n", br)
		}
		return ioutil.NopCloser(bytes.NewReader(slurp)), nil
	}

	// For large scaled images, the cached blob is a file schema blob referencing
	// the sub-chunks.
	fileBlob, err := schema.BlobFromReader(br, bytes.NewReader(slurp))
	if err != nil {
		log.Printf("Failed to parse non-image thumbnail cache blob %v: %v", br, err)
		return nil, err
	}
	fr, err := fileBlob.NewFileReader(ih.Cache)
	if err != nil {
		log.Printf("cached(%v) NewFileReader = %v", br, err)
		return nil, err
	}
	thumbCacheHitFile.Add(1)
	if imageDebug {
		log.Printf("Image Cache: fileref hit: %v\n", br)
	}
	return fr, nil
}
365189
func (r *buffer) readLimited(n int, src *countReader) error {
	if r.hasData() {
		panic("bgzf: read into non-empty buffer")
	}
	r.off = 0
	var err error
	r.size, err = io.ReadFull(src, r.data[:n])
	return err
}
19160
func (cache *DiskBlockCacheLocal) deleteLocked(ctx context.Context,
	blockEntries []kbfsblock.ID) (numRemoved int, sizeRemoved int64,
	err error) {
	if len(blockEntries) == 0 {
		return 0, 0, nil
	}
	defer func() {
		if err == nil {
			cache.deleteCountMeter.Mark(int64(numRemoved))
			cache.deleteSizeMeter.Mark(sizeRemoved)
		}
	}()
	blockBatch := new(leveldb.Batch)
	metadataBatch := new(leveldb.Batch)
	tlfBatch := new(leveldb.Batch)
	removalCounts := make(map[tlf.ID]int)
	removalSizes := make(map[tlf.ID]uint64)
	for _, entry := range blockEntries {
		blockKey := entry.Bytes()
		metadataBytes, err := cache.metaDb.Get(blockKey, nil)
		if err != nil {
			// If we can't retrieve the block, don't try to delete it, and
			// don't account for its non-presence.
			continue
		}
		metadata := DiskBlockCacheMetadata{}
		err = cache.config.Codec().Decode(metadataBytes, &metadata)
		if err != nil {
			return 0, 0, err
		}
		blockBatch.Delete(blockKey)
		metadataBatch.Delete(blockKey)
		tlfDbKey := cache.tlfKey(metadata.TlfID, blockKey)
		tlfBatch.Delete(tlfDbKey)
		removalCounts[metadata.TlfID]++
		removalSizes[metadata.TlfID] += uint64(metadata.BlockSize)
		sizeRemoved += int64(metadata.BlockSize)
		numRemoved++
	}
	// TODO: more gracefully handle non-atomic failures here.
	if err := cache.metaDb.Write(metadataBatch, nil); err != nil {
		return 0, 0, err
	}
	if err := cache.tlfDb.Write(tlfBatch, nil); err != nil {
		return 0, 0, err
	}
	if err := cache.blockDb.Write(blockBatch, nil); err != nil {
		return 0, 0, err
	}

	// Update the cache's totals.
	for k, v := range removalCounts {
		cache.tlfCounts[k] -= v
		cache.priorityBlockCounts[cache.homeDirs[k]] -= v
		cache.priorityTlfMap[cache.homeDirs[k]][k] -= v
		cache.numBlocks -= v
		cache.tlfSizes[k] -= removalSizes[k]
		cache.subCurrBytes(removalSizes[k])
	}
	if cache.useLimiter() {
		cache.config.DiskLimiter().release(ctx, cache.cacheType,
			sizeRemoved, 0)
	}

	return numRemoved, sizeRemoved, nil
}
165088
func (bg *Reader) cachePut(b Block) (evicted Block, retained bool) {
	if b == nil || !b.hasData() {
		return b, false
	}
	return bg.cache.Put(b)
}
1314344
func (c *Context) CacheLoad(name, path string, value interface{}) (ckey CacheKey, found bool) {
	ckey, data, found := c.CacheRead(name, path)
	if found {
		if err := gob.NewDecoder(bytes.NewBuffer(data)).Decode(value); err != nil {
			c.Criticalf("gob Decode: %v", err)
			found = false
		}
	}
	return
}
116578
func CacheHandler(h http.Handler, webDir string) http.Handler {
	return &cacheHandler{
		Handler: h,
		webDir:  webDir,
	}
}
251518
func (cm *cacheManager) getRecord(ctx context.Context, id string, fromSnapshotter bool, opts ...RefOption) (cr *cacheRecord, retErr error) {
	if rec, ok := cm.records[id]; ok {
		if rec.isDead() {
			return nil, errNotFound
		}
		return rec, nil
	}

	md, ok := cm.md.Get(id)
	if !ok && !fromSnapshotter {
		return nil, errNotFound
	}
	if mutableID := getEqualMutable(md); mutableID != "" {
		mutable, err := cm.getRecord(ctx, mutableID, fromSnapshotter)
		if err != nil {
			// check loading mutable deleted record from disk
			if errors.Cause(err) == errNotFound {
				cm.md.Clear(id)
			}
			return nil, err
		}
		rec := &cacheRecord{
			mu:           &sync.Mutex{},
			cm:           cm,
			refs:         make(map[ref]struct{}),
			parent:       mutable.parentRef(false),
			md:           md,
			equalMutable: &mutableRef{cacheRecord: mutable},
		}
		mutable.equalImmutable = &immutableRef{cacheRecord: rec}
		cm.records[id] = rec
		return rec, nil
	}

	info, err := cm.Snapshotter.Stat(ctx, id)
	if err != nil {
		return nil, errors.Wrap(errNotFound, err.Error())
	}

	var parent ImmutableRef
	if info.Parent != "" {
		parent, err = cm.get(ctx, info.Parent, fromSnapshotter, append(opts, NoUpdateLastUsed)...)
		if err != nil {
			return nil, err
		}
		defer func() {
			if retErr != nil {
				parent.Release(context.TODO())
			}
		}()
	}

	rec := &cacheRecord{
		mu:      &sync.Mutex{},
		mutable: info.Kind != snapshots.KindCommitted,
		cm:      cm,
		refs:    make(map[ref]struct{}),
		parent:  parent,
		md:      md,
	}

	// the record was deleted but we crashed before data on disk was removed
	if getDeleted(md) {
		if err := rec.remove(ctx, true); err != nil {
			return nil, err
		}
		return nil, errNotFound
	}

	if err := initializeMetadata(rec, opts...); err != nil {
		if parent != nil {
			parent.Release(context.TODO())
		}
		return nil, err
	}

	cm.records[id] = rec
	return rec, nil
}
74509
func (cache *DiskQuotaCacheLocal) checkCacheLocked(
	ctx context.Context, method string) error {
	// First see if the context has expired since we began.
	select {
	case <-ctx.Done():
		return ctx.Err()
	default:
	}

	select {
	case <-cache.startedCh:
	case <-cache.startErrCh:
		// The cache will never be started. No need for a stack here since this
		// could happen anywhere.
		return DiskCacheStartingError{method}
	default:
		// If the cache hasn't started yet, return an error.  No need for a
		// stack here since this could happen anywhere.
		return DiskCacheStartingError{method}
	}
	// shutdownCh has to be checked under lock, otherwise we can race.
	select {
	case <-cache.shutdownCh:
		return errors.WithStack(DiskCacheClosedError{method})
	default:
	}
	if cache.db == nil {
		return errors.WithStack(DiskCacheClosedError{method})
	}
	return nil
}
1074544
func (s *CommonStorageDB) ClearCachedVersions() {
	bulkOptimizable, ok := s.VersionedDB.(statedb.BulkOptimizable)
	if ok {
		bulkOptimizable.ClearCachedVersions()
	}
}
417397
func NewCachingFetcher(cache blobserver.Cache, fetcher blob.Fetcher) *CachingFetcher {
	return &CachingFetcher{c: cache, sf: fetcher}
}
87121
func (r *cachingReadCloser) Read(p []byte) (n int, err error) {
	n, err = r.R.Read(p)
	r.buf.Write(p[:n])
	if err == io.EOF {
		r.OnEOF(bytes.NewReader(r.buf.Bytes()))
	}
	return n, err
}
1078230
func (c *DiskTokenCache) readCacheFile() (*cacheFile, error) {
	// Minimize the time the file is locked on Windows by reading it all at once
	// and decoding later.
	//
	// We also need to open it with FILE_SHARE_DELETE sharing mode to allow
	// writeCacheFile() below to replace open files (even though it tries to wait
	// for the file to be closed). For some reason, omitting FILE_SHARE_DELETE
	// flag causes random sharing violation errors when opening the file for
	// reading.
	f, err := openSharedDelete(c.absPath())
	switch {
	case os.IsNotExist(err):
		return &cacheFile{}, nil
	case err != nil:
		return nil, err
	}
	blob, err := ioutil.ReadAll(f)
	f.Close()
	if err != nil {
		return nil, err
	}

	cache := &cacheFile{}
	if err := json.Unmarshal(blob, cache); err != nil {
		// If the cache file got broken somehow, it makes sense to treat it as
		// empty (so it can later be overwritten), since it's unlikely it's going
		// to "fix itself".
		logging.WithError(err).Warningf(c.Context, "The token cache %s is broken", c.absPath())
		return &cacheFile{}, nil
	}

	return cache, nil
}
1055938
func (zip GobMeddler) PostRead(fieldAddr, scanTarget interface{}) error {
	ptr := scanTarget.(*[]byte)
	if ptr == nil {
		return fmt.Errorf("GobMeddler.PostRead: nil pointer")
	}
	raw := *ptr

	if zip {
		// un-gzip and decode gob
		gzipReader, err := gzip.NewReader(bytes.NewReader(raw))
		if err != nil {
			return fmt.Errorf("Error creating gzip Reader: %v", err)
		}
		defer gzipReader.Close()
		gobDecoder := gob.NewDecoder(gzipReader)
		if err := gobDecoder.Decode(fieldAddr); err != nil {
			return fmt.Errorf("Gob decoder/gzip error: %v", err)
		}
		if err := gzipReader.Close(); err != nil {
			return fmt.Errorf("Closing gzip reader: %v", err)
		}

		return nil
	}

	// decode gob
	gobDecoder := gob.NewDecoder(bytes.NewReader(raw))
	if err := gobDecoder.Decode(fieldAddr); err != nil {
		return fmt.Errorf("Gob decode error: %v", err)
	}

	return nil
}
1064706
func CacheHandler(w http.ResponseWriter, r *http.Request) {
	if r.Header.Get("If-Modified-Since") != "" || r.Header.Get("If-None-Match") != "" {
		w.WriteHeader(http.StatusNotModified)
		return
	}
	GetHandler(w, r)
}
722790
func NewCompressedReader(rs io.ReadSeeker) (io.ReadCloser, error) {

	var (
		dr  io.ReadCloser
		err error
	)

	_, err = rs.Seek(0, 0)
	if err != nil {
		return nil, err
	}

	ftype, err := DetectFileType(rs)
	if err != nil {
		return nil, err
	}

	_, err = rs.Seek(0, 0)
	if err != nil {
		return nil, err
	}

	switch ftype {
	case TypeGzip:
		dr, err = gzip.NewReader(rs)
		if err != nil {
			return nil, err
		}
	case TypeBzip2:
		dr = ioutil.NopCloser(bzip2.NewReader(rs))
	case TypeXz:
		dr, err = NewXzReader(rs)
		if err != nil {
			return nil, err
		}
	case TypeTar:
		dr = ioutil.NopCloser(rs)
	case TypeUnknown:
		return nil, errors.New("error: unknown image filetype")
	default:
		return nil, errors.New("no type returned from DetectFileType?")
	}
	return dr, nil
}
489616
func (c *Conn) ClearCache(clearId bool, clearBloom bool, args map[string]interface{}, indices ...string) (ExtendedStatus, error) {
	var retval ExtendedStatus
	var clearCacheUrl string
	if len(indices) > 0 {
		clearCacheUrl = fmt.Sprintf("/%s/_cache/clear", strings.Join(indices, ","))

	} else {
		clearCacheUrl = fmt.Sprintf("/_cache/clear")
	}

	body, err := c.DoCommand("POST", clearCacheUrl, args, nil)
	if err != nil {
		return retval, err
	}
	if err == nil {
		// marshall into json
		jsonErr := json.Unmarshal(body, &retval)
		if jsonErr != nil {
			return retval, jsonErr
		}
	}
	return retval, err
}
366249
func (cache *DiskMDCacheLocal) getMetadataLocked(
	tlfID tlf.ID, metered bool) (metadata diskMDBlock, err error) {
	var hitMeter, missMeter *CountMeter
	if metered {
		hitMeter = cache.hitMeter
		missMeter = cache.missMeter
	}

	metadataBytes, err := cache.headsDb.GetWithMeter(
		tlfID.Bytes(), hitMeter, missMeter)
	if err != nil {
		return diskMDBlock{}, err
	}
	err = cache.config.Codec().Decode(metadataBytes, &metadata)
	if err != nil {
		return diskMDBlock{}, err
	}
	return metadata, nil
}