blob: f13dec444dfc6f7e6385689b9bf48c827bc8f126 [file] [log] [blame]
package caching
import (
"context"
"encoding/json"
"github.com/jackc/pgx/v4/pgxpool"
"go.skia.org/infra/go/cache"
"go.skia.org/infra/go/skerr"
)
type SearchCacheType int
const (
// ByBlame_Corpus denotes the cache type for untriaged images by commits for a given corpus.
ByBlame_Corpus SearchCacheType = iota
)
// SearchCacheManager provides a struct to handle the cache operations for gold search.
type SearchCacheManager struct {
cacheClient cache.Cache
db *pgxpool.Pool
corpora []string
commitWindow int
dataProviders map[SearchCacheType]cacheDataProvider
}
// New returns a new instance of the SearchCacheManager.
func New(cacheClient cache.Cache, db *pgxpool.Pool, corpora []string, commitWindow int) *SearchCacheManager {
return &SearchCacheManager{
cacheClient: cacheClient,
db: db,
corpora: corpora,
commitWindow: commitWindow,
dataProviders: map[SearchCacheType]cacheDataProvider{
ByBlame_Corpus: NewByBlameDataProvider(db, corpora, commitWindow),
},
}
}
// RunCachePopulation gets the cache data from the providers and stores it in the cache instance.
func (s SearchCacheManager) RunCachePopulation(ctx context.Context) error {
for _, prov := range s.dataProviders {
data, err := prov.GetCacheData(ctx)
if err != nil {
return skerr.Wrapf(err, "Error while running cache population with provider %s", prov)
}
for key, val := range data {
err := s.cacheClient.SetValue(ctx, key, val)
if err != nil {
return skerr.Wrapf(err, "Error while setting value in cache.")
}
}
}
return nil
}
// GetByBlameData returns the by blame data for the given corpus from cache.
func (s SearchCacheManager) GetByBlameData(ctx context.Context, corpus string) ([]ByBlameData, error) {
cacheKey := ByBlameKey(corpus)
data := []ByBlameData{}
jsonStr, err := s.cacheClient.GetValue(ctx, cacheKey)
if err != nil {
return data, skerr.Wrapf(err, "Error retrieving by blame data from cache for key %s corpus %s", cacheKey, corpus)
}
// This is the case when there is a cache miss.
if jsonStr == "" {
provider := s.dataProviders[ByBlame_Corpus].(ByBlameDataProvider)
return provider.GetDataForCorpus(ctx, corpus)
}
err = json.Unmarshal([]byte(jsonStr), &data)
return data, err
}