feature (plg_backend_local): speed improvements on linux

This commit is contained in:
MickaelK
2026-09-24 15:29:50 +10:00
parent 42033add54
commit 8db28167c3
3 changed files with 109 additions and 3 deletions
@@ -0,0 +1,92 @@
package plg_backend_local
import (
"errors"
"io"
"os"
"unsafe"
"golang.org/x/sys/unix"
)
const (
directChunk = 16 * 1024 * 1024
directAlign = 4096
directMinSize = 8 * 1024 * 1024
)
type direct struct {
f *os.File
ch chan []byte
done chan struct{}
err error
cur []byte
}
func NewDirect(f *os.File, fs os.FileInfo) io.ReadCloser {
if fs.Size() < directMinSize {
return f
}
flags, err := unix.FcntlInt(f.Fd(), unix.F_GETFL, 0)
if err != nil {
return f
} else if _, err = unix.FcntlInt(f.Fd(), unix.F_SETFL, flags|unix.O_DIRECT); err != nil {
return f
}
return &direct{f: f, done: make(chan struct{})}
}
func (this *direct) Seek(offset int64, whence int) (int64, error) {
if this.ch != nil {
return 0, errors.New("seek not supported after read")
}
return this.f.Seek(offset, whence)
}
func (this *direct) Read(p []byte) (int, error) {
if this.ch == nil {
this.ch = make(chan []byte)
go this.fill()
}
for len(this.cur) == 0 {
b, ok := <-this.ch
if !ok {
return 0, this.err
}
this.cur = b
}
n := copy(p, this.cur)
this.cur = this.cur[n:]
return n, nil
}
func (this *direct) fill() {
defer close(this.ch)
buf, next := alignedBuffer(directChunk), alignedBuffer(directChunk)
start, err := this.f.Seek(0, io.SeekCurrent)
pos := start - start%directAlign
for err == nil {
var n int
n, err = this.f.ReadAt(buf, pos)
skip := min(max(start-pos, 0), int64(n))
select {
case this.ch <- buf[skip:n]:
case <-this.done:
return
}
pos += int64(n)
buf, next = next, buf
}
this.err = err
}
func alignedBuffer(size int) []byte {
b := make([]byte, size+directAlign)
off := directAlign - int(uintptr(unsafe.Pointer(&b[0]))%directAlign)
return b[off : off+size]
}
func (this *direct) Close() error {
close(this.done)
return this.f.Close()
}
@@ -0,0 +1,12 @@
//go:build !linux
package plg_backend_local
import (
"io"
"os"
)
func NewDirect(f *os.File, fs os.FileInfo) io.ReadCloser {
return f
}
+5 -3
View File
@@ -1,11 +1,13 @@
package plg_backend_local
import (
. "github.com/mickael-kerjean/filestash/server/common"
"golang.org/x/crypto/bcrypt"
"io"
"os"
"os/user"
. "github.com/mickael-kerjean/filestash/server/common"
"golang.org/x/crypto/bcrypt"
)
func init() {
@@ -112,7 +114,7 @@ func (this Local) Cat(path string) (io.ReadCloser, error) {
f.Close()
return nil, ErrNotFound
}
return f, nil
return NewDirect(f, fs), nil
}
func (this Local) Mkdir(path string) error {