Fix MemMapFs.Readdir to use files buffer

To match behavior of os.File.Readdir, MemMapFs.Readdir should use
files buffer instead of retrieving currently stored files on each
call.

Fixes #261
This commit is contained in:
std0 2021-07-09 00:51:49 +03:00
parent bc94f58bed
commit 3dec8a9191
2 changed files with 49 additions and 1 deletions

View File

@ -31,6 +31,7 @@ type File struct {
// atomic requires 64-bit alignment for struct field access
at int64
readDirCount int64
dirBuf []*FileData
closed bool
readOnly bool
fileData *FileData
@ -150,7 +151,10 @@ func (f *File) Readdir(count int) (res []os.FileInfo, err error) {
var outLength int64
f.fileData.Lock()
files := f.fileData.memDir.Files()[f.readDirCount:]
if f.dirBuf == nil {
f.dirBuf = f.fileData.memDir.Files()
}
files := f.dirBuf[f.readDirCount:]
if count > 0 {
if len(files) < count {
outLength = int64(len(files))

View File

@ -2,6 +2,7 @@ package mem
import (
"bytes"
"fmt"
"io"
"testing"
"time"
@ -206,6 +207,49 @@ func TestFileDataSizeRace(t *testing.T) {
}
}
func TestFileReaddirBuffer(t *testing.T) {
dir := CreateDir("dir")
const testFiles = 5
for i := 0; i < testFiles; i++ {
fd := CreateFile(fmt.Sprintf("%d.txt", i))
AddToMemDir(dir, fd)
}
f := NewFileHandle(dir)
defer f.Close()
// Read part of all files
wantNames := 3
names, err := f.Readdirnames(wantNames)
if err != nil {
t.Fatal(err)
}
if len(names) != wantNames {
t.Fatalf("got %d names %v, want %d", len(names), names, wantNames)
}
// Remove half of files
for _, fd := range dir.memDir.Files()[:testFiles/2] {
RemoveFromMemDir(dir, fd)
}
// Try to read more files than remaining
wantNames = testFiles - len(names)
names, err = f.Readdirnames(wantNames + 1)
if err != nil {
t.Fatal(err)
}
if len(names) != wantNames {
t.Fatalf("got %d names %v, want %d", len(names), names, wantNames)
}
// End of directory
_, err = f.Readdirnames(testFiles + 1)
if err != io.EOF {
t.Fatal(err)
}
}
func TestFileReadAtSeekOffset(t *testing.T) {
t.Parallel()