1// Package diskcache provides an implementation of httpcache.Cache that uses the diskv package 2// to supplement an in-memory map with persistent storage 3// 4package diskcache 5 6import ( 7 "bytes" 8 "crypto/md5" 9 "encoding/hex" 10 "github.com/peterbourgon/diskv" 11 "io" 12) 13 14// Cache is an implementation of httpcache.Cache that supplements the in-memory map with persistent storage 15type Cache struct { 16 d *diskv.Diskv 17} 18 19// Get returns the response corresponding to key if present 20func (c *Cache) Get(key string) (resp []byte, ok bool) { 21 key = keyToFilename(key) 22 resp, err := c.d.Read(key) 23 if err != nil { 24 return []byte{}, false 25 } 26 return resp, true 27} 28 29// Set saves a response to the cache as key 30func (c *Cache) Set(key string, resp []byte) { 31 key = keyToFilename(key) 32 c.d.WriteStream(key, bytes.NewReader(resp), true) 33} 34 35// Delete removes the response with key from the cache 36func (c *Cache) Delete(key string) { 37 key = keyToFilename(key) 38 c.d.Erase(key) 39} 40 41func keyToFilename(key string) string { 42 h := md5.New() 43 io.WriteString(h, key) 44 return hex.EncodeToString(h.Sum(nil)) 45} 46 47// New returns a new Cache that will store files in basePath 48func New(basePath string) *Cache { 49 return &Cache{ 50 d: diskv.New(diskv.Options{ 51 BasePath: basePath, 52 CacheSizeMax: 100 * 1024 * 1024, // 100MB 53 }), 54 } 55} 56 57// NewWithDiskv returns a new Cache using the provided Diskv as underlying 58// storage. 59func NewWithDiskv(d *diskv.Diskv) *Cache { 60 return &Cache{d} 61} 62