start work

main v1.0.0
serr 2025-01-02 23:30:51 +03:00
commit c319e788e7
1 changed files with 132 additions and 0 deletions

132
simplecache.go Normal file
View File

@ -0,0 +1,132 @@
package simplecache
import (
"errors"
"fmt"
"sync"
"time"
)
// Элемент в кэше - это данные и время их жизни.
type Item struct {
destroyTimestamp int64 // Момент в Unix-секундах, когда элемент становится устаревшим
data interface{} // Данные
}
// Кэш - это хранилище элементов и инервал его очистки (ну и мьютекс на всякий случай).
// Интервал очистки хранилища укахывается в НАНОСЕКУНДАХ (используй множители для преобразования во что-то другое).
type Cache struct {
sync.RWMutex // Мьютекс ждя реализации безопасного доступа к общим данным
storage map[string]Item // Хранилище элементов
cleanupInterval time.Duration // Интервал очистки хранилища в наносекундах
}
// NewCache создает новый экземпляр Cache с интервалом очистки cleanupInterval.
// Если cleanupInterval < 0, то кэш не будет очищаться автоматически.
func NewCache(cleanupInterval time.Duration) *Cache {
cache := &Cache{
storage: make(map[string]Item),
cleanupInterval: cleanupInterval,
}
// Запускаем Garbage Collector если интервал очистки больше 0
// Иначе (если он отрицательный) кэш будет жить до ручного вызова Cleanup
if cleanupInterval > 0 {
go cache.gc(cleanupInterval)
}
return cache
}
// gc = Garbage Collector.
func (c *Cache) gc(cleanupInterval time.Duration) {
ticker := time.NewTicker(cleanupInterval)
defer ticker.Stop()
for range ticker.C {
c.Cleanup()
}
}
// Перебирает все элементы в кэше, удаляет устаревшие.
func (c *Cache) Cleanup() {
c.Lock()
defer c.Unlock()
for key, item := range c.storage {
if item.destroyTimestamp <= time.Now().Unix() {
delete(c.storage, key)
}
}
}
// Удаление всех элементов из кэша.
func (c *Cache) Flush() {
c.Lock()
defer c.Unlock()
for key := range c.storage {
delete(c.storage, key)
}
}
// Получение элемента из кэша по ключу.
func (c *Cache) Get(key string) (interface{}, bool) {
c.RLock()
defer c.RUnlock()
item, found := c.storage[key]
// Элемент не найден в кэше
if !found {
return nil, false
}
return item.data, true
}
// Удаление элемента по ключу.
func (c *Cache) Delete(key string) error {
c.Lock()
defer c.Unlock()
if _, found := c.storage[key]; !found {
return errors.New("key not found")
}
delete(c.storage, key)
return nil
}
// Добавление элемента в кэш.
// key - ключ.
// data - данные.
// ttl - время жизни элемента (time to life) в наносекундах.
func (c *Cache) Add(key string, data interface{}, ttl time.Duration) {
c.Lock()
defer c.Unlock()
c.storage[key] = Item{
destroyTimestamp: time.Now().Unix() + int64(ttl.Seconds()),
data: data,
}
}
// Вернет количество элементов в кэше.
func (c *Cache) Count() int {
c.RLock()
defer c.RUnlock()
return len(c.storage)
}
// Печать всех элементов кэша (ключ и время уничтожения).
func (c *Cache) Print() {
c.RLock()
defer c.RUnlock()
for key, item := range c.storage {
fmt.Printf("Key: %s, DestroyTimestamp: %d\n", key, item.destroyTimestamp)
}
}