You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
4.3 KiB

8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
4 years ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
  1. package filer
  2. import (
  3. "context"
  4. "github.com/seaweedfs/seaweedfs/weed/glog"
  5. "github.com/seaweedfs/seaweedfs/weed/util"
  6. "math"
  7. "path/filepath"
  8. "strings"
  9. )
  10. func splitPattern(pattern string) (prefix string, restPattern string) {
  11. position := strings.Index(pattern, "*")
  12. if position >= 0 {
  13. return pattern[:position], pattern[position:]
  14. }
  15. position = strings.Index(pattern, "?")
  16. if position >= 0 {
  17. return pattern[:position], pattern[position:]
  18. }
  19. return "", restPattern
  20. }
  21. // For now, prefix and namePattern are mutually exclusive
  22. func (f *Filer) ListDirectoryEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int64, prefix string, namePattern string, namePatternExclude string) (entries []*Entry, hasMore bool, err error) {
  23. if limit > math.MaxInt32-1 {
  24. limit = math.MaxInt32 - 1
  25. }
  26. _, err = f.StreamListDirectoryEntries(ctx, p, startFileName, inclusive, false, false, limit+1, prefix, namePattern, namePatternExclude, func(entry *Entry) bool {
  27. entries = append(entries, entry)
  28. return true
  29. })
  30. hasMore = int64(len(entries)) >= limit+1
  31. if hasMore {
  32. entries = entries[:limit]
  33. }
  34. return entries, hasMore, err
  35. }
  36. // For now, prefix and namePattern are mutually exclusive
  37. func (f *Filer) StreamListDirectoryEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, recursive bool, delimiter bool, limit int64, prefix string, namePattern string, namePatternExclude string, eachEntryFunc ListEachEntryFunc) (lastFileName string, err error) {
  38. glog.V(5).Infof("StreamListDirectoryEntries p %v startFileName %s prefix %s namePattern %v, recursive %v", p, startFileName, prefix, namePattern, recursive)
  39. if strings.HasSuffix(string(p), "/") && len(p) > 1 {
  40. p = p[0 : len(p)-1]
  41. }
  42. prefixInNamePattern, restNamePattern := splitPattern(namePattern)
  43. if prefixInNamePattern != "" {
  44. prefix = prefixInNamePattern
  45. }
  46. var missedCount int64
  47. missedCount, lastFileName, err = f.doListPatternMatchedEntries(ctx, p, startFileName, inclusive, recursive, delimiter, limit, prefix, restNamePattern, namePatternExclude, eachEntryFunc)
  48. for missedCount > 0 && err == nil {
  49. missedCount, lastFileName, err = f.doListPatternMatchedEntries(ctx, p, lastFileName, false, recursive, delimiter, missedCount, prefix, restNamePattern, namePatternExclude, eachEntryFunc)
  50. }
  51. return
  52. }
  53. func (f *Filer) doListPatternMatchedEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, recursive bool, delimiter bool, limit int64, prefix, restNamePattern string, namePatternExclude string, eachEntryFunc ListEachEntryFunc) (missedCount int64, lastFileName string, err error) {
  54. glog.V(5).Infof("doListPatternMatchedEntries startFileName %v, recursive %v", startFileName, recursive)
  55. if len(restNamePattern) == 0 && len(namePatternExclude) == 0 {
  56. lastFileName, err = f.doListValidEntries(ctx, p, startFileName, inclusive, recursive, delimiter, limit, prefix, eachEntryFunc)
  57. return 0, lastFileName, err
  58. }
  59. lastFileName, err = f.doListValidEntries(ctx, p, startFileName, inclusive, recursive, delimiter, limit, prefix, func(entry *Entry) bool {
  60. nameToTest := entry.Name()
  61. if len(namePatternExclude) > 0 {
  62. if matched, matchErr := filepath.Match(namePatternExclude, nameToTest); matchErr == nil && matched {
  63. missedCount++
  64. return true
  65. }
  66. }
  67. if len(restNamePattern) > 0 {
  68. if matched, matchErr := filepath.Match(restNamePattern, nameToTest[len(prefix):]); matchErr == nil && !matched {
  69. missedCount++
  70. return true
  71. }
  72. }
  73. if !eachEntryFunc(entry) {
  74. return false
  75. }
  76. return true
  77. })
  78. if err != nil {
  79. return
  80. }
  81. return
  82. }
  83. func (f *Filer) doListValidEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, recursive bool, delimiter bool, limit int64, prefix string, eachEntryFunc ListEachEntryFunc) (lastFileName string, err error) {
  84. glog.V(5).Infof("doListValidEntries p %v startFileName %v, recursive %v", p, startFileName, recursive)
  85. var expiredCount int64
  86. expiredCount, lastFileName, err = f.doListDirectoryEntries(ctx, p, startFileName, inclusive, recursive, delimiter, limit, prefix, eachEntryFunc)
  87. for expiredCount > 0 && err == nil {
  88. expiredCount, lastFileName, err = f.doListDirectoryEntries(ctx, p, lastFileName, false, recursive, delimiter, expiredCount, prefix, eachEntryFunc)
  89. }
  90. return
  91. }