mirror of
https://github.com/restic/restic.git
synced 2025-10-27 12:28:34 +00:00
Add local cache
This commit is contained in:
@@ -112,8 +112,6 @@ func newLoadBlobsProgress(s restic.Server) (*restic.Progress, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// fmt.Printf("sec: %v, trees: %v / %v\n", sec, s.Trees, trees)
|
||||
|
||||
fmt.Printf("\x1b[2K\r[%s] %3.2f%% %d trees/s %d / %d trees, %d blobs ETA %s",
|
||||
format_duration(d),
|
||||
float64(s.Trees)/float64(trees)*100,
|
||||
|
||||
114
cmd/restic/cmd_cache.go
Normal file
114
cmd/restic/cmd_cache.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/restic/restic"
|
||||
"github.com/restic/restic/backend"
|
||||
)
|
||||
|
||||
type CmdCache struct{}
|
||||
|
||||
func init() {
|
||||
_, err := parser.AddCommand("cache",
|
||||
"manage cache",
|
||||
"The cache command creates and manages the local cache",
|
||||
&CmdCache{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd CmdCache) Usage() string {
|
||||
return "[update|clear]"
|
||||
}
|
||||
|
||||
func (cmd CmdCache) Execute(args []string) error {
|
||||
// if len(args) == 0 || len(args) > 2 {
|
||||
// return fmt.Errorf("wrong number of parameters, Usage: %s", cmd.Usage())
|
||||
// }
|
||||
|
||||
s, err := OpenRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("update cache, load trees\n")
|
||||
|
||||
list, err := s.List(backend.Tree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cache, err := restic.NewCache()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
treeCh := make(chan backend.ID)
|
||||
worker := func(wg *sync.WaitGroup, ch chan backend.ID) {
|
||||
for treeID := range ch {
|
||||
cached, err := cache.Has(backend.Tree, treeID)
|
||||
if err != nil {
|
||||
fmt.Printf("tree %v cache error: %v\n", treeID.Str(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
if cached {
|
||||
fmt.Printf("tree %v already cached\n", treeID.Str())
|
||||
continue
|
||||
}
|
||||
|
||||
rd, err := s.GetReader(backend.Tree, treeID)
|
||||
if err != nil {
|
||||
fmt.Printf(" load error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
decRd, err := s.Key().DecryptFrom(rd)
|
||||
if err != nil {
|
||||
fmt.Printf(" store error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
err = cache.Store(backend.Tree, treeID, decRd)
|
||||
if err != nil {
|
||||
fmt.Printf(" store error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
err = decRd.Close()
|
||||
if err != nil {
|
||||
fmt.Printf(" close error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
err = rd.Close()
|
||||
if err != nil {
|
||||
fmt.Printf(" close error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("tree %v stored\n", treeID.Str())
|
||||
}
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
// start workers
|
||||
for i := 0; i < 500; i++ {
|
||||
wg.Add(1)
|
||||
go worker(&wg, treeCh)
|
||||
}
|
||||
|
||||
for _, treeID := range list {
|
||||
treeCh <- treeID
|
||||
}
|
||||
|
||||
close(treeCh)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -165,6 +165,7 @@ func init() {
|
||||
|
||||
func main() {
|
||||
// defer profile.Start(profile.MemProfileRate(100000), profile.ProfilePath(".")).Stop()
|
||||
// defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop()
|
||||
opts.Repo = os.Getenv("RESTIC_REPOSITORY")
|
||||
|
||||
debug.Log("restic", "main %#v", os.Args)
|
||||
|
||||
Reference in New Issue
Block a user