|
@@ -21,6 +21,7 @@ import (
|
|
"io/fs"
|
|
"io/fs"
|
|
"os"
|
|
"os"
|
|
"path"
|
|
"path"
|
|
|
|
+ "slices"
|
|
"strings"
|
|
"strings"
|
|
"sync"
|
|
"sync"
|
|
"sync/atomic"
|
|
"sync/atomic"
|
|
@@ -1795,12 +1796,12 @@ type DirListerAt struct {
|
|
lister vfs.DirLister
|
|
lister vfs.DirLister
|
|
}
|
|
}
|
|
|
|
|
|
-// Add adds the given os.FileInfo to the internal cache
|
|
|
|
-func (l *DirListerAt) Add(fi os.FileInfo) {
|
|
|
|
|
|
+// Prepend adds the given os.FileInfo as first element of the internal cache
|
|
|
|
+func (l *DirListerAt) Prepend(fi os.FileInfo) {
|
|
l.mu.Lock()
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
defer l.mu.Unlock()
|
|
|
|
|
|
- l.info = append(l.info, fi)
|
|
|
|
|
|
+ l.info = slices.Insert(l.info, 0, fi)
|
|
}
|
|
}
|
|
|
|
|
|
// ListAt implements sftp.ListerAt
|
|
// ListAt implements sftp.ListerAt
|
|
@@ -1813,10 +1814,10 @@ func (l *DirListerAt) ListAt(f []os.FileInfo, _ int64) (int, error) {
|
|
}
|
|
}
|
|
if len(f) <= len(l.info) {
|
|
if len(f) <= len(l.info) {
|
|
files := make([]os.FileInfo, 0, len(f))
|
|
files := make([]os.FileInfo, 0, len(f))
|
|
- for idx := len(l.info) - 1; idx >= 0; idx-- {
|
|
|
|
|
|
+ for idx := range l.info {
|
|
files = append(files, l.info[idx])
|
|
files = append(files, l.info[idx])
|
|
if len(files) == len(f) {
|
|
if len(files) == len(f) {
|
|
- l.info = l.info[:idx]
|
|
|
|
|
|
+ l.info = l.info[idx+1:]
|
|
n := copy(f, files)
|
|
n := copy(f, files)
|
|
return n, nil
|
|
return n, nil
|
|
}
|
|
}
|
|
@@ -1838,9 +1839,7 @@ func (l *DirListerAt) Next(limit int) ([]os.FileInfo, error) {
|
|
}
|
|
}
|
|
files = l.user.FilterListDir(files, l.virtualPath)
|
|
files = l.user.FilterListDir(files, l.virtualPath)
|
|
if len(l.info) > 0 {
|
|
if len(l.info) > 0 {
|
|
- for _, fi := range l.info {
|
|
|
|
- files = util.PrependFileInfo(files, fi)
|
|
|
|
- }
|
|
|
|
|
|
+ files = slices.Concat(l.info, files)
|
|
l.info = nil
|
|
l.info = nil
|
|
}
|
|
}
|
|
if err != nil || len(files) > 0 {
|
|
if err != nil || len(files) > 0 {
|