initial commit
This commit is contained in:
commit
3053f89410
39 changed files with 4567 additions and 0 deletions
106
pkg/fs/file.go
Normal file
106
pkg/fs/file.go
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// Copyright (C) 2022 Marius Schellenberger
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
log logr.Logger
|
||||
f *os.File
|
||||
md *Metadata
|
||||
offset int64
|
||||
}
|
||||
|
||||
type preload struct {
|
||||
f *File
|
||||
skipped int64
|
||||
written int64
|
||||
}
|
||||
|
||||
func (p *preload) Read(data []byte) (n int, err error) {
|
||||
if p.f.offset >= p.f.size() {
|
||||
return 0, io.EOF
|
||||
}
|
||||
n = len(data)
|
||||
if p.f.hasChunk(n) {
|
||||
p.skipped++
|
||||
_, err = p.f.Seek(int64(n), io.SeekCurrent)
|
||||
return
|
||||
}
|
||||
n, err = p.f.readWithoutCache(data)
|
||||
p.written++
|
||||
return
|
||||
}
|
||||
|
||||
func (f *File) Preload(unlock func()) {
|
||||
f.log.V(2).Info("preload started")
|
||||
p := &preload{f: f}
|
||||
_, err := io.Copy(io.Discard, p)
|
||||
if err != nil && err != io.EOF {
|
||||
f.log.Error(err, "error preloading file")
|
||||
}
|
||||
f.log.V(2).Info("preload finished", "skipped", p.skipped, "written", p.written)
|
||||
unlock()
|
||||
}
|
||||
|
||||
func (f *File) Read(p []byte) (n int, err error) {
|
||||
if f.hasChunk(len(p)) {
|
||||
n, err = f.md.ReadAt(p, f.offset)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = f.Seek(int64(n), io.SeekCurrent)
|
||||
return
|
||||
}
|
||||
return f.readWithoutCache(p)
|
||||
}
|
||||
|
||||
func (f *File) size() int64 {
|
||||
return f.md.Size
|
||||
}
|
||||
|
||||
func (f *File) hasChunk(n int) bool {
|
||||
return f.md.HasChunk(f.offset, n)
|
||||
}
|
||||
|
||||
func (f *File) readWithoutCache(p []byte) (n int, err error) {
|
||||
n, err = f.f.Read(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
f.md.WriteAt(p, f.offset)
|
||||
f.md.AddChunk(f.offset, n)
|
||||
f.offset += int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
func (f *File) Seek(offset int64, whence int) (n int64, err error) {
|
||||
n, err = f.f.Seek(offset, whence)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch whence {
|
||||
case io.SeekStart:
|
||||
f.offset = offset
|
||||
case io.SeekCurrent:
|
||||
f.offset += offset
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
||||
return f.f.Readdir(count)
|
||||
}
|
||||
|
||||
func (f *File) Stat() (os.FileInfo, error) {
|
||||
return f.f.Stat()
|
||||
}
|
||||
|
||||
func (f *File) Close() error {
|
||||
return f.f.Close()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue