Skip to content

Commit 07eb7a1

Browse files
committed
Add LRU cache
1 parent 65a87a5 commit 07eb7a1

File tree

6 files changed

+81
-35
lines changed

6 files changed

+81
-35
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module github.com/krakendio/httpcache
22

33
go 1.19
4+
5+
require github.com/hashicorp/golang-lru v1.0.2

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
2+
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=

httpcache.go

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"net/http"
1414
"net/http/httputil"
1515
"strings"
16-
"sync"
1716
"time"
1817
)
1918

@@ -57,40 +56,6 @@ func CachedResponse(c Cache, req *http.Request) (resp *http.Response, err error)
5756
return http.ReadResponse(bufio.NewReader(b), req)
5857
}
5958

60-
// MemoryCache is an implemtation of Cache that stores responses in an in-memory map.
61-
type MemoryCache struct {
62-
mu sync.RWMutex
63-
items map[string][]byte
64-
}
65-
66-
// Get returns the []byte representation of the response and true if present, false if not
67-
func (c *MemoryCache) Get(key string) (resp []byte, ok bool) {
68-
c.mu.RLock()
69-
resp, ok = c.items[key]
70-
c.mu.RUnlock()
71-
return resp, ok
72-
}
73-
74-
// Set saves response resp to the cache with key
75-
func (c *MemoryCache) Set(key string, resp []byte) {
76-
c.mu.Lock()
77-
c.items[key] = resp
78-
c.mu.Unlock()
79-
}
80-
81-
// Delete removes key from the cache
82-
func (c *MemoryCache) Delete(key string) {
83-
c.mu.Lock()
84-
delete(c.items, key)
85-
c.mu.Unlock()
86-
}
87-
88-
// NewMemoryCache returns a new Cache that will store items in an in-memory map
89-
func NewMemoryCache() *MemoryCache {
90-
c := &MemoryCache{items: map[string][]byte{}}
91-
return c
92-
}
93-
9459
// Transport is an implementation of http.RoundTripper that will return values from a cache
9560
// where possible (avoiding a network request) and will additionally add validators (etag/if-modified-since)
9661
// to repeated requests allowing servers to return 304 / Not Modified
@@ -552,3 +517,9 @@ func NewMemoryCacheTransport() *Transport {
552517
t := NewTransport(c)
553518
return t
554519
}
520+
521+
func NewLruCacheTransport(size int) *Transport {
522+
c := NewLruCache(size)
523+
t := NewTransport(c)
524+
return t
525+
}

lru.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package httpcache
2+
3+
import (
4+
lru "github.com/hashicorp/golang-lru"
5+
)
6+
7+
type LruCache struct {
8+
cache *lru.Cache
9+
}
10+
11+
func NewLruCache(size int) *LruCache {
12+
c, _ := lru.New(size)
13+
return &LruCache{cache: c}
14+
}
15+
16+
func (c *LruCache) Get(key string) ([]byte, bool) {
17+
v, ok := c.cache.Get(key)
18+
if !ok {
19+
return nil, false
20+
}
21+
return v.([]byte), true
22+
}
23+
24+
func (c *LruCache) Set(key string, resp []byte) {
25+
c.cache.Add(key, resp)
26+
}
27+
28+
func (c *LruCache) Delete(key string) {
29+
c.cache.Remove(key)
30+
}

memory.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package httpcache
2+
3+
import "sync"
4+
5+
// MemoryCache is an implemtation of Cache that stores responses in an in-memory map.
6+
type MemoryCache struct {
7+
mu sync.RWMutex
8+
items map[string][]byte
9+
}
10+
11+
// Get returns the []byte representation of the response and true if present, false if not
12+
func (c *MemoryCache) Get(key string) (resp []byte, ok bool) {
13+
c.mu.RLock()
14+
resp, ok = c.items[key]
15+
c.mu.RUnlock()
16+
return resp, ok
17+
}
18+
19+
// Set saves response resp to the cache with key
20+
func (c *MemoryCache) Set(key string, resp []byte) {
21+
c.mu.Lock()
22+
c.items[key] = resp
23+
c.mu.Unlock()
24+
}
25+
26+
// Delete removes key from the cache
27+
func (c *MemoryCache) Delete(key string) {
28+
c.mu.Lock()
29+
delete(c.items, key)
30+
c.mu.Unlock()
31+
}
32+
33+
// NewMemoryCache returns a new Cache that will store items in an in-memory map
34+
func NewMemoryCache() *MemoryCache {
35+
c := &MemoryCache{items: map[string][]byte{}}
36+
return c
37+
}

test/test_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ import (
1010
func TestMemoryCache(t *testing.T) {
1111
test.Cache(t, httpcache.NewMemoryCache())
1212
}
13+
14+
func TestLruCache(t *testing.T) {
15+
test.Cache(t, httpcache.NewLruCache(10))
16+
}

0 commit comments

Comments
 (0)