File: memory_cache.go

package info (click to toggle)
rdap 0.9.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 608 kB
  • sloc: makefile: 4
file content (81 lines) | stat: -rw-r--r-- 1,744 bytes parent folder | download
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

}