func NewTTLStore(keyFunc KeyFunc, ttl time.Duration) Store {
	return NewExpirationStore(keyFunc, &TTLPolicy{ttl, clock.RealClock{}})
}
NewTTLStore creates and returns a ExpirationCache with a TTLPolicy
package cache
import (
	"sync"
	"time"
	"k8s.io/apimachinery/pkg/util/clock"
	"k8s.io/klog"
)
type ExpirationCache struct {
	cacheStorage     ThreadSafeStore
	keyFunc          KeyFunc
	clock            clock.Clock
	expirationPolicy ExpirationPolicy
	expirationLock sync.Mutex
}
type ExpirationPolicy interface {
	IsExpired(obj *TimestampedEntry) bool
}
type TTLPolicy struct {
	Ttl time.Duration
	Clock clock.Clock
}
func (p *TTLPolicy) IsExpired(obj *TimestampedEntry) bool {
	return p.Ttl > 0 && p.Clock.Since(obj.Timestamp) > p.Ttl
}
type TimestampedEntry struct {
	Obj       interface{}
	Timestamp time.Time
}
func (c *ExpirationCache) getTimestampedEntry(key string) (*TimestampedEntry, bool) {
	item, _ := c.cacheStorage.Get(key)
	if tsEntry, ok := item.(*TimestampedEntry); ok {
		return tsEntry, true
	}
	return nil, false
}
func (c *ExpirationCache) getOrExpire(key string) (interface{}, bool) {
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()
	timestampedItem, exists := c.getTimestampedEntry(key)
	if !exists {
		return nil, false
	}
	if c.expirationPolicy.IsExpired(timestampedItem) {
		klog.V(4).Infof("Entry %v: %+v has expired", key, timestampedItem.Obj)
		c.cacheStorage.Delete(key)
		return nil, false
	}
	return timestampedItem.Obj, true
}
func (c *ExpirationCache) GetByKey(key string) (interface{}, bool, error) {
	obj, exists := c.getOrExpire(key)
	return obj, exists, nil
}
func (c *ExpirationCache) Get(obj interface{}) (interface{}, bool, error) {
	key, err := c.keyFunc(obj)
	if err != nil {
		return nil, false, KeyError{obj, err}
	}
	obj, exists := c.getOrExpire(key)
	return obj, exists, nil
}
func (c *ExpirationCache) List() []interface{} {
	items := c.cacheStorage.List()
	list := make([]interface{}, 0, len(items))
	for _, item := range items {
		obj := item.(*TimestampedEntry).Obj
		if key, err := c.keyFunc(obj); err != nil {
			list = append(list, obj)
		} else if obj, exists := c.getOrExpire(key); exists {
			list = append(list, obj)
		}
	}
	return list
}
func (c *ExpirationCache) ListKeys() []string {
	return c.cacheStorage.ListKeys()
}
func (c *ExpirationCache) Add(obj interface{}) error {
	key, err := c.keyFunc(obj)
	if err != nil {
		return KeyError{obj, err}
	}
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()
	c.cacheStorage.Add(key, &TimestampedEntry{obj, c.clock.Now()})
	return nil
}
func (c *ExpirationCache) Update(obj interface{}) error {
	return c.Add(obj)
}
func (c *ExpirationCache) Delete(obj interface{}) error {
	key, err := c.keyFunc(obj)
	if err != nil {
		return KeyError{obj, err}
	}
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()
	c.cacheStorage.Delete(key)
	return nil
}
func (c *ExpirationCache) Replace(list []interface{}, resourceVersion string) error {
	items := make(map[string]interface{}, len(list))
	ts := c.clock.Now()
	for _, item := range list {
		key, err := c.keyFunc(item)
		if err != nil {
			return KeyError{item, err}
		}
		items[key] = &TimestampedEntry{item, ts}
	}
	c.expirationLock.Lock()
	defer c.expirationLock.Unlock()
	c.cacheStorage.Replace(items, resourceVersion)
	return nil
}
func (c *ExpirationCache) Resync() error {
	return c.cacheStorage.Resync()
}