Make file.Read more intelligible
This commit is contained in:
parent
3731a94367
commit
0606b9884e
1 changed files with 35 additions and 28 deletions
|
@ -275,9 +275,7 @@ type file struct {
|
||||||
node *restic.Node
|
node *restic.Node
|
||||||
|
|
||||||
sizes []uint32
|
sizes []uint32
|
||||||
|
blobs [][]byte
|
||||||
// cleartext contents
|
|
||||||
clearContent [][]byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFile(repo *repository.Repository, node *restic.Node) (*file, error) {
|
func newFile(repo *repository.Repository, node *restic.Node) (*file, error) {
|
||||||
|
@ -291,10 +289,10 @@ func newFile(repo *repository.Repository, node *restic.Node) (*file, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &file{
|
return &file{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
node: node,
|
node: node,
|
||||||
sizes: sizes,
|
sizes: sizes,
|
||||||
clearContent: make([][]byte, len(node.Content)),
|
blobs: make([][]byte, len(node.Content)),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,37 +303,46 @@ func (f *file) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *file) getBlobAt(i int) (blob []byte, err error) {
|
||||||
|
if f.blobs[i] != nil {
|
||||||
|
blob = f.blobs[i]
|
||||||
|
} else {
|
||||||
|
blob, err = f.repo.LoadBlob(pack.Data, f.node.Content[i])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f.blobs[i] = blob
|
||||||
|
}
|
||||||
|
|
||||||
|
return blob, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (f *file) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
func (f *file) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
||||||
off := req.Offset
|
off := req.Offset
|
||||||
|
|
||||||
|
// Skip blobs before the offset
|
||||||
|
startContent := 0
|
||||||
|
for off > int64(f.sizes[startContent]) {
|
||||||
|
off -= int64(f.sizes[startContent])
|
||||||
|
startContent++
|
||||||
|
}
|
||||||
|
|
||||||
content := make([]byte, req.Size)
|
content := make([]byte, req.Size)
|
||||||
allContent := content
|
allContent := content
|
||||||
|
for i := startContent; i < len(f.sizes); i++ {
|
||||||
for i := range f.node.Content {
|
blob, err := f.getBlobAt(i)
|
||||||
if off >= int64(f.sizes[i]) {
|
if err != nil {
|
||||||
off -= int64(f.sizes[i])
|
return err
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var subContent []byte
|
blob = blob[off:]
|
||||||
if f.clearContent[i] != nil {
|
|
||||||
subContent = f.clearContent[i]
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
subContent, err = f.repo.LoadBlob(pack.Data, f.node.Content[i])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.clearContent[i] = subContent
|
|
||||||
}
|
|
||||||
|
|
||||||
subContent = subContent[off:]
|
|
||||||
off = 0
|
off = 0
|
||||||
|
|
||||||
var copied int
|
var copied int
|
||||||
if len(subContent) > len(content) {
|
if len(blob) > len(content) {
|
||||||
copied = copy(content[0:], subContent[:len(content)])
|
copied = copy(content[0:], blob[:len(content)])
|
||||||
} else {
|
} else {
|
||||||
copied = copy(content[0:], subContent)
|
copied = copy(content[0:], blob)
|
||||||
}
|
}
|
||||||
content = content[copied:]
|
content = content[copied:]
|
||||||
if len(content) == 0 {
|
if len(content) == 0 {
|
||||||
|
|
Loading…
Reference in a new issue