1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
// OpenRDAP
// Copyright 2017 Tom Harwood
// MIT License, see the LICENSE file.
package cache
import (
"fmt"
"time"
)
// A MemoryCache caches Service Registry files in memory.
type MemoryCache struct {
Timeout time.Duration
cache map[string][]byte
mtime map[string]time.Time
}
// NewMemoryCache creates a new MemoryCache.
func NewMemoryCache() *MemoryCache {
return &MemoryCache{
cache: make(map[string][]byte),
mtime: make(map[string]time.Time),
Timeout: time.Hour * 24,
}
}
// SetTimeout sets the duration each Service Registry file can be stored before
// its State() is Expired.
func (m *MemoryCache) SetTimeout(timeout time.Duration) {
m.Timeout = timeout
}
// Save saves the file |filename| with |data| to the cache.
func (m *MemoryCache) Save(filename string, data []byte) error {
m.cache[filename] = make([]byte, len(data))
copy(m.cache[filename], data)
m.mtime[filename] = time.Now()
return nil
}
// Load returns the file |filename| from the cache.
//
// Since Service Registry files do not change much, the file is returned even
// if its State() is Expired.
//
// An error is returned if the file is not in the cache.
func (m *MemoryCache) Load(filename string) ([]byte, error) {
data, ok := m.cache[filename]
if !ok {
return nil, fmt.Errorf("File %s not in cache", filename)
}
result := make([]byte, len(data))
copy(result, data)
return result, nil
}
// State returns the cache state of the file |filename|.
//
// The returned state is one of: Absent, Good, Expired.
func (m *MemoryCache) State(filename string) FileState {
mtime, ok := m.mtime[filename]
if !ok {
return Absent
}
expiry := mtime.Add(m.Timeout)
if expiry.Before(time.Now()) {
return Expired
}
return Good
}
|