mirror of
https://github.com/restic/restic.git
synced 2025-08-25 20:47:40 +00:00
dump: add GetOrCompute to bloblru cache
This commit is contained in:
@@ -20,13 +20,15 @@ type Cache struct {
|
||||
c *simplelru.LRU[restic.ID, []byte]
|
||||
|
||||
free, size int // Current and max capacity, in bytes.
|
||||
inProgress map[restic.ID]chan struct{}
|
||||
}
|
||||
|
||||
// New constructs a blob cache that stores at most size bytes worth of blobs.
|
||||
func New(size int) *Cache {
|
||||
c := &Cache{
|
||||
free: size,
|
||||
size: size,
|
||||
free: size,
|
||||
size: size,
|
||||
inProgress: make(map[restic.ID]chan struct{}),
|
||||
}
|
||||
|
||||
// NewLRU wants us to specify some max. number of entries, else it errors.
|
||||
@@ -85,6 +87,48 @@ func (c *Cache) Get(id restic.ID) ([]byte, bool) {
|
||||
return blob, ok
|
||||
}
|
||||
|
||||
func (c *Cache) GetOrCompute(id restic.ID, compute func() ([]byte, error)) ([]byte, error) {
|
||||
// check if already cached
|
||||
blob, ok := c.Get(id)
|
||||
if ok {
|
||||
return blob, nil
|
||||
}
|
||||
|
||||
// check for parallel download or start our own
|
||||
finish := make(chan struct{})
|
||||
c.mu.Lock()
|
||||
waitForResult, isDownloading := c.inProgress[id]
|
||||
if !isDownloading {
|
||||
c.inProgress[id] = finish
|
||||
|
||||
// remove progress channel once finished here
|
||||
defer func() {
|
||||
c.mu.Lock()
|
||||
delete(c.inProgress, id)
|
||||
c.mu.Unlock()
|
||||
close(finish)
|
||||
}()
|
||||
}
|
||||
c.mu.Unlock()
|
||||
|
||||
if isDownloading {
|
||||
// wait for result of parallel download
|
||||
<-waitForResult
|
||||
blob, ok := c.Get(id)
|
||||
if ok {
|
||||
return blob, nil
|
||||
}
|
||||
}
|
||||
|
||||
// download it
|
||||
blob, err := compute()
|
||||
if err == nil {
|
||||
c.Add(id, blob)
|
||||
}
|
||||
|
||||
return blob, err
|
||||
}
|
||||
|
||||
func (c *Cache) evict(key restic.ID, blob []byte) {
|
||||
debug.Log("bloblru.Cache: evict %v, %d bytes", key, cap(blob))
|
||||
c.free += cap(blob) + overhead
|
||||
|
Reference in New Issue
Block a user