From e9d820192587e6ae01d7183f99b898953f192cf7 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Thu, 28 Jan 2021 13:20:06 -0800 Subject: [PATCH] s3: batch purge empty folders --- weed/s3api/s3api_object_handlers.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go index 401e2f96c..e8c1b59d7 100644 --- a/weed/s3api/s3api_object_handlers.go +++ b/weed/s3api/s3api_object_handlers.go @@ -175,16 +175,15 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h var deletedObjects []ObjectIdentifier var deleteErrors []DeleteError + directoriesWithDeletion := make(map[string]int) + s3a.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { + // delete file entries for _, object := range deleteObjects.Objects { - response, _ := s3a.listFilerEntries(bucket, object.ObjectName, 1, "", "/") - if len(response.Contents) != 0 && strings.HasSuffix(object.ObjectName, "/") { - continue - } lastSeparator := strings.LastIndex(object.ObjectName, "/") - parentDirectoryPath, entryName, isDeleteData, isRecursive := "/", object.ObjectName, true, true + parentDirectoryPath, entryName, isDeleteData, isRecursive := "/", object.ObjectName, true, false if lastSeparator > 0 && lastSeparator+1 < len(object.ObjectName) { entryName = object.ObjectName[lastSeparator+1:] parentDirectoryPath = "/" + object.ObjectName[:lastSeparator] @@ -193,8 +192,10 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h err := doDeleteEntry(client, parentDirectoryPath, entryName, isDeleteData, isRecursive) if err == nil { + directoriesWithDeletion[parentDirectoryPath]++ deletedObjects = append(deletedObjects, object) } else { + delete(directoriesWithDeletion, parentDirectoryPath) deleteErrors = append(deleteErrors, DeleteError{ Code: "", Message: err.Error(), @@ -202,6 +203,15 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h }) } } + + // purge empty folders, only checking folders with deletions + for dir, deletionCount := range directoriesWithDeletion { + parentDir, dirName := util.FullPath(dir).DirAndName() + if err := doDeleteEntry(client, parentDir, dirName, false, false); err != nil { + glog.V(4).Infof("directory %s has %d deletion but still not empty: %v", dir, deletionCount, err) + } + } + return nil })