-
Notifications
You must be signed in to change notification settings - Fork 46
/
cache.go
165 lines (139 loc) · 5.55 KB
/
cache.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright (c) 2024 Alexey Mayshev. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package otter
import (
"time"
"github.com/maypok86/otter/internal/core"
)
// DeletionCause the cause why a cached entry was deleted.
type DeletionCause = core.DeletionCause
const (
// Explicit the entry was manually deleted by the user.
Explicit = core.Explicit
// Replaced the entry itself was not actually deleted, but its value was replaced by the user.
Replaced = core.Replaced
// Size the entry was evicted due to size constraints.
Size = core.Size
// Expired the entry's expiration timestamp has passed.
Expired = core.Expired
)
type baseCache[K comparable, V any] struct {
cache *core.Cache[K, V]
}
func newBaseCache[K comparable, V any](c core.Config[K, V]) baseCache[K, V] {
return baseCache[K, V]{
cache: core.NewCache(c),
}
}
// Has checks if there is an entry with the given key in the cache.
func (bs baseCache[K, V]) Has(key K) bool {
return bs.cache.Has(key)
}
// Get returns the value associated with the key in this cache.
func (bs baseCache[K, V]) Get(key K) (V, bool) {
return bs.cache.Get(key)
}
// Delete removes the association for this key from the cache.
func (bs baseCache[K, V]) Delete(key K) {
bs.cache.Delete(key)
}
// DeleteByFunc removes the association for this key from the cache when the given function returns true.
func (bs baseCache[K, V]) DeleteByFunc(f func(key K, value V) bool) {
bs.cache.DeleteByFunc(f)
}
// Range iterates over all entries in the cache.
//
// Iteration stops early when the given function returns false.
func (bs baseCache[K, V]) Range(f func(key K, value V) bool) {
bs.cache.Range(f)
}
// Clear clears the hash table, all policies, buffers, etc.
//
// NOTE: this operation must be performed when no requests are made to the cache otherwise the behavior is undefined.
func (bs baseCache[K, V]) Clear() {
bs.cache.Clear()
}
// Close clears the hash table, all policies, buffers, etc and stop all goroutines.
//
// NOTE: this operation must be performed when no requests are made to the cache otherwise the behavior is undefined.
func (bs baseCache[K, V]) Close() {
bs.cache.Close()
}
// Size returns the current number of entries in the cache.
func (bs baseCache[K, V]) Size() int {
return bs.cache.Size()
}
// Capacity returns the cache capacity.
func (bs baseCache[K, V]) Capacity() int {
return bs.cache.Capacity()
}
// Stats returns a current snapshot of this cache's cumulative statistics.
func (bs baseCache[K, V]) Stats() Stats {
return newStats(bs.cache.Stats())
}
// Extension returns access to inspect and perform low-level operations on this cache based on its runtime
// characteristics. These operations are optional and dependent on how the cache was constructed
// and what abilities the implementation exposes.
func (bs baseCache[K, V]) Extension() Extension[K, V] {
return newExtension(bs.cache)
}
// Cache is a structure performs a best-effort bounding of a hash table using eviction algorithm
// to determine which entries to evict when the capacity is exceeded.
type Cache[K comparable, V any] struct {
baseCache[K, V]
}
func newCache[K comparable, V any](c core.Config[K, V]) Cache[K, V] {
return Cache[K, V]{
baseCache: newBaseCache(c),
}
}
// Set associates the value with the key in this cache.
//
// If it returns false, then the key-value pair had too much cost and the Set was dropped.
func (c Cache[K, V]) Set(key K, value V) bool {
return c.cache.Set(key, value)
}
// SetIfAbsent if the specified key is not already associated with a value associates it with the given value.
//
// If the specified key is not already associated with a value, then it returns false.
//
// Also, it returns false if the key-value pair had too much cost and the SetIfAbsent was dropped.
func (c Cache[K, V]) SetIfAbsent(key K, value V) bool {
return c.cache.SetIfAbsent(key, value)
}
// CacheWithVariableTTL is a structure performs a best-effort bounding of a hash table using eviction algorithm
// to determine which entries to evict when the capacity is exceeded.
type CacheWithVariableTTL[K comparable, V any] struct {
baseCache[K, V]
}
func newCacheWithVariableTTL[K comparable, V any](c core.Config[K, V]) CacheWithVariableTTL[K, V] {
return CacheWithVariableTTL[K, V]{
baseCache: newBaseCache(c),
}
}
// Set associates the value with the key in this cache and sets the custom ttl for this key-value pair.
//
// If it returns false, then the key-value pair had too much cost and the Set was dropped.
func (c CacheWithVariableTTL[K, V]) Set(key K, value V, ttl time.Duration) bool {
return c.cache.SetWithTTL(key, value, ttl)
}
// SetIfAbsent if the specified key is not already associated with a value associates it with the given value
// and sets the custom ttl for this key-value pair.
//
// If the specified key is not already associated with a value, then it returns false.
//
// Also, it returns false if the key-value pair had too much cost and the SetIfAbsent was dropped.
func (c CacheWithVariableTTL[K, V]) SetIfAbsent(key K, value V, ttl time.Duration) bool {
return c.cache.SetIfAbsentWithTTL(key, value, ttl)
}