mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-03 06:37:09 +00:00
more comments
This commit is contained in:
@@ -215,6 +215,7 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h
|
||||
var deleteErrors []DeleteError
|
||||
var auditLog *s3err.AccessLog
|
||||
|
||||
// Track directories with deletions for batch cleanup optimization
|
||||
directoriesWithDeletion := make(map[string]bool)
|
||||
|
||||
if s3err.Logger != nil {
|
||||
@@ -339,7 +340,7 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
// Handle non-versioned delete (original logic)
|
||||
// Handle non-versioned delete (defer cleanup for batch optimization)
|
||||
lastSeparator := strings.LastIndex(object.Key, "/")
|
||||
parentDirectoryPath, entryName, isDeleteData, isRecursive := "", object.Key, true, false
|
||||
if lastSeparator > 0 && lastSeparator+1 < len(object.Key) {
|
||||
@@ -348,10 +349,11 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h
|
||||
}
|
||||
parentDirectoryPath = fmt.Sprintf("%s/%s%s", s3a.option.BucketsPath, bucket, parentDirectoryPath)
|
||||
|
||||
// Delete file without cleanup (batch cleanup at the end for efficiency)
|
||||
err := filer_pb.DoRemove(opCtx, client, parentDirectoryPath, entryName, isDeleteData, isRecursive, true, false, nil, false, "")
|
||||
if err == nil {
|
||||
// Track directory for empty directory cleanup
|
||||
if !s3a.option.AllowEmptyFolder {
|
||||
// Track directory for batch cleanup
|
||||
if !s3a.option.AllowEmptyFolder && lastSeparator > 0 {
|
||||
directoriesWithDeletion[parentDirectoryPath] = true
|
||||
}
|
||||
deletedObjects = append(deletedObjects, object)
|
||||
@@ -373,26 +375,29 @@ func (s3a *S3ApiServer) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *h
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup empty directories - optimize by processing deepest first
|
||||
// Batch cleanup: Process empty directories after all deletions
|
||||
// This is much more efficient than checking after each deletion
|
||||
if !s3a.option.AllowEmptyFolder && len(directoriesWithDeletion) > 0 {
|
||||
bucketPath := fmt.Sprintf("%s/%s", s3a.option.BucketsPath, bucket)
|
||||
|
||||
// Collect and sort directories by depth (deepest first) to avoid redundant checks
|
||||
// Sort directories by depth (deepest first) to avoid redundant checks
|
||||
// Deeper directories are more likely to be empty and cleaning them first
|
||||
// may make their parents empty, reducing total checks needed
|
||||
var allDirs []string
|
||||
for dirPath := range directoriesWithDeletion {
|
||||
allDirs = append(allDirs, dirPath)
|
||||
}
|
||||
// Sort by depth (deeper directories first)
|
||||
slices.SortFunc(allDirs, func(a, b string) int {
|
||||
return strings.Count(b, "/") - strings.Count(a, "/")
|
||||
})
|
||||
|
||||
// Track already-checked directories to avoid redundant work
|
||||
// When we check a directory and recursively clean parents,
|
||||
// mark them all as checked so we skip them in subsequent iterations
|
||||
checked := make(map[string]bool)
|
||||
for _, dirPath := range allDirs {
|
||||
if !checked[dirPath] {
|
||||
// Recursively delete empty parent directories, stop at bucket path
|
||||
// Mark this directory and all its parents as checked during recursion
|
||||
// Use server-side cleanup for consistency
|
||||
filer_pb.DoDeleteEmptyParentDirectories(opCtx, client, util.FullPath(dirPath), util.FullPath(bucketPath), checked)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user