<commit_before>package cache

import (
	"context"
	"fmt"
	"io"
	"sort"
	"sync"
	"time"

	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/util/errors"
)

const existingOperatorKey = "@existing"

type SourceKey struct {
	Name      string
	Namespace string
}

func (k *SourceKey) String() string {
	return fmt.Sprintf("%s/%s", k.Name, k.Namespace)
}

func (k *SourceKey) Empty() bool {
	return k.Name == "" && k.Namespace == ""
}

func (k *SourceKey) Equal(compare SourceKey) bool {
	return k.Name == compare.Name && k.Namespace == compare.Namespace
}

// Virtual indicates if this is a "virtual" catalog representing the currently installed operators in a namespace
func (k *SourceKey) Virtual() bool {
	return k.Name == existingOperatorKey && k.Namespace != ""
}

func NewVirtualSourceKey(namespace string) SourceKey {
	return SourceKey{
		Name:      existingOperatorKey,
		Namespace: namespace,
	}
}

type Source interface {
	Snapshot(context.Context) (*Snapshot, error)
}

type SourceProvider interface {
	// TODO: namespaces parameter is an artifact of SourceStore
	Sources(namespaces ...string) map[SourceKey]Source
}

type StaticSourceProvider map[SourceKey]Source

func (p StaticSourceProvider) Sources(namespaces ...string) map[SourceKey]Source {
	result := make(map[SourceKey]Source)
	for key, source := range p {
		for _, namespace := range namespaces {
			if key.Namespace == namespace {
				result[key] = source
				break
			}
		}
	}
	return result
}

type OperatorCacheProvider interface {
	Namespaced(namespaces ...string) MultiCatalogOperatorFinder
}

type SourcePriorityProvider interface {
	Priority(SourceKey) int
}

type constantSourcePriorityProvider int

func (spp constantSourcePriorityProvider) Priority(SourceKey) int {
	return int(spp)
}

type Cache struct {
	logger                 logrus.StdLogger
	sp                     SourceProvider
	sourcePriorityProvider SourcePriorityProvider
	snapshots              map[SourceKey]*snapshotHeader
	ttl                    time.Duration
	sem                    chan struct{}
	m                      sync.RWMutex
}

var _ OperatorCacheProvider = &Cache{}

type Option func(*Cache)

func WithLogger(logger logrus.StdLogger) Option {
	return func(c *Cache) {
		c.logger = logger
	}
}

func WithSourcePriorityProvider(spp SourcePriorityProvider) Option {
	return func(c *Cache) {
		c.sourcePriorityProvider = spp
	}
}

func New(sp SourceProvider, options ...Option) *Cache {
	const (
		MaxConcurrentSnapshotUpdates = 4
	)

	cache := Cache{
		logger: func() logrus.StdLogger {
			logger := logrus.New()
			logger.SetOutput(io.Discard)
			return logger
		}(),
		sp:                     sp,
		sourcePriorityProvider: constantSourcePriorityProvider(0),
		snapshots:              make(map[SourceKey]*snapshotHeader),
		ttl:                    5 * time.Minute,
		sem:                    make(chan struct{}, MaxConcurrentSnapshotUpdates),
	}

	for _, opt := range options {
		opt(&cache)
	}

	return &cache
}

type NamespacedOperatorCache struct {
	snapshots map[SourceKey]*snapshotHeader
}<commit_msg>Remove unused ttl field from cache.Cache. (#2658)<commit_after>package cache

import (
	"context"
	"fmt"
	"io"
	"sort"
	"sync"
	"time"

	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/util/errors"
)

const existingOperatorKey = "@existing"

type SourceKey struct {
	Name      string
	Namespace string
}

func (k *SourceKey) String() string {
	return fmt.Sprintf("%s/%s", k.Name, k.Namespace)
}

func (k *SourceKey) Empty() bool {
	return k.Name == "" && k.Namespace == ""
}

func (k *SourceKey) Equal(compare SourceKey) bool {
	return k.Name == compare.Name && k.Namespace == compare.Namespace
}

// Virtual indicates if this is a "virtual" catalog representing the currently installed operators in a namespace
func (k *SourceKey) Virtual() bool {
	return k.Name == existingOperatorKey && k.Namespace != ""
}

func NewVirtualSourceKey(namespace string) SourceKey {
	return SourceKey{
		Name:      existingOperatorKey,
		Namespace: namespace,
	}
}

type Source interface {
	Snapshot(context.Context) (*Snapshot, error)
}

type SourceProvider interface {
	// TODO: namespaces parameter is an artifact of SourceStore
	Sources(namespaces ...string) map[SourceKey]Source
}

type StaticSourceProvider map[SourceKey]Source

func (p StaticSourceProvider) Sources(namespaces ...string) map[SourceKey]Source {
	result := make(map[SourceKey]Source)
	for key, source := range p {
		for _, namespace := range namespaces {
			if key.Namespace == namespace {
				result[key] = source
				break
			}
		}
	}
	return result
}

type OperatorCacheProvider interface {
	Namespaced(namespaces ...string) MultiCatalogOperatorFinder
}

type SourcePriorityProvider interface {
	Priority(SourceKey) int
}

type constantSourcePriorityProvider int

func (spp constantSourcePriorityProvider) Priority(SourceKey) int {
	return int(spp)
}

type Cache struct {
	logger                 logrus.StdLogger
	sp                     SourceProvider
	sourcePriorityProvider SourcePriorityProvider
	snapshots              map[SourceKey]*snapshotHeader
	sem                    chan struct{}
	m                      sync.RWMutex
}

var _ OperatorCacheProvider = &Cache{}

type Option func(*Cache)

func WithLogger(logger logrus.StdLogger) Option {
	return func(c *Cache) {
		c.logger = logger
	}
}

func WithSourcePriorityProvider(spp SourcePriorityProvider) Option {
	return func(c *Cache) {
		c.sourcePriorityProvider = spp
	}
}

func New(sp SourceProvider, options ...Option) *Cache {
	const (
		MaxConcurrentSnapshotUpdates = 4
	)

	cache := Cache{
		logger: func() logrus.StdLogger {
			logger := logrus.New()
			logger.SetOutput(io.Discard)
			return logger
		}(),
		sp:                     sp,
		sourcePriorityProvider: constantSourcePriorityProvider(0),
		snapshots:              make(map[SourceKey]*snapshotHeader),
		sem:                    make(chan struct{}, MaxConcurrentSnapshotUpdates),
	}

	for _, opt := range options {
		opt(&cache)
	}

	return &cache
}

type NamespacedOperatorCache struct {
	snapshots map[SourceKey]*snapshotHeader
}
{'fraction_non_alphanumeric': 0.10199045895706531, 'fraction_numerical': 0.0018095081427866426, 'mean_word_length': 3.5645645645645647, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3218310', 'n_tokens_mistral': 1901, 'n_tokens_neox': 1800, 'n_words': 479}