code: func (f *fragment) openCache() error {
  	// Determine cache type from field name.
  	switch f.CacheType {
  	case CacheTypeRanked:
  		f.cache = NewRankCache(f.CacheSize)
  	case CacheTypeLRU:
  		f.cache = newLRUCache(f.CacheSize)
  	case CacheTypeNone:
  		f.cache = globalNopCache
  		return nil
  	default:
  		return ErrInvalidCacheType
  	}
  
  	// Read cache data from disk.
  	path := f.cachePath()
  	buf, err := ioutil.ReadFile(path)
  	if os.IsNotExist(err) {
  		return nil
  	} else if err != nil {
  		return fmt.Errorf("open cache: %s", err)
  	}
  
  	// Unmarshal cache data.
  	var pb internal.Cache
  	if err := proto.Unmarshal(buf, &pb); err != nil {
  		f.Logger.Printf("error unmarshaling cache data, skipping: path=%s, err=%s", path, err)
  		return nil
  	}
  
  	// Read in all rows by ID.
  	// This will cause them to be added to the cache.
  	for _, id := range pb.IDs {
  		n := f.storage.CountRange(id*ShardWidth, (id+1)*ShardWidth)
  		f.cache.BulkAdd(id, n)
  	}
  	f.cache.Invalidate()
  
  	return nil
  }
docs: // openCache initializes the cache from row ids persisted to disk.