Skip to content

Commit 570ab1d

Browse files
committed
perf: pull two blocks in parallel when downloading a whole file (fixes #261)
1 parent b3a1295 commit 570ab1d

File tree

4 files changed

+199
-116
lines changed

4 files changed

+199
-116
lines changed

SushitrainCore/src/entry.go

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"context"
1010
"encoding/base64"
1111
"errors"
12-
"fmt"
12+
"io"
1313
"os"
1414
"path"
1515
"path/filepath"
@@ -379,6 +379,20 @@ func (entry *Entry) availabilityPerDevice() (map[protocol.DeviceID]int, int, err
379379
return deviceStatus, len(info.Blocks), nil
380380
}
381381

382+
type progressWriter struct {
383+
delegate DownloadDelegate
384+
out io.Writer
385+
written int
386+
total int
387+
}
388+
389+
func (pw *progressWriter) Write(buf []byte) (n int, err error) {
390+
n, err = pw.out.Write(buf)
391+
pw.written += n
392+
pw.delegate.OnProgress(float64(pw.written) / float64(pw.total))
393+
return
394+
}
395+
382396
/** Download this file to the specific location (should be outside the synced folder!) **/
383397
func (entry *Entry) Download(toPath string, delegate DownloadDelegate) {
384398
go func() {
@@ -410,33 +424,17 @@ func (entry *Entry) Download(toPath string, delegate DownloadDelegate) {
410424
}()
411425

412426
delegate.OnProgress(0.0)
413-
414-
for blockNo, block := range info.Blocks {
415-
if delegate.IsCancelled() {
416-
return
417-
}
418-
delegate.OnProgress(float64(block.Offset) / float64(info.Size))
419-
av, err := m.BlockAvailability(folderID, info, block)
420-
if err != nil {
421-
delegate.OnError(fmt.Sprintf("could not fetch availability for block %d: %s", blockNo, err.Error()))
422-
return
423-
}
424-
if len(av) < 1 {
425-
delegate.OnError(fmt.Sprintf("Part of the file is not available (block %d)", blockNo))
426-
return
427-
}
428-
429-
// Fetch the block
430-
buf, err := m.DownloadBlock(context, av[0].ID, folderID, info.Name, int(blockNo), block, false)
431-
if err != nil {
432-
delegate.OnError(fmt.Sprintf("could not fetch block %d: %s", blockNo, err.Error()))
433-
return
434-
}
435-
_, err = outFile.Write(buf)
436-
if err != nil {
437-
delegate.OnError(fmt.Sprintf("could not write block %d: %s", blockNo, err.Error()))
438-
return
439-
}
427+
mp := newMiniPuller(entry.Folder.client.Measurements, m)
428+
pw := progressWriter{
429+
out: outFile,
430+
delegate: delegate,
431+
total: int(info.Size),
432+
written: 0,
433+
}
434+
err = mp.downloadInto(context, &pw, folderID, info)
435+
if err != nil {
436+
delegate.OnError(err.Error())
437+
return
440438
}
441439
delegate.OnFinished(toPath)
442440
}()

0 commit comments

Comments
 (0)