1
mirror of https://github.com/rclone/rclone synced 2024-12-28 21:03:45 +01:00

mountlib: store only Node in *Dir removing DirEntry struct

This commit is contained in:
Nick Craig-Wood 2017-10-26 17:21:03 +01:00
parent 8b6daaa877
commit 2fac74b517
4 changed files with 33 additions and 56 deletions

View File

@ -301,7 +301,7 @@ func (fsys *FS) Readdir(dirPath string,
fill(".", nil, 0)
fill("..", nil, 0)
for _, item := range items {
name := path.Base(item.Obj.Remote())
name := path.Base(item.DirEntry().Remote())
fill(name, nil, 0)
}
itemsRead = len(items)

View File

@ -111,7 +111,7 @@ func (d *Dir) ReadDirAll(ctx context.Context) (dirents []fuse.Dirent, err error)
}
for _, item := range items {
var dirent fuse.Dirent
switch x := item.Obj.(type) {
switch x := item.DirEntry().(type) {
case fs.Object:
dirent = fuse.Dirent{
// Inode FIXME ???

View File

@ -11,14 +11,6 @@ import (
"github.com/pkg/errors"
)
// DirEntry describes the contents of a directory entry
//
// It can be a file or a directory
type DirEntry struct {
Obj fs.DirEntry
Node Node
}
// Dir represents a directory entry
type Dir struct {
fsys *FS
@ -28,9 +20,9 @@ type Dir struct {
path string
modTime time.Time
entry fs.Directory
mu sync.Mutex // protects the following
read time.Time // time directory entry last read
items map[string]*DirEntry // NB can be nil when directory not read yet
mu sync.Mutex // protects the following
read time.Time // time directory entry last read
items map[string]Node // NB can be nil when directory not read yet
}
func newDir(fsys *FS, f fs.Fs, parent *Dir, fsDir fs.Directory) *Dir {
@ -124,8 +116,8 @@ func (d *Dir) walk(absPath string, fun func(*Dir)) {
d.mu.Lock()
defer d.mu.Unlock()
if d.items != nil {
for _, entry := range d.items {
if dir, ok := entry.Node.(*Dir); ok {
for _, node := range d.items {
if dir, ok := node.(*Dir); ok {
dir.walk(absPath, fun)
}
}
@ -152,17 +144,12 @@ func (d *Dir) rename(newParent *Dir, fsDir fs.Directory) {
// addObject adds a new object or directory to the directory
//
// note that we add new objects rather than updating old ones
func (d *Dir) addObject(o fs.DirEntry, node Node) *DirEntry {
item := &DirEntry{
Obj: o,
Node: node,
}
func (d *Dir) addObject(node Node) {
d.mu.Lock()
if d.items != nil {
d.items[path.Base(o.Remote())] = item
d.items[node.Name()] = node
}
d.mu.Unlock()
return item
}
// delObject removes an object from the directory
@ -201,32 +188,26 @@ func (d *Dir) _readDir() error {
oldItems := d.items
// Cache the items by name
d.items = make(map[string]*DirEntry, len(entries))
d.items = make(map[string]Node, len(entries))
for _, entry := range entries {
switch item := entry.(type) {
case fs.Object:
obj := item
name := path.Base(obj.Remote())
d.items[name] = &DirEntry{
Obj: obj,
Node: newFile(d, obj, name),
}
d.items[name] = newFile(d, obj, name)
case fs.Directory:
dir := item
name := path.Base(dir.Remote())
// Use old dir value if it exists
if oldItems != nil {
if oldItem, ok := oldItems[name]; ok {
if _, ok := oldItem.Obj.(fs.Directory); ok {
d.items[name] = oldItem
if oldNode, ok := oldItems[name]; ok {
if oldNode.IsDir() {
d.items[name] = oldNode
continue
}
}
}
d.items[name] = &DirEntry{
Obj: dir,
Node: newDir(d.fsys, d.f, d, dir),
}
d.items[name] = newDir(d.fsys, d.f, d, dir)
default:
err = errors.Errorf("unknown type %T", item)
fs.Errorf(d.path, "readDir error: %v", err)
@ -240,7 +221,7 @@ func (d *Dir) _readDir() error {
// lookup a single item in the directory
//
// returns ENOENT if not found.
func (d *Dir) lookup(leaf string) (*DirEntry, error) {
func (d *Dir) lookup(leaf string) (Node, error) {
d.mu.Lock()
defer d.mu.Unlock()
err := d._readDir()
@ -296,7 +277,7 @@ func (d *Dir) SetModTime(modTime time.Time) error {
func (d *Dir) Lookup(name string) (node Node, err error) {
path := path.Join(d.path, name)
// fs.Debugf(path, "Dir.Lookup")
item, err := d.lookup(name)
node, err = d.lookup(name)
if err != nil {
if err != ENOENT {
fs.Errorf(path, "Dir.Lookup error: %v", err)
@ -304,11 +285,11 @@ func (d *Dir) Lookup(name string) (node Node, err error) {
return nil, err
}
// fs.Debugf(path, "Dir.Lookup OK")
return item.Node, nil
return node, nil
}
// ReadDirAll reads the contents of the directory
func (d *Dir) ReadDirAll() (items []*DirEntry, err error) {
func (d *Dir) ReadDirAll() (items []Node, err error) {
// fs.Debugf(d.path, "Dir.ReadDirAll")
d.mu.Lock()
defer d.mu.Unlock()
@ -357,7 +338,7 @@ func (d *Dir) Mkdir(name string) (*Dir, error) {
}
fsDir := fs.NewDir(path, time.Now())
dir := newDir(d.fsys, d.f, d, fsDir)
d.addObject(fsDir, dir)
d.addObject(dir)
// fs.Debugf(path, "Dir.Mkdir OK")
return dir, nil
}
@ -396,15 +377,15 @@ func (d *Dir) RemoveAll() error {
return EROFS
}
// Remove contents of the directory
items, err := d.ReadDirAll()
nodes, err := d.ReadDirAll()
if err != nil {
fs.Errorf(d.path, "Dir.RemoveAll failed to read directory: %v", err)
return err
}
for _, item := range items {
err = item.Node.RemoveAll()
for _, node := range nodes {
err = node.RemoveAll()
if err != nil {
fs.Errorf(item.Obj, "Dir.RemoveAll failed to remove: %v", err)
fs.Errorf(node.DirEntry(), "Dir.RemoveAll failed to remove: %v", err)
return err
}
}
@ -425,12 +406,12 @@ func (d *Dir) RemoveName(name string) error {
}
path := path.Join(d.path, name)
// fs.Debugf(path, "Dir.Remove")
item, err := d.lookup(name)
node, err := d.lookup(name)
if err != nil {
fs.Errorf(path, "Dir.Remove error: %v", err)
return err
}
return item.Node.Remove()
return node.Remove()
}
// Rename the file
@ -441,14 +422,12 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
oldPath := path.Join(d.path, oldName)
newPath := path.Join(destDir.path, newName)
// fs.Debugf(oldPath, "Dir.Rename to %q", newPath)
oldItem, err := d.lookup(oldName)
oldNode, err := d.lookup(oldName)
if err != nil {
fs.Errorf(oldPath, "Dir.Rename error: %v", err)
return err
}
var newObj fs.DirEntry
oldNode := oldItem.Node
switch x := oldItem.Obj.(type) {
switch x := oldNode.DirEntry().(type) {
case fs.Object:
oldObject := x
// FIXME: could Copy then Delete if Move not available
@ -464,11 +443,10 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
fs.Errorf(oldPath, "Dir.Rename error: %v", err)
return err
}
newObj = newObject
// Update the node with the new details
if oldNode != nil {
if oldFile, ok := oldNode.(*File); ok {
fs.Debugf(oldItem.Obj, "Updating file with %v %p", newObject, oldFile)
fs.Debugf(oldNode.DirEntry(), "Updating file with %v %p", newObject, oldFile)
oldFile.rename(destDir, newObject)
}
}
@ -487,23 +465,22 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
return err
}
newDir := fs.NewDirCopy(x).SetRemote(newPath)
newObj = newDir
// Update the node with the new details
if oldNode != nil {
if oldDir, ok := oldNode.(*Dir); ok {
fs.Debugf(oldItem.Obj, "Updating dir with %v %p", newDir, oldDir)
fs.Debugf(oldNode.DirEntry(), "Updating dir with %v %p", newDir, oldDir)
oldDir.rename(destDir, newDir)
}
}
default:
err = errors.Errorf("unknown type %T", oldItem)
err = errors.Errorf("unknown type %T", oldNode)
fs.Errorf(d.path, "Dir.ReadDirAll error: %v", err)
return err
}
// Show moved - delete from old dir and add to new
d.delObject(oldName)
destDir.addObject(newObj, oldNode)
destDir.addObject(oldNode)
// fs.Debugf(newPath, "Dir.Rename renamed from %q", oldPath)
return nil

View File

@ -179,7 +179,7 @@ func (f *File) setObject(o fs.Object) {
defer f.mu.Unlock()
f.o = o
_ = f.applyPendingModTime()
f.d.addObject(o, f)
f.d.addObject(f)
}
// Wait for f.o to become non nil for a short time returning it or an