// ___ ____ ___ ___ // \ \ / / | _ | __| \ \ / / || | __ || || _ | // \ \/ / |___ | |__ \ \/ / || |___ || ||___| // \ / | _ | _ | \ / || __ | || ||\\ // \/ |___ |___ | \/ || ____| || || \\ // // Copyright (c) 2021 Piotr Biernat. https://pbiernat.dev. MIT License // Repo: https://git.pbiernat.dev/golang/vegvisir package cache import ( "errors" "sync" "time" ) // TTLItem struct type TTLItem struct { ts int // timestamp ttl int // ttl in seconds } // NewMemoryDatastore function func NewMemoryDatastore() *MemoryDatastore { return &MemoryDatastore{ cache: make(map[string]interface{}), ts: make(map[string]TTLItem), } } // MemoryDatastore struct type MemoryDatastore struct { cache map[string]interface{} ts map[string]TTLItem lock sync.RWMutex } // SetKey function func (ds *MemoryDatastore) SetKey(key string, data interface{}, ttl int) error { ds.lock.Lock() ds.cache[key] = data ds.ts[key] = TTLItem{ ts: time.Now().Second(), ttl: ttl, } ds.lock.Unlock() return nil } // GetKey function func (ds *MemoryDatastore) GetKey(key string) (interface{}, error) { ds.lock.RLock() defer ds.lock.RUnlock() ds.gc(key) // remove key is time of creation is outdated if data, ok := ds.cache[key]; ok { return data, nil } return nil, errors.New("Key not found" + key) } // IsConnected function func (ds *MemoryDatastore) IsConnected() bool { return true } func (ds *MemoryDatastore) gc(key string) { if item, ok := ds.ts[key]; ok && item.ts < time.Now().Second()-item.ttl { delete(ds.cache, key) } }