ceeac84cfe
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.
75 lines
1.2 KiB
Go
75 lines
1.2 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|