This repository has been archived by the owner on May 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
memory.go
94 lines (81 loc) · 2.15 KB
/
memory.go
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
82
83
84
85
86
87
88
89
90
91
92
93
94
package cache
import (
"context"
"sync"
"time"
)
type memoryData struct {
data interface{}
expiration time.Time
}
type memoryClient struct {
data sync.Map
}
// NewMemoryClient returns a Client that only stores in memory.
// Useful for stubbing tests.
func NewMemoryClient() Client {
return &memoryClient{}
}
func (c *memoryClient) Get(ctx context.Context, key string, data interface{}) error {
if item, ok := c.data.Load(key); ok {
mItem := item.(memoryData)
if mItem.expiration.IsZero() || mItem.expiration.After(time.Now()) {
return setPointerValue(data, mItem.data)
}
}
return ErrCacheMiss
}
func (c *memoryClient) Set(ctx context.Context, key string, data interface{}, expiration time.Time) error {
c.data.Store(key, memoryData{
data: data,
expiration: expiration,
})
return nil
}
func (c *memoryClient) Add(ctx context.Context, key string, data interface{}, expiration time.Time) error {
_, loaded := c.data.LoadOrStore(key, memoryData{
data: data,
expiration: expiration,
})
if loaded {
// TODO: handle when the conflicting data is expired
return ErrNotStored
}
return nil
}
func (c *memoryClient) Delete(ctx context.Context, key string) error {
c.data.Delete(key)
return nil
}
func (c *memoryClient) getInt(key string) (uint64, time.Time, error) {
var curr uint64
var expiration time.Time
if item, ok := c.data.Load(key); ok {
mItem := item.(memoryData)
if curr, ok = mItem.data.(uint64); !ok {
return 0, expiration, ErrNotANumber
}
expiration = mItem.expiration
}
return curr, expiration, nil
}
func (c *memoryClient) Increment(ctx context.Context, key string, delta uint64) (uint64, error) {
// TODO: definitely not thread-safe
curr, expiration, err := c.getInt(key)
if err != nil {
return 0, err
}
curr += delta
err = c.Set(context.Background(), key, curr, expiration)
return curr, err
}
func (c *memoryClient) Decrement(ctx context.Context, key string, delta uint64) (uint64, error) {
// TODO: definitely not thread-safe
curr, expiration, err := c.getInt(key)
if err != nil {
return 0, err
}
curr -= delta
err = c.Set(context.Background(), key, curr, expiration)
return curr, err
}