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.

80 lines
2.7 KiB

  1. package filer
  2. import (
  3. "context"
  4. "github.com/chrislusf/seaweedfs/weed/util"
  5. "path/filepath"
  6. "strings"
  7. )
  8. func splitPattern(pattern string) (prefix string, restPattern string) {
  9. position := strings.Index(pattern, "*")
  10. if position >= 0 {
  11. return pattern[:position], pattern[position:]
  12. }
  13. position = strings.Index(pattern, "?")
  14. if position >= 0 {
  15. return pattern[:position], pattern[position:]
  16. }
  17. return "", restPattern
  18. }
  19. // For now, prefix and namePattern are mutually exclusive
  20. func (f *Filer) ListDirectoryEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, prefix string, namePattern string) (entries []*Entry, err error) {
  21. if strings.HasSuffix(string(p), "/") && len(p) > 1 {
  22. p = p[0 : len(p)-1]
  23. }
  24. prefixInNamePattern, restNamePattern := splitPattern(namePattern)
  25. if prefixInNamePattern != "" {
  26. prefix = prefixInNamePattern
  27. }
  28. var missedCount int
  29. var lastFileName string
  30. entries, missedCount, lastFileName, err = f.doListPatternMatchedEntries(ctx, p, startFileName, inclusive, limit, prefix, restNamePattern)
  31. for missedCount > 0 && err == nil {
  32. var makeupEntries []*Entry
  33. makeupEntries, missedCount, lastFileName, err = f.doListPatternMatchedEntries(ctx, p, lastFileName, false, missedCount, prefix, restNamePattern)
  34. for _, entry := range makeupEntries {
  35. entries = append(entries, entry)
  36. }
  37. }
  38. return entries, err
  39. }
  40. func (f *Filer) doListPatternMatchedEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, prefix, restNamePattern string) (matchedEntries []*Entry, missedCount int, lastFileName string, err error) {
  41. var foundEntries []*Entry
  42. foundEntries, lastFileName, err = f.doListValidEntries(ctx, p, startFileName, inclusive, limit, prefix)
  43. if err != nil {
  44. return
  45. }
  46. if len(restNamePattern) == 0 {
  47. return foundEntries, 0, lastFileName, nil
  48. }
  49. for _, entry := range foundEntries {
  50. nameToTest := strings.ToLower(entry.Name())
  51. if matched, matchErr := filepath.Match(restNamePattern, nameToTest[len(prefix):]); matchErr == nil && matched {
  52. matchedEntries = append(matchedEntries, entry)
  53. } else {
  54. missedCount++
  55. }
  56. }
  57. return
  58. }
  59. func (f *Filer) doListValidEntries(ctx context.Context, p util.FullPath, startFileName string, inclusive bool, limit int, prefix string) (entries []*Entry, lastFileName string, err error) {
  60. var makeupEntries []*Entry
  61. var expiredCount int
  62. entries, expiredCount, lastFileName, err = f.doListDirectoryEntries(ctx, p, startFileName, inclusive, limit, prefix)
  63. for expiredCount > 0 && err == nil {
  64. makeupEntries, expiredCount, lastFileName, err = f.doListDirectoryEntries(ctx, p, lastFileName, false, expiredCount, prefix)
  65. if err == nil {
  66. entries = append(entries, makeupEntries...)
  67. }
  68. }
  69. return
  70. }