101 lines
2.0 KiB
Go
101 lines
2.0 KiB
Go
package caches
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/alice-lg/alice-lg/pkg/api"
|
|
)
|
|
|
|
/*
|
|
RoutesCache stores routes responses from the backend.
|
|
|
|
Keep a kv map with neighborId <-> api.RoutesResponse
|
|
TTL is derived from the api.RoutesResponse.
|
|
|
|
To avoid memory issues, we only keep N responses (MRU) (per RS).
|
|
*/
|
|
type RoutesCache struct {
|
|
responses map[string]*api.RoutesResponse
|
|
accessedAt LRUMap
|
|
|
|
disabled bool
|
|
size int
|
|
|
|
sync.Mutex
|
|
}
|
|
|
|
// NewRoutesCache initializes a new cache for route responses.
|
|
func NewRoutesCache(disabled bool, size int) *RoutesCache {
|
|
cache := &RoutesCache{
|
|
responses: make(map[string]*api.RoutesResponse),
|
|
accessedAt: make(map[string]time.Time),
|
|
disabled: disabled,
|
|
size: size,
|
|
}
|
|
|
|
return cache
|
|
}
|
|
|
|
// Get retrievs all routes for a given neighbor
|
|
func (cache *RoutesCache) Get(neighborID string) *api.RoutesResponse {
|
|
if cache.disabled {
|
|
return nil
|
|
}
|
|
|
|
cache.Lock()
|
|
defer cache.Unlock()
|
|
|
|
response, ok := cache.responses[neighborID]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
if response.CacheTTL() < 0 {
|
|
return nil
|
|
}
|
|
|
|
cache.accessedAt[neighborID] = time.Now()
|
|
|
|
return response
|
|
}
|
|
|
|
// Set the routes response for a given neighbor
|
|
func (cache *RoutesCache) Set(neighborID string, response *api.RoutesResponse) {
|
|
if cache.disabled {
|
|
return
|
|
}
|
|
|
|
cache.Lock()
|
|
defer cache.Unlock()
|
|
|
|
if len(cache.responses) > cache.size {
|
|
// delete LRU
|
|
leastRecentNeighbor := cache.accessedAt.LRU()
|
|
delete(cache.accessedAt, leastRecentNeighbor)
|
|
delete(cache.responses, leastRecentNeighbor)
|
|
}
|
|
|
|
cache.accessedAt[neighborID] = time.Now()
|
|
cache.responses[neighborID] = response
|
|
}
|
|
|
|
// Expire will flush expired keys. (TODO: naming could be better.)
|
|
func (cache *RoutesCache) Expire() int {
|
|
cache.Lock()
|
|
defer cache.Unlock()
|
|
|
|
expiredKeys := []string{}
|
|
for key, response := range cache.responses {
|
|
if response.CacheTTL() < 0 {
|
|
expiredKeys = append(expiredKeys, key)
|
|
}
|
|
}
|
|
|
|
for _, key := range expiredKeys {
|
|
delete(cache.responses, key)
|
|
}
|
|
|
|
return len(expiredKeys)
|
|
}
|