1
0
mirror of https://github.com/rclone/rclone.git synced 2025-12-06 00:03:32 +00:00

serve restic: implement object cache

This caches all the objects returned from the List call. This makes
opening them much quicker so speeds up prune and restores. It also
uses fewer transactions. It can be disabled with
`--cache-objects=false`.

This was discovered when using the B2 backend when the budget was
being blown on list object calls which can avoided with a bit of
caching.

For typical 1 million file backup for a latop or server this will only
use a small amount more memory.
This commit is contained in:
Nick Craig-Wood
2020-11-09 16:13:08 +00:00
parent 83d48f65b6
commit ceeac84cfe
3 changed files with 178 additions and 14 deletions

75
cmd/serve/restic/cache.go Normal file
View File

@@ -0,0 +1,75 @@
package restic
import (
"strings"
"sync"
"github.com/rclone/rclone/fs"
)
// cache implements a simple object cache
type cache struct {
mu sync.RWMutex // protects the cache
items map[string]fs.Object // cache of objects
}
// create a new cache
func newCache() *cache {
return &cache{
items: map[string]fs.Object{},
}
}
// find the object at remote or return nil
func (c *cache) find(remote string) fs.Object {
if !cacheObjects {
return nil
}
c.mu.RLock()
o := c.items[remote]
c.mu.RUnlock()
return o
}
// add the object to the cache
func (c *cache) add(remote string, o fs.Object) {
if !cacheObjects {
return
}
c.mu.Lock()
c.items[remote] = o
c.mu.Unlock()
}
// remove the object from the cache
func (c *cache) remove(remote string) {
if !cacheObjects {
return
}
c.mu.Lock()
delete(c.items, remote)
c.mu.Unlock()
}
// remove all the items with prefix from the cache
func (c *cache) removePrefix(prefix string) {
if !cacheObjects {
return
}
c.mu.Lock()
defer c.mu.Unlock()
if !strings.HasSuffix(prefix, "/") {
prefix += "/"
}
if prefix == "/" {
c.items = map[string]fs.Object{}
return
}
for key := range c.items {
if strings.HasPrefix(key, prefix) {
delete(c.items, key)
}
}
}