98 lines · 2.6 KB · Go
RawDownload
// +build !plan9,!js package cache import (	"strconv"	"strings"	"time" 	cache "github.com/patrickmn/go-cache"	"github.com/pkg/errors"	"github.com/rclone/rclone/fs") // Memory is a wrapper of transient storage for a go-cache storetype Memory struct {	db *cache.Cache} // NewMemory builds this cache storage// defaultExpiration will set the expiry time of chunks in this storagefunc NewMemory(defaultExpiration time.Duration) *Memory {	mem := &Memory{}	err := mem.Connect(defaultExpiration)	if err != nil {		fs.Errorf("cache", "can't open ram connection: %v", err)	} 	return mem} // Connect will create a connection for the storagefunc (m *Memory) Connect(defaultExpiration time.Duration) error {	m.db = cache.New(defaultExpiration, -1)	return nil} // HasChunk confirms the existence of a single chunk of an objectfunc (m *Memory) HasChunk(cachedObject *Object, offset int64) bool {	key := cachedObject.abs() + "-" + strconv.FormatInt(offset, 10)	_, found := m.db.Get(key)	return found} // GetChunk will retrieve a single chunk which belongs to a cached object or an error if it doesn't find itfunc (m *Memory) GetChunk(cachedObject *Object, offset int64) ([]byte, error) {	key := cachedObject.abs() + "-" + strconv.FormatInt(offset, 10)	var data []byte 	if x, found := m.db.Get(key); found {		data = x.([]byte)		return data, nil	} 	return nil, errors.Errorf("couldn't get cached object data at offset %v", offset)} // AddChunk adds a new chunk of a cached objectfunc (m *Memory) AddChunk(fp string, data []byte, offset int64) error {	return m.AddChunkAhead(fp, data, offset, time.Second)} // AddChunkAhead adds a new chunk of a cached objectfunc (m *Memory) AddChunkAhead(fp string, data []byte, offset int64, t time.Duration) error {	key := fp + "-" + strconv.FormatInt(offset, 10)	m.db.Set(key, data, cache.DefaultExpiration) 	return nil} // CleanChunksByAge will cleanup on a cron basisfunc (m *Memory) CleanChunksByAge(chunkAge time.Duration) {	m.db.DeleteExpired()} // CleanChunksByNeed will cleanup chunks after the FS passes a specific chunkfunc (m *Memory) CleanChunksByNeed(offset int64) {	var items map[string]cache.Item 	items = m.db.Items()	for key := range items {		sepIdx := strings.LastIndex(key, "-")		keyOffset, err := strconv.ParseInt(key[sepIdx+1:], 10, 64)		if err != nil {			fs.Errorf("cache", "couldn't parse offset entry %v", key)			continue		} 		if keyOffset < offset {			m.db.Delete(key)		}	}} // CleanChunksBySize will cleanup chunks after the total size passes a certain pointfunc (m *Memory) CleanChunksBySize(maxSize int64) {	// NOOP}