s3api: reuse prefetched entry in versioned DELETE operations

Update deleteSpecificObjectVersion() to accept an optional prefetchedEntry
parameter. When the entry was already fetched by enforceObjectLockProtections(),
it is now passed through to avoid a duplicate filer lookup.

This optimization applies to:
- DELETE specific version (versionId specified)
- DELETE null version (suspended versioning)
- DeleteMultipleObjects for versioned buckets

Performance impact:
- Versioned DELETE: reduces filer lookups from 2 to 1 (50% reduction)
- Non-versioned DELETE: no change (requires gRPC protocol changes)
This commit is contained in:
chrislu committed 2025-12-05 20:58:58 -08:00
1 parent eb6a56b6c6
commit acd7f1a4d5
2 files changed
+31 -17

No files matched your search

+12 -8
View File
@@ -637,8 +637,10 @@ func (s3a *S3ApiServer) getSpecificObjectVersion(bucket, object, versionId strin
return entry, nil
}
// deleteSpecificObjectVersion deletes a specific version of an object
func (s3a *S3ApiServer) deleteSpecificObjectVersion(bucket, object, versionId string) error {
// deleteSpecificObjectVersion deletes a specific version of an object.
// The optional prefetchedEntry parameter allows callers to pass an already-fetched entry
// to avoid duplicate filer lookups (optimization for DELETE operations).
func (s3a *S3ApiServer) deleteSpecificObjectVersion(bucket, object, versionId string, prefetchedEntry *filer_pb.Entry) error {
// Normalize object path to ensure consistency with toFilerPath behavior
normalizedObject := removeDuplicateSlashes(object)
@@ -651,12 +653,14 @@ func (s3a *S3ApiServer) deleteSpecificObjectVersion(bucket, object, versionId st
bucketDir := s3a.option.BucketsPath + "/" + bucket
cleanObject := strings.TrimPrefix(normalizedObject, "/")
// Check if the object exists
_, err := s3a.getEntry(bucketDir, cleanObject)
if err != nil {
// Object doesn't exist - this is OK for delete operations (idempotent)
glog.V(2).Infof("deleteSpecificObjectVersion: null version object %s already deleted or doesn't exist", cleanObject)
return nil
// Check if the object exists (skip if we have a prefetched entry)
if prefetchedEntry == nil {
_, err := s3a.getEntry(bucketDir, cleanObject)
if err != nil {
// Object doesn't exist - this is OK for delete operations (idempotent)
glog.V(2).Infof("deleteSpecificObjectVersion: null version object %s already deleted or doesn't exist", cleanObject)
return nil
}
}
// Delete the regular file