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)
fill("..", nil, 0) fill("..", nil, 0)
for _, item := range items { for _, item := range items {
name := path.Base(item.Obj.Remote()) name := path.Base(item.DirEntry().Remote())
fill(name, nil, 0) fill(name, nil, 0)
} }
itemsRead = len(items) 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 { for _, item := range items {
var dirent fuse.Dirent var dirent fuse.Dirent
switch x := item.Obj.(type) { switch x := item.DirEntry().(type) {
case fs.Object: case fs.Object:
dirent = fuse.Dirent{ dirent = fuse.Dirent{
// Inode FIXME ??? // Inode FIXME ???

View file

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

View file

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