cleanup: refactor common code between FS and XL listDirFactory. (#3639)

This commit is contained in:
Krishna Srinivas 2017-01-26 15:39:22 -08:00 committed by Harshavardhana
parent 8e49a3d047
commit 17dd1c19df
3 changed files with 54 additions and 75 deletions

View File

@ -731,38 +731,12 @@ func (fs fsObjects) listDirFactory(isLeaf isLeafFunc) listDirFunc {
// listDir - lists all the entries at a given prefix and given entry in the prefix. // listDir - lists all the entries at a given prefix and given entry in the prefix.
listDir := func(bucket, prefixDir, prefixEntry string) (entries []string, delayIsLeaf bool, err error) { listDir := func(bucket, prefixDir, prefixEntry string) (entries []string, delayIsLeaf bool, err error) {
entries, err = readDir(pathJoin(fs.fsPath, bucket, prefixDir)) entries, err = readDir(pathJoin(fs.fsPath, bucket, prefixDir))
if err == nil { if err != nil {
// Listing needs to be sorted.
sort.Strings(entries)
// Filter entries that have the prefix prefixEntry.
entries = filterMatchingPrefix(entries, prefixEntry)
// Can isLeaf() check be delayed till when it has to be sent down the
// treeWalkResult channel?
delayIsLeaf = delayIsLeafCheck(entries)
if delayIsLeaf {
return entries, delayIsLeaf, nil
}
// isLeaf() check has to happen here so that trailing "/" for objects can be removed.
for i, entry := range entries {
if isLeaf(bucket, pathJoin(prefixDir, entry)) {
entries[i] = strings.TrimSuffix(entry, slashSeparator)
}
}
// Sort again after removing trailing "/" for objects as the previous sort
// does not hold good anymore.
sort.Strings(entries)
// Succes.
return entries, delayIsLeaf, nil
} // Return error at the end.
// Error.
return nil, false, err return nil, false, err
} }
entries, delayIsLeaf = filterListEntries(bucket, prefixDir, entries, prefixEntry, isLeaf)
return entries, delayIsLeaf, nil
}
// Return list factory instance. // Return list factory instance.
return listDir return listDir

View File

@ -95,18 +95,7 @@ type listDirFunc func(bucket, prefixDir, prefixEntry string) (entries []string,
// 4. XL backend multipart listing - isLeaf is true if the entry is a directory and contains uploads.json // 4. XL backend multipart listing - isLeaf is true if the entry is a directory and contains uploads.json
type isLeafFunc func(string, string) bool type isLeafFunc func(string, string) bool
// Returns function "listDir" of the type listDirFunc. func filterListEntries(bucket, prefixDir string, entries []string, prefixEntry string, isLeaf isLeafFunc) ([]string, bool) {
// isLeaf - is used by listDir function to check if an entry is a leaf or non-leaf entry.
// disks - used for doing disk.ListDir(). FS passes single disk argument, XL passes a list of disks.
func listDirFactory(isLeaf isLeafFunc, treeWalkIgnoredErrs []error, disks ...StorageAPI) listDirFunc {
// listDir - lists all the entries at a given prefix and given entry in the prefix.
listDir := func(bucket, prefixDir, prefixEntry string) (entries []string, delayIsLeaf bool, err error) {
for _, disk := range disks {
if disk == nil {
continue
}
entries, err = disk.ListDir(bucket, prefixDir)
if err == nil {
// Listing needs to be sorted. // Listing needs to be sorted.
sort.Strings(entries) sort.Strings(entries)
@ -115,9 +104,9 @@ func listDirFactory(isLeaf isLeafFunc, treeWalkIgnoredErrs []error, disks ...Sto
// Can isLeaf() check be delayed till when it has to be sent down the // Can isLeaf() check be delayed till when it has to be sent down the
// treeWalkResult channel? // treeWalkResult channel?
delayIsLeaf = delayIsLeafCheck(entries) delayIsLeaf := delayIsLeafCheck(entries)
if delayIsLeaf { if delayIsLeaf {
return entries, delayIsLeaf, nil return entries, true
} }
// isLeaf() check has to happen here so that trailing "/" for objects can be removed. // isLeaf() check has to happen here so that trailing "/" for objects can be removed.
@ -129,19 +118,7 @@ func listDirFactory(isLeaf isLeafFunc, treeWalkIgnoredErrs []error, disks ...Sto
// Sort again after removing trailing "/" for objects as the previous sort // Sort again after removing trailing "/" for objects as the previous sort
// does not hold good anymore. // does not hold good anymore.
sort.Strings(entries) sort.Strings(entries)
return entries, delayIsLeaf, nil return entries, false
}
// For any reason disk was deleted or goes offline, continue
// and list from other disks if possible.
if isErrIgnored(err, treeWalkIgnoredErrs...) {
continue
}
break
}
// Return error at the end.
return nil, false, traceError(err)
}
return listDir
} }
// treeWalk walks directory tree recursively pushing treeWalkResult into the channel as and when it encounters files. // treeWalk walks directory tree recursively pushing treeWalkResult into the channel as and when it encounters files.

View File

@ -18,6 +18,34 @@ package cmd
import "strings" import "strings"
// Returns function "listDir" of the type listDirFunc.
// isLeaf - is used by listDir function to check if an entry is a leaf or non-leaf entry.
// disks - used for doing disk.ListDir(). FS passes single disk argument, XL passes a list of disks.
func listDirFactory(isLeaf isLeafFunc, treeWalkIgnoredErrs []error, disks ...StorageAPI) listDirFunc {
// listDir - lists all the entries at a given prefix and given entry in the prefix.
listDir := func(bucket, prefixDir, prefixEntry string) (entries []string, delayIsLeaf bool, err error) {
for _, disk := range disks {
if disk == nil {
continue
}
entries, err = disk.ListDir(bucket, prefixDir)
if err == nil {
entries, delayIsLeaf = filterListEntries(bucket, prefixDir, entries, prefixEntry, isLeaf)
return entries, delayIsLeaf, nil
}
// For any reason disk was deleted or goes offline, continue
// and list from other disks if possible.
if isErrIgnored(err, treeWalkIgnoredErrs...) {
continue
}
break
}
// Return error at the end.
return nil, false, traceError(err)
}
return listDir
}
// listObjects - wrapper function implemented over file tree walk. // listObjects - wrapper function implemented over file tree walk.
func (xl xlObjects) listObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) { func (xl xlObjects) listObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) {
// Default is recursive, if delimiter is set then list non recursive. // Default is recursive, if delimiter is set then list non recursive.