mirror of
https://github.com/pgsty/minio.git
synced 2026-07-20 04:30:26 +03:00
metacache: Allow prefix filtering (#10920)
Do listings with prefix filter when bloom filter is dirty. This will forward the prefix filter to the lister which will make it only scan the folders/objects with the specified prefix. If we have a clean bloom filter we try to build a more generally useful cache so in that case, we will list all objects/folders.
This commit is contained in:
+17
-1
@@ -42,6 +42,10 @@ type WalkDirOptions struct {
|
||||
|
||||
// Do a full recursive scan.
|
||||
Recursive bool
|
||||
|
||||
// FilterPrefix will only return results with given prefix within folder.
|
||||
// Should never contain a slash.
|
||||
FilterPrefix string
|
||||
}
|
||||
|
||||
// WalkDir will traverse a directory and return all entries found.
|
||||
@@ -85,6 +89,7 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
}
|
||||
defer close(out)
|
||||
|
||||
prefix := opts.FilterPrefix
|
||||
var scanDir func(path string) error
|
||||
scanDir = func(current string) error {
|
||||
entries, err := s.ListDir(ctx, opts.Bucket, current, -1)
|
||||
@@ -98,6 +103,9 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
}
|
||||
dirObjects := make(map[string]struct{})
|
||||
for i, entry := range entries {
|
||||
if len(prefix) > 0 && !strings.HasPrefix(entry, prefix) {
|
||||
continue
|
||||
}
|
||||
if strings.HasSuffix(entry, slashSeparator) {
|
||||
if strings.HasSuffix(entry, globalDirSuffixWithSlash) {
|
||||
// Add without extension so it is sorted correctly.
|
||||
@@ -148,6 +156,7 @@ func (s *xlStorage) WalkDir(ctx context.Context, opts WalkDirOptions, wr io.Writ
|
||||
// Process in sort order.
|
||||
sort.Strings(entries)
|
||||
dirStack := make([]string, 0, 5)
|
||||
prefix = "" // Remove prefix after first level.
|
||||
for _, entry := range entries {
|
||||
if entry == "" {
|
||||
continue
|
||||
@@ -232,6 +241,7 @@ func (client *storageRESTClient) WalkDir(ctx context.Context, opts WalkDirOption
|
||||
values.Set(storageRESTVolume, opts.Bucket)
|
||||
values.Set(storageRESTDirPath, opts.BaseDir)
|
||||
values.Set(storageRESTRecursive, strconv.FormatBool(opts.Recursive))
|
||||
values.Set(storageRESTPrefixFilter, opts.FilterPrefix)
|
||||
respBody, err := client.call(ctx, storageRESTMethodWalkDir, values, nil, -1)
|
||||
if err != nil {
|
||||
logger.LogIf(ctx, err)
|
||||
@@ -248,11 +258,17 @@ func (s *storageRESTServer) WalkDirHandler(w http.ResponseWriter, r *http.Reques
|
||||
vars := mux.Vars(r)
|
||||
volume := vars[storageRESTVolume]
|
||||
dirPath := vars[storageRESTDirPath]
|
||||
prefix := vars[storageRESTPrefixFilter]
|
||||
recursive, err := strconv.ParseBool(vars[storageRESTRecursive])
|
||||
if err != nil {
|
||||
s.writeErrorResponse(w, err)
|
||||
return
|
||||
}
|
||||
writer := streamHTTPResponse(w)
|
||||
writer.CloseWithError(s.storage.WalkDir(r.Context(), WalkDirOptions{Bucket: volume, BaseDir: dirPath, Recursive: recursive}, writer))
|
||||
writer.CloseWithError(s.storage.WalkDir(r.Context(), WalkDirOptions{
|
||||
Bucket: volume,
|
||||
BaseDir: dirPath,
|
||||
Recursive: recursive,
|
||||
FilterPrefix: prefix,
|
||||
}, writer))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user