mirror of https://github.com/spf13/afero.git
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:
parent
bc94f58bed
commit
3dec8a9191
|
@ -31,6 +31,7 @@ type File struct {
|
||||||
// atomic requires 64-bit alignment for struct field access
|
// atomic requires 64-bit alignment for struct field access
|
||||||
at int64
|
at int64
|
||||||
readDirCount int64
|
readDirCount int64
|
||||||
|
dirBuf []*FileData
|
||||||
closed bool
|
closed bool
|
||||||
readOnly bool
|
readOnly bool
|
||||||
fileData *FileData
|
fileData *FileData
|
||||||
|
@ -150,7 +151,10 @@ func (f *File) Readdir(count int) (res []os.FileInfo, err error) {
|
||||||
var outLength int64
|
var outLength int64
|
||||||
|
|
||||||
f.fileData.Lock()
|
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 count > 0 {
|
||||||
if len(files) < count {
|
if len(files) < count {
|
||||||
outLength = int64(len(files))
|
outLength = int64(len(files))
|
||||||
|
|
|
@ -2,6 +2,7 @@ package mem
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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) {
|
func TestFileReadAtSeekOffset(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue