volatile/volatile.go (view raw)
1package volatile
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/sirupsen/logrus"
8)
9
10var logger = logrus.New()
11
12type Element[V any] struct {
13 value *V
14 Timestamp time.Time
15}
16
17type Volatile[K comparable, V any] struct {
18 data map[K]Element[V]
19 timeToLive time.Duration
20}
21
22func reverseIntArray(arr []int) {
23 length := len(arr)
24 for i := 0; i < length/2; i++ {
25 arr[i], arr[length-i-1] = arr[length-i-1], arr[i]
26 }
27}
28
29func NewVolatile[K comparable, V any](timeToLive time.Duration) *Volatile[K, V] {
30 return &Volatile[K, V]{
31 data: make(map[K]Element[V]),
32 timeToLive: timeToLive,
33 }
34}
35
36func (v *Volatile[K, V]) clean() {
37 now := time.Now()
38 keysToDelete := []K{}
39
40 for key, value := range v.data {
41 if now.Sub(value.Timestamp) > v.timeToLive {
42 keysToDelete = append(keysToDelete, key)
43 }
44 }
45 for _, key := range keysToDelete {
46 delete(v.data, key)
47 }
48}
49
50func (v *Volatile[K, V]) Has(key K) bool {
51 v.clean()
52 _, ok := v.data[key]
53 return ok
54}
55
56func (v *Volatile[K, V]) Get(key K) (*V, error) {
57 v.clean()
58 element, ok := v.data[key]
59 if !ok {
60 return nil, fmt.Errorf("not found")
61 }
62 return element.value, nil
63}
64
65func (v *Volatile[K, V]) Remove(key K) (*V, error) {
66 v.clean()
67 value, ok := v.data[key]
68
69 if ok {
70 delete(v.data, key)
71 return value.value, nil
72 }
73
74 return nil, fmt.Errorf("not found")
75}
76
77func (v *Volatile[K, V]) Set(key K, value *V) error {
78 v.data[key] = Element[V]{value: value, Timestamp: time.Now()}
79 v.clean()
80 return nil
81}