diff --git a/backend/amazonclouddrive/amazonclouddrive.go b/backend/amazonclouddrive/amazonclouddrive.go index 2341c8b9a..ebe5c51d5 100644 --- a/backend/amazonclouddrive/amazonclouddrive.go +++ b/backend/amazonclouddrive/amazonclouddrive.go @@ -514,10 +514,6 @@ func (f *Fs) listAll(dirID string, title string, directoriesOnly bool, filesOnly // This should return ErrDirNotFound if the directory isn't // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -665,7 +661,7 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options . return nil, err } // If not create it - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, remote, true) if err != nil { return nil, err } @@ -696,13 +692,7 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options . // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -724,10 +714,6 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, } // create the destination directory if necessary - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return nil, err - } srcLeaf, srcDirectoryID, err := srcObj.fs.dirCache.FindPath(ctx, srcObj.remote, false) if err != nil { return nil, err @@ -797,54 +783,24 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err = srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - dstLeaf, dstDirectoryID, err := f.dirCache.FindPath(ctx, findPath, true) + dstLeaf, dstDirectoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src parent - findPath = srcRemote - var srcDirectoryID string - if srcRemote == "" { - srcDirectoryID, err = srcFs.dirCache.RootParentID() - } else { - _, srcDirectoryID, err = srcFs.dirCache.FindPath(ctx, findPath, false) - } + _, srcDirectoryID, err := srcFs.dirCache.FindPath(ctx, srcRemote, false) if err != nil { return err } @@ -890,10 +846,6 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return errors.New("can't purge root directory") } dc := f.dirCache - err := dc.FindRoot(ctx, false) - if err != nil { - return err - } rootID, err := dc.FindDir(ctx, dir, false) if err != nil { return err @@ -1037,7 +989,7 @@ func (o *Object) readMetaData(ctx context.Context) (err error) { if o.info != nil { return nil } - leaf, directoryID, err := o.fs.dirCache.FindRootAndPath(ctx, o.remote, false) + leaf, directoryID, err := o.fs.dirCache.FindPath(ctx, o.remote, false) if err != nil { if err == fs.ErrorDirNotFound { return fs.ErrorObjectNotFound diff --git a/backend/box/box.go b/backend/box/box.go index d5388c5c6..bdb75f465 100644 --- a/backend/box/box.go +++ b/backend/box/box.go @@ -329,7 +329,7 @@ func shouldRetry(resp *http.Response, err error) (bool, error) { // readMetaDataForPath reads the metadata from the path func (f *Fs) readMetaDataForPath(ctx context.Context, path string) (info *api.Item, err error) { // defer fs.Trace(f, "path=%q", path)("info=%+v, err=%v", &info, &err) - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, path, false) + leaf, directoryID, err := f.dirCache.FindPath(ctx, path, false) if err != nil { if err == fs.ErrorDirNotFound { return nil, fs.ErrorObjectNotFound @@ -617,10 +617,6 @@ OUTER: // This should return ErrDirNotFound if the directory isn't // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -661,7 +657,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e // Used to create new objects func (f *Fs) createObject(ctx context.Context, remote string, modTime time.Time, size int64) (o *Object, leaf string, directoryID string, err error) { // Create the directory for the object if it doesn't exist - leaf, directoryID, err = f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err = f.dirCache.FindPath(ctx, remote, true) if err != nil { return } @@ -717,13 +713,7 @@ func (f *Fs) PutUnchecked(ctx context.Context, in io.Reader, src fs.ObjectInfo, // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -748,10 +738,6 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return errors.New("can't purge root directory") } dc := f.dirCache - err := dc.FindRoot(ctx, false) - if err != nil { - return err - } rootID, err := dc.FindDir(ctx, dir, false) if err != nil { return err @@ -967,45 +953,20 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err := srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, directoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, directoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src @@ -1330,7 +1291,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op remote := o.Remote() // Create the directory for the object if it doesn't exist - leaf, directoryID, err := o.fs.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := o.fs.dirCache.FindPath(ctx, remote, true) if err != nil { return err } diff --git a/backend/drive/drive.go b/backend/drive/drive.go index 252ab5081..5fb4a62cf 100755 --- a/backend/drive/drive.go +++ b/backend/drive/drive.go @@ -1589,10 +1589,6 @@ func (f *Fs) findImportFormat(mimeType string) string { // This should return ErrDirNotFound if the directory isn't // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -1814,10 +1810,6 @@ func (f *Fs) listRRunner(ctx context.Context, wg *sync.WaitGroup, in chan listRE // Don't implement this unless you have a more efficient way // of listing recursively that doing a directory traversal. func (f *Fs) ListR(ctx context.Context, dir string, callback fs.ListRCallback) (err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return err @@ -2026,7 +2018,7 @@ func (f *Fs) itemToDirEntry(remote string, item *drive.File) (entry fs.DirEntry, // // Used to create new objects func (f *Fs) createFileInfo(ctx context.Context, remote string, modTime time.Time) (*drive.File, error) { - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, remote, true) if err != nil { return nil, err } @@ -2189,13 +2181,7 @@ func (f *Fs) MergeDirs(ctx context.Context, dirs []fs.Directory) error { // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -2368,11 +2354,11 @@ func (f *Fs) Purge(ctx context.Context) error { if f.opt.TrashedOnly { return errors.New("Can't purge with --drive-trashed-only. Use delete if you want to selectively delete files") } - err := f.dirCache.FindRoot(ctx, false) + rootID, err := f.dirCache.RootID(ctx, false) if err != nil { return err } - err = f.delete(ctx, shortcutID(f.dirCache.RootID()), f.opt.UseTrash) + err = f.delete(ctx, shortcutID(rootID), f.opt.UseTrash) f.dirCache.ResetRoot() if err != nil { return err @@ -2565,55 +2551,25 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err := srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, dstDirectoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, dstDirectoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, dstDirectoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } dstDirectoryID = actualID(dstDirectoryID) // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src parent - var srcDirectoryID string - if srcRemote == "" { - srcDirectoryID, err = srcFs.dirCache.RootParentID() - } else { - _, srcDirectoryID, err = srcFs.dirCache.FindPath(ctx, srcRemote, false) - } + _, srcDirectoryID, err := srcFs.dirCache.FindPath(ctx, srcRemote, false) if err != nil { return err } @@ -2878,11 +2834,10 @@ func (f *Fs) makeShortcut(ctx context.Context, srcPath string, dstFs *Fs, dstPat isDir := false if srcPath == "" { // source is root directory - err = f.dirCache.FindRoot(ctx, false) + srcID, err = f.dirCache.RootID(ctx, false) if err != nil { return nil, err } - srcID = f.dirCache.RootID() isDir = true } else if srcObj, err := srcFs.NewObject(ctx, srcPath); err != nil { if err != fs.ErrorNotAFile { @@ -3111,7 +3066,7 @@ func (f *Fs) getRemoteInfo(ctx context.Context, remote string) (info *drive.File // getRemoteInfoWithExport returns a drive.File and the export settings for the remote func (f *Fs) getRemoteInfoWithExport(ctx context.Context, remote string) ( info *drive.File, extension, exportName, exportMimeType string, isDocument bool, err error) { - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, remote, false) + leaf, directoryID, err := f.dirCache.FindPath(ctx, remote, false) if err != nil { if err == fs.ErrorDirNotFound { return nil, "", "", "", false, fs.ErrorObjectNotFound diff --git a/backend/fichier/api.go b/backend/fichier/api.go index d58f58626..c67d05259 100644 --- a/backend/fichier/api.go +++ b/backend/fichier/api.go @@ -148,11 +148,6 @@ func (f *Fs) listFolders(ctx context.Context, directoryID int) (foldersList *Fol } func (f *Fs) listDir(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } - directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err diff --git a/backend/fichier/fichier.go b/backend/fichier/fichier.go index 26dba8340..b8689a8d5 100644 --- a/backend/fichier/fichier.go +++ b/backend/fichier/fichier.go @@ -264,7 +264,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e // NewObject finds the Object at remote. If it can't be found // it returns the error ErrorObjectNotFound. func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) { - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, remote, false) + leaf, directoryID, err := f.dirCache.FindPath(ctx, remote, false) if err != nil { if err == fs.ErrorDirNotFound { return nil, fs.ErrorObjectNotFound @@ -334,7 +334,7 @@ func (f *Fs) putUnchecked(ctx context.Context, in io.Reader, remote string, size return nil, err } - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, remote, true) if err != nil { return nil, err } @@ -389,13 +389,7 @@ func (f *Fs) PutUnchecked(ctx context.Context, in io.Reader, src fs.ObjectInfo, // // Shouldn't return an error if it already exists func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -403,11 +397,6 @@ func (f *Fs) Mkdir(ctx context.Context, dir string) error { // // Return an error if it doesn't exist or isn't empty func (f *Fs) Rmdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return err diff --git a/backend/onedrive/onedrive.go b/backend/onedrive/onedrive.go index 202433742..d3a030761 100755 --- a/backend/onedrive/onedrive.go +++ b/backend/onedrive/onedrive.go @@ -498,13 +498,13 @@ func (f *Fs) readMetaDataForPath(ctx context.Context, path string) (info *api.It var dirCacheFoundRoot bool var rootNormalizedID string if f.dirCache != nil { - var dirCacheRootIDExists bool - rootNormalizedID, dirCacheRootIDExists = f.dirCache.Get("") + rootNormalizedID, err = f.dirCache.RootID(ctx, false) + dirCacheRootIDExists := err == nil if f.root == "" { // if f.root == "", it means f.root is the absolute root of the drive // and its ID should have been found in NewFs dirCacheFoundRoot = dirCacheRootIDExists - } else if _, err := f.dirCache.RootParentID(); err == nil { + } else if _, err := f.dirCache.RootParentID(ctx, false); err == nil { // if root is in a folder, it must have a parent folder, and // if dirCache has found root in NewFs, the parent folder's ID // should be present. @@ -813,10 +813,6 @@ OUTER: // This should return ErrDirNotFound if the directory isn't // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -864,7 +860,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e // Used to create new objects func (f *Fs) createObject(ctx context.Context, remote string, modTime time.Time, size int64) (o *Object, leaf string, directoryID string, err error) { // Create the directory for the object if it doesn't exist - leaf, directoryID, err = f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err = f.dirCache.FindPath(ctx, remote, true) if err != nil { return nil, leaf, directoryID, err } @@ -895,13 +891,7 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options . // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -924,10 +914,6 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return errors.New("can't purge root directory") } dc := f.dirCache - err := dc.FindRoot(ctx, false) - if err != nil { - return err - } rootID, err := dc.FindDir(ctx, dir, false) if err != nil { return err @@ -1182,31 +1168,8 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err := srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, dstDirectoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, dstDirectoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, dstDirectoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } @@ -1226,15 +1189,13 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Get timestamps of src so they can be preserved diff --git a/backend/opendrive/opendrive.go b/backend/opendrive/opendrive.go index 6e89bcca6..c06b96314 100644 --- a/backend/opendrive/opendrive.go +++ b/backend/opendrive/opendrive.go @@ -280,13 +280,7 @@ func errorHandler(resp *http.Response) error { // Mkdir creates the folder if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { // fs.Debugf(nil, "Mkdir(\"%s\")", dir) - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -312,10 +306,6 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return errors.New("can't purge root directory") } dc := f.dirCache - err := dc.FindRoot(ctx, false) - if err != nil { - return err - } rootID, err := dc.FindDir(ctx, dir, false) if err != nil { return err @@ -492,45 +482,20 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err = srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, directoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, directoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src @@ -620,7 +585,7 @@ func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) { // Used to create new objects func (f *Fs) createObject(ctx context.Context, remote string, modTime time.Time, size int64) (o *Object, leaf string, directoryID string, err error) { // Create the directory for the object if it doesn't exist - leaf, directoryID, err = f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err = f.dirCache.FindPath(ctx, remote, true) if err != nil { return nil, leaf, directoryID, err } @@ -803,10 +768,6 @@ func (f *Fs) FindLeaf(ctx context.Context, pathID, leaf string) (pathIDOut strin // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { // fs.Debugf(nil, "List(%v)", dir) - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -1079,7 +1040,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op } func (o *Object) readMetaData(ctx context.Context) (err error) { - leaf, directoryID, err := o.fs.dirCache.FindRootAndPath(ctx, o.remote, false) + leaf, directoryID, err := o.fs.dirCache.FindPath(ctx, o.remote, false) if err != nil { if err == fs.ErrorDirNotFound { return fs.ErrorObjectNotFound diff --git a/backend/pcloud/pcloud.go b/backend/pcloud/pcloud.go index 46bbf6d61..83524e35a 100644 --- a/backend/pcloud/pcloud.go +++ b/backend/pcloud/pcloud.go @@ -198,7 +198,7 @@ func shouldRetry(resp *http.Response, err error) (bool, error) { // readMetaDataForPath reads the metadata from the path func (f *Fs) readMetaDataForPath(ctx context.Context, path string) (info *api.Item, err error) { // defer fs.Trace(f, "path=%q", path)("info=%+v, err=%v", &info, &err) - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, path, false) + leaf, directoryID, err := f.dirCache.FindPath(ctx, path, false) if err != nil { if err == fs.ErrorDirNotFound { return nil, fs.ErrorObjectNotFound @@ -455,10 +455,6 @@ func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, fi // This should return ErrDirNotFound if the directory isn't // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -499,7 +495,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e // Used to create new objects func (f *Fs) createObject(ctx context.Context, remote string, modTime time.Time, size int64) (o *Object, leaf string, directoryID string, err error) { // Create the directory for the object if it doesn't exist - leaf, directoryID, err = f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err = f.dirCache.FindPath(ctx, remote, true) if err != nil { return } @@ -530,13 +526,7 @@ func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options . // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -548,10 +538,6 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return errors.New("can't purge root directory") } dc := f.dirCache - err := dc.FindRoot(ctx, false) - if err != nil { - return err - } rootID, err := dc.FindDir(ctx, dir, false) if err != nil { return err @@ -659,7 +645,7 @@ func (f *Fs) Purge(ctx context.Context) error { // CleanUp empties the trash func (f *Fs) CleanUp(ctx context.Context) error { - err := f.dirCache.FindRoot(ctx, false) + rootID, err := f.dirCache.RootID(ctx, false) if err != nil { return err } @@ -668,7 +654,7 @@ func (f *Fs) CleanUp(ctx context.Context) error { Path: "/trash_clear", Parameters: url.Values{}, } - opts.Parameters.Set("folderid", dirIDtoNumber(f.dirCache.RootID())) + opts.Parameters.Set("folderid", dirIDtoNumber(rootID)) var resp *http.Response var result api.Error return f.pacer.Call(func() (bool, error) { @@ -750,45 +736,20 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err := srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, directoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, directoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src @@ -1111,7 +1072,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op remote := o.Remote() // Create the directory for the object if it doesn't exist - leaf, directoryID, err := o.fs.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := o.fs.dirCache.FindPath(ctx, remote, true) if err != nil { return err } diff --git a/backend/premiumizeme/premiumizeme.go b/backend/premiumizeme/premiumizeme.go index b80f5a749..bc31a121a 100644 --- a/backend/premiumizeme/premiumizeme.go +++ b/backend/premiumizeme/premiumizeme.go @@ -183,7 +183,7 @@ func shouldRetry(resp *http.Response, err error) (bool, error) { // readMetaDataForPath reads the metadata from the path func (f *Fs) readMetaDataForPath(ctx context.Context, path string, directoriesOnly bool, filesOnly bool) (info *api.Item, err error) { // defer fs.Trace(f, "path=%q", path)("info=%+v, err=%v", &info, &err) - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, path, false) + leaf, directoryID, err := f.dirCache.FindPath(ctx, path, false) if err != nil { if err == fs.ErrorDirNotFound { return nil, fs.ErrorObjectNotFound @@ -450,10 +450,6 @@ func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, fi // This should return ErrDirNotFound if the directory isn't // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -493,7 +489,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e // Used to create new objects func (f *Fs) createObject(ctx context.Context, remote string, modTime time.Time, size int64) (o *Object, leaf string, directoryID string, err error) { // Create the directory for the object if it doesn't exist - leaf, directoryID, err = f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err = f.dirCache.FindPath(ctx, remote, true) if err != nil { return } @@ -544,13 +540,7 @@ func (f *Fs) PutUnchecked(ctx context.Context, in io.Reader, src fs.ObjectInfo, // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -562,10 +552,6 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return errors.New("can't purge root directory") } dc := f.dirCache - err := dc.FindRoot(ctx, false) - if err != nil { - return err - } rootID, err := dc.FindDir(ctx, dir, false) if err != nil { return err @@ -754,45 +740,20 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err := srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, directoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, directoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src @@ -802,12 +763,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string } // Find ID of src parent, not creating subdirs - var srcLeaf, srcDirectoryID string - findPath = srcRemote - if srcRemote == "" { - findPath = srcFs.root - } - srcLeaf, srcDirectoryID, err = srcFs.dirCache.FindPath(ctx, findPath, false) + srcLeaf, srcDirectoryID, err := srcFs.dirCache.FindPath(ctx, srcRemote, false) if err != nil { return err } @@ -990,7 +946,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op size := src.Size() // Create the directory for the object if it doesn't exist - leaf, directoryID, err := o.fs.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := o.fs.dirCache.FindPath(ctx, remote, true) if err != nil { return err } diff --git a/backend/putio/fs.go b/backend/putio/fs.go index d35414a2a..aa779c10a 100644 --- a/backend/putio/fs.go +++ b/backend/putio/fs.go @@ -197,10 +197,6 @@ func (f *Fs) FindLeaf(ctx context.Context, pathID, leaf string) (pathIDOut strin // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { // defer log.Trace(f, "dir=%v", dir)("err=%v", &err) - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -260,7 +256,7 @@ func (f *Fs) PutUnchecked(ctx context.Context, in io.Reader, src fs.ObjectInfo, // defer log.Trace(f, "src=%+v", src)("o=%+v, err=%v", &o, &err) size := src.Size() remote := src.Remote() - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, remote, true) if err != nil { return nil, err } @@ -458,13 +454,7 @@ func (f *Fs) makeUploadPatchRequest(ctx context.Context, location string, in io. // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) (err error) { // defer log.Trace(f, "dir=%v", dir)("err=%v", &err) - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err = f.dirCache.FindDir(ctx, dir, true) return err } @@ -528,12 +518,11 @@ func (f *Fs) Purge(ctx context.Context) (err error) { if f.root == "" { return errors.New("can't purge root directory") } - err = f.dirCache.FindRoot(ctx, false) + rootIDs, err := f.dirCache.RootID(ctx, false) if err != nil { return err } - - rootID := atoi(f.dirCache.RootID()) + rootID := atoi(rootIDs) // Let putio delete the filesystem tree err = f.pacer.Call(func() (bool, error) { // fs.Debugf(f, "deleting file: %d", rootID) @@ -559,7 +548,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (o fs.Objec if !ok { return nil, fs.ErrorCantCopy } - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, remote, true) if err != nil { return nil, err } @@ -598,7 +587,7 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (o fs.Objec if !ok { return nil, fs.ErrorCantMove } - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, remote, true) if err != nil { return nil, err } @@ -644,45 +633,20 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err = srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, dstDirectoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, dstDirectoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, dstDirectoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src diff --git a/backend/putio/object.go b/backend/putio/object.go index 09ddcf844..2507f6488 100644 --- a/backend/putio/object.go +++ b/backend/putio/object.go @@ -125,7 +125,7 @@ func (o *Object) setMetadataFromEntry(info putio.File) error { // Reads the entry for a file from putio func (o *Object) readEntry(ctx context.Context) (f *putio.File, err error) { // defer log.Trace(o, "")("f=%+v, err=%v", f, &err) - leaf, directoryID, err := o.fs.dirCache.FindRootAndPath(ctx, o.remote, false) + leaf, directoryID, err := o.fs.dirCache.FindPath(ctx, o.remote, false) if err != nil { if err == fs.ErrorDirNotFound { return nil, fs.ErrorObjectNotFound diff --git a/backend/sharefile/sharefile.go b/backend/sharefile/sharefile.go index d72112334..202211ac3 100644 --- a/backend/sharefile/sharefile.go +++ b/backend/sharefile/sharefile.go @@ -350,7 +350,7 @@ func (f *Fs) readMetaDataForID(ctx context.Context, id string, directoriesOnly b // readMetaDataForPath reads the metadata from the path func (f *Fs) readMetaDataForPath(ctx context.Context, path string, directoriesOnly bool, filesOnly bool) (info *api.Item, err error) { - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, path, false) + leaf, directoryID, err := f.dirCache.FindPath(ctx, path, false) if err != nil { if err == fs.ErrorDirNotFound { return nil, fs.ErrorObjectNotFound @@ -700,10 +700,6 @@ func (f *Fs) listAll(ctx context.Context, dirID string, directoriesOnly bool, fi // This should return ErrDirNotFound if the directory isn't // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -743,7 +739,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e // Used to create new objects func (f *Fs) createObject(ctx context.Context, remote string, modTime time.Time, size int64) (o *Object, leaf string, directoryID string, err error) { // Create the directory for the object if it doesn't exist - leaf, directoryID, err = f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err = f.dirCache.FindPath(ctx, remote, true) if err != nil { return } @@ -799,13 +795,7 @@ func (f *Fs) PutUnchecked(ctx context.Context, in io.Reader, src fs.ObjectInfo, // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -817,10 +807,6 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return errors.New("can't purge root directory") } dc := f.dirCache - err := dc.FindRoot(ctx, false) - if err != nil { - return err - } rootID, err := dc.FindDir(ctx, dir, false) if err != nil { return err @@ -1042,45 +1028,20 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err := srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, directoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, directoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src @@ -1090,12 +1051,7 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string } // Find ID of src parent, not creating subdirs - var srcLeaf, srcDirectoryID string - findPath = srcRemote - if srcRemote == "" { - findPath = srcFs.root - } - srcLeaf, srcDirectoryID, err = srcFs.dirCache.FindPath(ctx, findPath, false) + srcLeaf, srcDirectoryID, err := srcFs.dirCache.FindPath(ctx, srcRemote, false) if err != nil { return err } @@ -1402,7 +1358,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op isLargeFile := size < 0 || size > int64(o.fs.opt.UploadCutoff) // Create the directory for the object if it doesn't exist - leaf, directoryID, err := o.fs.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := o.fs.dirCache.FindPath(ctx, remote, true) if err != nil { return err } diff --git a/backend/sugarsync/sugarsync.go b/backend/sugarsync/sugarsync.go index 8c22d680f..e41a9a23c 100644 --- a/backend/sugarsync/sugarsync.go +++ b/backend/sugarsync/sugarsync.go @@ -255,7 +255,7 @@ func shouldRetry(resp *http.Response, err error) (bool, error) { // readMetaDataForPath reads the metadata from the path func (f *Fs) readMetaDataForPath(ctx context.Context, path string) (info *api.File, err error) { // defer fs.Trace(f, "path=%q", path)("info=%+v, err=%v", &info, &err) - leaf, directoryID, err := f.dirCache.FindRootAndPath(ctx, path, false) + leaf, directoryID, err := f.dirCache.FindPath(ctx, path, false) if err != nil { if err == fs.ErrorDirNotFound { return nil, fs.ErrorObjectNotFound @@ -663,10 +663,6 @@ OUTER: // This should return ErrDirNotFound if the directory isn't // found. func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) { - err = f.dirCache.FindRoot(ctx, false) - if err != nil { - return nil, err - } directoryID, err := f.dirCache.FindDir(ctx, dir, false) if err != nil { return nil, err @@ -709,7 +705,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e // Used to create new objects func (f *Fs) createObject(ctx context.Context, remote string, modTime time.Time, size int64) (o *Object, leaf string, directoryID string, err error) { // Create the directory for the object if it doesn't exist - leaf, directoryID, err = f.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err = f.dirCache.FindPath(ctx, remote, true) if err != nil { return } @@ -765,13 +761,7 @@ func (f *Fs) PutUnchecked(ctx context.Context, in io.Reader, src fs.ObjectInfo, // Mkdir creates the container if it doesn't exist func (f *Fs) Mkdir(ctx context.Context, dir string) error { - err := f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - if dir != "" { - _, err = f.dirCache.FindDir(ctx, dir, true) - } + _, err := f.dirCache.FindDir(ctx, dir, true) return err } @@ -807,10 +797,6 @@ func (f *Fs) purgeCheck(ctx context.Context, dir string, check bool) error { return errors.New("can't purge root directory") } dc := f.dirCache - err := dc.FindRoot(ctx, false) - if err != nil { - return err - } directoryID, err := dc.FindDir(ctx, dir, false) if err != nil { return err @@ -1042,45 +1028,20 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return errors.New("can't move root directory") } - // find the root src directory - err := srcFs.dirCache.FindRoot(ctx, false) - if err != nil { - return err - } - - // find the root dst directory - if dstRemote != "" { - err = f.dirCache.FindRoot(ctx, true) - if err != nil { - return err - } - } else { - if f.dirCache.FoundRoot() { - return fs.ErrorDirExists - } - } - // Find ID of dst parent, creating subdirs if necessary - var leaf, directoryID string - findPath := dstRemote - if dstRemote == "" { - findPath = f.root - } - leaf, directoryID, err = f.dirCache.FindPath(ctx, findPath, true) + leaf, directoryID, err := f.dirCache.FindPath(ctx, dstRemote, true) if err != nil { return err } // Check destination does not exist - if dstRemote != "" { - _, err = f.dirCache.FindDir(ctx, dstRemote, false) - if err == fs.ErrorDirNotFound { - // OK - } else if err != nil { - return err - } else { - return fs.ErrorDirExists - } + _, err = f.dirCache.FindDir(ctx, dstRemote, false) + if err == fs.ErrorDirNotFound { + // OK + } else if err != nil { + return err + } else { + return fs.ErrorDirExists } // Find ID of src @@ -1289,7 +1250,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op remote := o.Remote() // Create the directory for the object if it doesn't exist - leaf, directoryID, err := o.fs.dirCache.FindRootAndPath(ctx, remote, true) + leaf, directoryID, err := o.fs.dirCache.FindPath(ctx, remote, true) if err != nil { return err } diff --git a/lib/dircache/dircache.go b/lib/dircache/dircache.go index ab06d42c3..67a84a0c6 100644 --- a/lib/dircache/dircache.go +++ b/lib/dircache/dircache.go @@ -1,4 +1,5 @@ -// Package dircache provides a simple cache for caching directory to path lookups +// Package dircache provides a simple cache for caching directory ID +// to path lookups and the inverse. package dircache // _methods are called without the lock @@ -7,7 +8,6 @@ import ( "bytes" "context" "fmt" - "log" "strings" "sync" @@ -17,19 +17,23 @@ import ( // DirCache caches paths to directory IDs and vice versa type DirCache struct { - cacheMu sync.RWMutex - cache map[string]string - invCache map[string]string - mu sync.Mutex - fs DirCacher // Interface to find and make stuff - trueRootID string // ID of the absolute root - root string // the path we are working on - rootID string // ID of the root directory - rootParentID string // ID of the root's parent directory - foundRoot bool // Whether we have found the root or not + cacheMu sync.RWMutex // protects cache and invCache + cache map[string]string + invCache map[string]string + + mu sync.Mutex // protects the below + fs DirCacher // Interface to find and make directories + trueRootID string // ID of the absolute root + root string // the path the cache is rooted on + rootID string // ID of the root directory + rootParentID string // ID of the root's parent directory + foundRoot bool // Whether we have found the root or not } // DirCacher describes an interface for doing the low level directory work +// +// This should be implemented by the backend and will be called by the +// dircache package when appropriate. type DirCacher interface { FindLeaf(ctx context.Context, pathID, leaf string) (pathIDOut string, found bool, err error) CreateDir(ctx context.Context, pathID, leaf string) (newID string, err error) @@ -37,6 +41,15 @@ type DirCacher interface { // New makes a DirCache // +// This is created with the true root ID and the root path. +// +// In order to use the cache FindRoot() must be called on it without +// error. This isn't done at initialization as it isn't known whether +// the root and intermediate directories need to be created or not. +// +// Most of the utility functions wil call FindRoot() on the caller's +// behalf with the create flag passed in. +// // The cache is safe for concurrent use func New(root string, trueRootID string, fs DirCacher) *DirCache { d := &DirCache{ @@ -74,23 +87,29 @@ func (dc *DirCache) String() string { return buf.String() } -// Get an ID given a path +// Get a directory ID given a path +// +// Returns the ID and a boolean as to whether it was found or not in +// the cache. func (dc *DirCache) Get(path string) (id string, ok bool) { dc.cacheMu.RLock() id, ok = dc.cache[path] dc.cacheMu.RUnlock() - return + return id, ok } -// GetInv gets a path given an ID +// GetInv gets a path given a directory ID +// +// Returns the path and a boolean as to whether it was found or not in +// the cache. func (dc *DirCache) GetInv(id string) (path string, ok bool) { dc.cacheMu.RLock() path, ok = dc.invCache[id] dc.cacheMu.RUnlock() - return + return path, ok } -// Put a path, id into the map +// Put a (path, directory ID) pair into the cache func (dc *DirCache) Put(path, id string) { dc.cacheMu.Lock() dc.cache[path] = id @@ -98,7 +117,7 @@ func (dc *DirCache) Put(path, id string) { dc.cacheMu.Unlock() } -// Flush the map of all data +// Flush the cache of all data func (dc *DirCache) Flush() { dc.cacheMu.Lock() dc.cache = make(map[string]string) @@ -106,9 +125,10 @@ func (dc *DirCache) Flush() { dc.cacheMu.Unlock() } -// FlushDir flushes the map of all data starting with dir +// FlushDir flushes the map of all data starting with with the path +// dir. // -// If dir is empty then this is equivalent to calling ResetRoot +// If dir is empty string then this is equivalent to calling ResetRoot func (dc *DirCache) FlushDir(dir string) { if dir == "" { dc.ResetRoot() @@ -159,39 +179,29 @@ func SplitPath(path string) (directory, leaf string) { // // If create is set it will make the directory if not found // -// Algorithm: -// Look in the cache for the path, if found return the pathID -// If not found strip the last path off the path and recurse -// Now have a parent directory id, so look in the parent for self and return it +// It will call FindRoot if it hasn't been called already func (dc *DirCache) FindDir(ctx context.Context, path string, create bool) (pathID string, err error) { dc.mu.Lock() defer dc.mu.Unlock() + err = dc._findRoot(ctx, create) + if err != nil { + return "", err + } return dc._findDir(ctx, path, create) } -// Look for the root and in the cache - safe to call without the mu -func (dc *DirCache) _findDirInCache(path string) string { - // fmt.Println("Finding",path,"create",create,"cache",cache) +// Unlocked findDir +// +// Call with a lock on mu +func (dc *DirCache) _findDir(ctx context.Context, path string, create bool) (pathID string, err error) { // If it is the root, then return it if path == "" { - // fmt.Println("Root") - return dc.rootID + return dc.rootID, nil } // If it is in the cache then return it pathID, ok := dc.Get(path) if ok { - // fmt.Println("Cache hit on", path) - return pathID - } - - return "" -} - -// Unlocked findDir - must have mu -func (dc *DirCache) _findDir(ctx context.Context, path string, create bool) (pathID string, err error) { - pathID = dc._findDirInCache(path) - if pathID != "" { return pathID, nil } @@ -232,29 +242,48 @@ func (dc *DirCache) _findDir(ctx context.Context, path string, create bool) (pat // FindPath finds the leaf and directoryID from a path // -// Do not call FindPath with the root directory - it will return an error +// If called with path == "" then it will return the ID of the parent +// directory of the root and the leaf name of the root in that +// directory. Note that it won't create the root directory in this +// case even if create is true. // // If create is set parent directories will be created if they don't exist +// +// It will call FindRoot if it hasn't been called already func (dc *DirCache) FindPath(ctx context.Context, path string, create bool) (leaf, directoryID string, err error) { if path == "" { - err = errors.New("internal error: can't call FindPath with root directory") - return + _, leaf = SplitPath(dc.root) + directoryID, err = dc.RootParentID(ctx, create) + } else { + var directory string + directory, leaf = SplitPath(path) + directoryID, err = dc.FindDir(ctx, directory, create) } - dc.mu.Lock() - defer dc.mu.Unlock() - directory, leaf := SplitPath(path) - directoryID, err = dc._findDir(ctx, directory, create) - return + return leaf, directoryID, err } // FindRoot finds the root directory if not already found // +// If successful this changes the root of the cache from the true root +// to the root specified by the path passed into New. +// // Resets the root directory // // If create is set it will make the directory if not found func (dc *DirCache) FindRoot(ctx context.Context, create bool) error { dc.mu.Lock() defer dc.mu.Unlock() + return dc._findRoot(ctx, create) +} + +// _findRoot finds the root directory if not already found +// +// Resets the root directory +// +// If create is set it will make the directory if not found +// +// Call with mu held +func (dc *DirCache) _findRoot(ctx context.Context, create bool) error { if dc.foundRoot { return nil } @@ -277,51 +306,51 @@ func (dc *DirCache) FindRoot(ctx context.Context, create bool) error { return nil } -// FindRootAndPath finds the root first if not found then finds leaf and directoryID from a path -// -// If create is set parent directories will be created if they don't exist -func (dc *DirCache) FindRootAndPath(ctx context.Context, path string, create bool) (leaf, directoryID string, err error) { - err = dc.FindRoot(ctx, create) - if err != nil { - return - } - return dc.FindPath(ctx, path, create) -} - // FoundRoot returns whether the root directory has been found yet -// -// Call this from FindLeaf or CreateDir only func (dc *DirCache) FoundRoot() bool { + dc.mu.Lock() + defer dc.mu.Unlock() return dc.foundRoot } // RootID returns the ID of the root directory // -// This should be called after FindRoot -func (dc *DirCache) RootID() string { +// If create is set it will make the root directory if not found +func (dc *DirCache) RootID(ctx context.Context, create bool) (ID string, err error) { dc.mu.Lock() defer dc.mu.Unlock() - if !dc.foundRoot { - log.Fatalf("Internal Error: RootID() called before FindRoot") + err = dc._findRoot(ctx, create) + if err != nil { + return "", err } - return dc.rootID + return dc.rootID, nil } // RootParentID returns the ID of the parent of the root directory // -// This should be called after FindRoot -func (dc *DirCache) RootParentID() (string, error) { +// If create is set it will make the root parent directory if not found (but not the root) +func (dc *DirCache) RootParentID(ctx context.Context, create bool) (ID string, err error) { dc.mu.Lock() defer dc.mu.Unlock() if !dc.foundRoot { - return "", errors.New("internal error: RootID() called before FindRoot") + if dc.root == "" { + return "", errors.New("is root directory") + } + // Find the rootParentID without creating the root + rootParent, _ := SplitPath(dc.root) + rootParentID, err := dc._findDir(ctx, rootParent, create) + if err != nil { + return "", err + } + dc.rootParentID = rootParentID + } else { + if dc.rootID == dc.trueRootID { + return "", errors.New("is root directory") + } } if dc.rootParentID == "" { return "", errors.New("internal error: didn't find rootParentID") } - if dc.rootID == dc.trueRootID { - return "", errors.New("is root directory") - } return dc.rootParentID, nil }