Вопрос проверяет знание идиом Go для управления временем жизни данных в map, включая использование отдельных структур с TTL и горутин для очистки.
Стандартная map в Go не поддерживает автоматическое удаление записей по времени жизни (TTL). Если вам нужно кэшировать данные с истечением срока, необходимо реализовать эту логику самостоятельно. Основная идея — хранить вместе с каждым значением метку времени, когда оно должно быть удалено, и периодически проверять и чистить устаревшие записи.
Создадим структуру, которая хранит значение и время истечения. Для потокобезопасности используем sync.RWMutex. Отдельная горутина с time.Ticker будет выполнять очистку.
type Item struct {
Value interface{}
Expiration int64 // Unix timestamp
}
type TTLMap struct {
items map[string]Item
mu sync.RWMutex
}
func NewTTLMap(cleanupInterval time.Duration) *TTLMap {
tm := &TTLMap{
items: make(map[string]Item),
}
go tm.cleanupLoop(cleanupInterval)
return tm
}
func (tm *TTLMap) Set(key string, value interface{}, ttl time.Duration) {
tm.mu.Lock()
defer tm.mu.Unlock()
tm.items[key] = Item{
Value: value,
Expiration: time.Now().Add(ttl).Unix(),
}
}
func (tm *TTLMap) Get(key string) (interface{}, bool) {
tm.mu.RLock()
defer tm.mu.RUnlock()
item, ok := tm.items[key]
if !ok || time.Now().Unix() > item.Expiration {
return nil, false
}
return item.Value, true
}
func (tm *TTLMap) cleanupLoop(interval time.Duration) {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for range ticker.C {
tm.mu.Lock()
now := time.Now().Unix()
for k, v := range tm.items {
if now > v.Expiration {
delete(tm.items, k)
}
}
tm.mu.Unlock()
}
}При большом количестве записей полный проход по map может быть дорогим. Можно использовать кучу (heap) для хранения ключей по времени истечения, чтобы удалять только просроченные записи. Однако для большинства случаев простая горутина с тикером работает достаточно эффективно. Также существуют проверенные библиотеки, такие как go-cache (github.com/patrickmn/go-cache) или freecache, которые предоставляют готовую функциональность TTL-кэша с оптимизациями.
Реализация TTL в map Go требует ручного управления временем и горутиной для очистки. Это простой и эффективный способ для кэширования данных с истечением срока, особенно когда не нужна сложная логика вытеснения. Для production-систем рекомендуется использовать проверенные библиотеки, чтобы избежать ошибок синхронизации и улучшить производительность.