Codebase list golang-github-renekroon-ttlcache / 136a06f
New upstream version 2.2.0+ds Sascha Steinbiss 3 years ago
5 changed file(s) with 106 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
00 package ttlcache
11
22 import (
3 "errors"
43 "sync"
54 "time"
65 )
3130 isShutDown bool
3231 loaderFunction LoaderFunction
3332 sizeLimit int
34 }
35
36 var (
33 metrics Metrics
34 }
35
36 const (
3737 // ErrClosed is raised when operating on a cache where Close() has already been called.
38 ErrClosed = errors.New("cache already closed")
38 ErrClosed = constError("cache already closed")
3939 // ErrNotFound indicates that the requested key is not present in the cache
40 ErrNotFound = errors.New("key not found")
40 ErrNotFound = constError("key not found")
4141 )
42
43 type constError string
44
45 func (err constError) Error() string {
46 return string(err)
47 }
4248
4349 func (cache *Cache) getItem(key string) (*item, bool, bool) {
4450 item, exists := cache.items[key]
4551 if !exists || item.expired() {
4652 return nil, false, false
53 } else {
4754 }
4855
4956 if item.ttl >= 0 && (item.ttl > 0 || cache.ttl > 0) {
119126 }
120127
121128 func (cache *Cache) removeItem(item *item) {
129 cache.metrics.Evicted++
122130 if cache.expireCallback != nil {
123131 go cache.expireCallback(item.key, item.data)
124132 }
206214 item = newItem(key, data, ttl)
207215 cache.items[key] = item
208216 }
217 cache.metrics.Inserted++
209218
210219 if item.ttl >= 0 && (item.ttl > 0 || cache.ttl > 0) {
211220 if cache.ttl > 0 && item.ttl == 0 {
236245 cache.mutex.Unlock()
237246 return nil, ErrClosed
238247 }
248
249 cache.metrics.Hits++
239250 item, exists, triggerExpirationNotification := cache.getItem(key)
240251
241252 var dataToReturn interface{}
242253 if exists {
254 cache.metrics.Retrievals++
243255 dataToReturn = item.data
244256 }
245257
246258 var err error
247259 if !exists {
260 cache.metrics.Misses++
248261 err = ErrNotFound
249262 }
250263 if cache.loaderFunction == nil || exists {
380393 if cache.isShutDown {
381394 return ErrClosed
382395 }
396 cache.metrics.Evicted += int64(len(cache.items))
383397 cache.items = make(map[string]*item)
384398 cache.priorityQueue = newPriorityQueue()
385399 return nil
407421 isShutDown: false,
408422 loaderFunction: nil,
409423 sizeLimit: 0,
424 metrics: Metrics{},
410425 }
411426 go cache.startExpirationProcessing()
412427 return cache
428 }
429
430 // GetMetrics exposes the metrics of the cache. This is a snapshot copy of the metrics.
431 func (cache *Cache) GetMetrics() Metrics {
432 cache.mutex.Lock()
433 defer cache.mutex.Unlock()
434 return cache.metrics
413435 }
414436
415437 func min(duration time.Duration, second time.Duration) time.Duration {
00 package ttlcache_test
11
22 import (
3 "go.uber.org/goleak"
43 "math/rand"
54 "strconv"
65 "sync/atomic"
76 "testing"
87 "time"
98
9 "go.uber.org/goleak"
10
1011 "fmt"
1112 "sync"
1213
1617
1718 func TestMain(m *testing.M) {
1819 goleak.VerifyTestMain(m)
20 }
21
22 // Issue #37: Cache metrics
23 func TestCache_TestMetrics(t *testing.T) {
24 t.Parallel()
25 cache := NewCache()
26 defer cache.Close()
27
28 cache.SetTTL(time.Second)
29 cache.Set("myKey", "myData")
30 cache.SetWithTTL("myKey2", "myData", time.Second)
31
32 cache.Get("myKey")
33 cache.Get("myMiss")
34
35 metrics := cache.GetMetrics()
36 assert.Equal(t, int64(2), metrics.Inserted)
37 assert.Equal(t, int64(1), metrics.Misses)
38 assert.Equal(t, int64(2), metrics.Hits)
39 assert.Equal(t, int64(1), metrics.Retrievals)
40 cache.Purge()
41 metrics = cache.GetMetrics()
42 assert.Equal(t, int64(2), metrics.Evicted)
43
44 cache.SetWithTTL("3", "3", time.Nanosecond)
45 cache.SetWithTTL("4", "4", time.Nanosecond)
46 cache.Count()
47 time.Sleep(time.Millisecond * 10)
48
49 metrics = cache.GetMetrics()
50 assert.Equal(t, int64(4), metrics.Evicted)
51
1952 }
2053
2154 // Issue #31: Test that a single fetch is executed with the loader function
00 module github.com/ReneKroon/ttlcache/v2
11
2 go 1.14
2 go 1.15
33
44 require (
55 github.com/davecgh/go-spew v1.1.1 // indirect
6 github.com/stretchr/testify v1.6.1
6 github.com/stretchr/testify v1.7.0
77 go.uber.org/goleak v1.1.10
8 golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
9 golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d // indirect
8 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
9 golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064 // indirect
1010 )
0 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
01 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
12 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
23 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
34 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
45 github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
56 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
7 github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
8 github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
69 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
710 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
811 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
12 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
13 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
914 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1015 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1116 github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
1318 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
1419 github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
1520 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
21 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
22 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
1623 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
24 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
1725 go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
1826 go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
1927 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
2331 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
2432 golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
2533 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
34 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
35 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
2636 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
2737 golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
2838 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
39 golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
40 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
2941 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
3042 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
3143 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
3244 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
45 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
3346 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
3447 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
48 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
3549 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
3650 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3751 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
52 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3853 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
54 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
55 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
3956 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
4057 golang.org/x/tools v0.0.0-20191108193012-7d206e10da11 h1:Yq9t9jnGoR+dBuitxdo9l6Q7xh/zOyNnYUtDKaQ3x0E=
4158 golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
4360 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
4461 golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d h1:szSOL78iTCl0LF1AMjhSWJj8tIM0KixlUUnBtYXsmd8=
4562 golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
63 golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064 h1:BmCFkEH4nJrYcAc2L08yX5RhYGD4j58PTMkEUDkpz2I=
64 golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
4665 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
4766 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
4867 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
4968 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
69 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
70 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5071 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5172 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
5273 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
74 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
75 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
5376 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5477 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
5578 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
79 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
80 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
0 package ttlcache
1
2 // Metrics contains common cache metrics so you can calculate hit and miss rates
3 type Metrics struct {
4 // succesful inserts
5 Inserted int64
6 // retrieval attempts
7 Retrievals int64
8 // all get calls that were in the cache (excludes loader invocations)
9 Hits int64
10 // entries not in cache (includes loader invocations)
11 Misses int64
12 // items removed from the cache in any way
13 Evicted int64
14 }