Skip to content

Commit

Permalink
backend/fs: introduce a lazy implementation of ReadSeekCloser
Browse files Browse the repository at this point in the history
  • Loading branch information
fsouza committed Nov 1, 2022
1 parent 7c5ad47 commit 2109a1c
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 8 deletions.
10 changes: 2 additions & 8 deletions internal/backend/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,18 +285,12 @@ func (s *storageFS) getObject(bucketName, objectName string) (StreamingObject, e
}

func openObjectAndSetSize(obj *StreamingObject, path string) error {
// file is expected to be closed by the caller by calling obj.Close()
file, err := os.Open(path)
info, err := os.Stat(path)
if err != nil {
return err
}

info, err := file.Stat()
if err != nil {
return err
}

obj.Content = file
obj.Content = newLazyReader(path)
obj.Size = info.Size()

return nil
Expand Down
53 changes: 53 additions & 0 deletions internal/backend/lazy_file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2022 Francisco Souza. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package backend

import (
"io"
"os"
"sync"
)

type lazyReader struct {
filename string
once *sync.Once
f *os.File
err error
}

func newLazyReader(filename string) io.ReadSeekCloser {
return &lazyReader{
filename: filename,
once: &sync.Once{},
}
}

func (r *lazyReader) open() {
r.f, r.err = os.Open(r.filename)
}

func (r *lazyReader) Read(p []byte) (int, error) {
r.once.Do(r.open)
if r.err != nil {
return 0, r.err
}
return r.f.Read(p)
}

func (r *lazyReader) Seek(offset int64, whence int) (int64, error) {
r.once.Do(r.open)
if r.err != nil {
return 0, r.err
}
return r.f.Seek(offset, whence)
}

func (r *lazyReader) Close() error {
r.once.Do(r.open)
if r.err != nil {
return r.err
}
return r.f.Close()
}

0 comments on commit 2109a1c

Please sign in to comment.