This is an automated email from the ASF dual-hosted git repository.

chihsuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 684b6b9917c HDDS-16748. Avoid repeated delimiter searches in S3 object 
listings (#11459)
684b6b9917c is described below

commit 684b6b9917c80bdbe418478d1d739de48d124904
Author: KUAN-HAO HUANG <[email protected]>
AuthorDate: Sat Oct 10 19:15:40 2026 +0800

    HDDS-16748. Avoid repeated delimiter searches in S3 object listings (#11459)
---
 .../hadoop/ozone/s3/endpoint/BucketEndpoint.java   |  7 +++----
 .../hadoop/ozone/s3/endpoint/TestBucketList.java   | 23 ++++++++++++++++++++++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
index 298ee53e8a7..3688a012c3f 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
@@ -190,13 +190,12 @@ Response handleGetRequest(S3RequestContext context, 
String bucketName) throws IO
           }
           String relativeKeyName = next.getName().substring(prefix.length());
 
-          int depth = StringUtils.countMatches(relativeKeyName, delimiter);
           if (!StringUtils.isEmpty(delimiter)) {
-            if (depth > 0) {
+            int delimiterIndex = relativeKeyName.indexOf(delimiter);
+            if (delimiterIndex >= 0) {
               // means key has multiple delimiters in its value.
               // ex: dir/dir1/dir2, where delimiter is "/" and prefix is dir/
-              String dirName = relativeKeyName.substring(0, relativeKeyName
-                  .indexOf(delimiter));
+              String dirName = relativeKeyName.substring(0, delimiterIndex);
               if (!dirName.equals(prevDir)) {
                 response.addPrefix(EncodingTypeObject.createNullable(
                     prefix + dirName + delimiter, encodingType));
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketList.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketList.java
index d16ef557bff..879cc64c08b 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketList.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketList.java
@@ -706,6 +706,29 @@ public void 
listObjectOwnerIncludedForListV2WhenFetchOwnerTrue() throws OS3Excep
     assertNotNull(response.getContents().get(0).getOwner());
   }
 
+  @Test
+  public void delimiterScanKeepsLiteralPrefixes() throws Exception {
+    setup("a::one", "a::two", "b::item", "plain");
+    bucketEndpoint.queryParamsForTest().set(QueryParams.DELIMITER, "::");
+    ListObjectResponse response = (ListObjectResponse) 
bucketEndpoint.get(BUCKET_NAME).getEntity();
+    assertEquals(2, response.getCommonPrefixes().size());
+    assertEquals("a::", 
response.getCommonPrefixes().get(0).getPrefix().getName());
+    assertEquals("b::", 
response.getCommonPrefixes().get(1).getPrefix().getName());
+    assertEquals(1, response.getContents().size());
+    assertEquals("plain", response.getContents().get(0).getKey().getName());
+  }
+
+  @Test
+  public void delimiterScanKeepsOverlappingPrefixes() throws Exception {
+    setup("aaa", "aab", "baa");
+    bucketEndpoint.queryParamsForTest().set(QueryParams.DELIMITER, "aa");
+    ListObjectResponse response = (ListObjectResponse) 
bucketEndpoint.get(BUCKET_NAME).getEntity();
+    assertEquals(2, response.getCommonPrefixes().size());
+    assertEquals("aa", 
response.getCommonPrefixes().get(0).getPrefix().getName());
+    assertEquals("baa", 
response.getCommonPrefixes().get(1).getPrefix().getName());
+    assertTrue(response.getContents().isEmpty());
+  }
+
   private void createKeys(OzoneClient ozoneClient, String... keys) throws 
IOException {
     OzoneBucket bucket = ozoneClient.getObjectStore().getS3Bucket(BUCKET_NAME);
     for (String key : keys) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to