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[K comparable, V any] struct {
13 key K
14 value V
15 Timestamp time.Time
16}
17
18type Volatile[K comparable, V any] struct {
19 data []Element[K, V]
20 timeToLive time.Duration
21}
22
23func reverseIntArray(arr []int) {
24 length := len(arr)
25 for i := 0; i < length/2; i++ {
26 arr[i], arr[length-i-1] = arr[length-i-1], arr[i]
27 }
28}
29
30func NewVolatile[K comparable, V any](timeToLive time.Duration) *Volatile[K, V] {
31 return &Volatile[K, V]{
32 data: nil,
33 timeToLive: timeToLive,
34 }
35}
36
37func (v *Volatile[K, V]) removeIndex(index int) error {
38 if index < 0 || index >= len(v.data) {
39 return fmt.Errorf("Index out of bounds")
40 }
41 v.data = append(v.data[:index], v.data[index+1:]...)
42 return nil
43}
44
45func (v *Volatile[K, V]) clean() error {
46 now := time.Now()
47
48 for i := len(v.data) - 1; i >= 0; i-- {
49 if now.Sub(v.data[i].Timestamp) > v.timeToLive {
50 err := v.removeIndex(i)
51 if err != nil {
52 return err
53 }
54 }
55 }
56 return nil
57}
58
59func (v *Volatile[K, V]) indexOf(key K) int {
60 for i := range v.data {
61 e := v.data[i]
62 if e.key == key {
63 return i
64 }
65 }
66 return -1
67}
68
69func (v *Volatile[K, V]) Has(key K) bool {
70 err := v.clean()
71 if err != nil {
72 logger.Println(err)
73 return false
74 }
75 return v.indexOf(key) != -1
76}
77
78func (v *Volatile[K, V]) Get(key K) (*V, error) {
79 err := v.clean()
80 if err != nil {
81 logger.Println(err)
82 return nil, err
83 }
84
85 i := v.indexOf(key)
86 if i == -1 {
87 return nil, fmt.Errorf("Not found")
88 }
89 return &v.data[i].value, nil
90}
91
92func (v *Volatile[K, V]) Remove(key K) (*V, error) {
93 err := v.clean()
94 if err != nil {
95 logger.Error(err)
96 return nil, err
97 }
98 i := v.indexOf(key)
99 if i == -1 {
100 logger.Error(err)
101 return nil, err
102 }
103
104 value := &v.data[i].value
105 err = v.removeIndex(i)
106 if err != nil {
107 logger.Error(err)
108 return nil, err
109 }
110 return value, nil
111}
112
113func (v *Volatile[K, V]) Set(key K, value V) error {
114 err := v.clean()
115 if err != nil {
116 logger.Error(err)
117 return err
118 }
119 _, err = v.Remove(key)
120 if err != nil {
121 logger.Error(err)
122 return err
123 }
124 e := Element[K, V]{key: key, value: value, Timestamp: time.Now()}
125 v.data = append(v.data, e)
126 return nil
127}