From c188bdf426011a68f0b1158f0f7af08bf470cfb4 Mon Sep 17 00:00:00 2001 From: ermahesh Date: Fri, 4 Sep 2026 13:30:27 -0500 Subject: [PATCH 1/3] HDDS-16375. Apply fileSize filter independently in Recon fileCount endpoint The scan branch of UtilizationEndpoint#getFileCounts filtered only on volume and bucket, so the fileSize query parameter was silently ignored for every combination except volume + bucket + fileSize. Callers got an unfiltered list that looked like a filtered one, with no error or warning. Apply the fileSize filter in the scan branch as well, matching the behaviour already documented in ReconApi.md. The comparison is against the exact bin upper bound, consistent with the point-get branch which uses the raw value as the RocksDB key. --- .../ozone/recon/api/UtilizationEndpoint.java | 5 +++- .../hadoop/ozone/recon/api/TestEndpoints.java | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java index 5a19890d3dcf..877a89cb2901 100644 --- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java +++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java @@ -116,7 +116,10 @@ public Response getFileCounts( if (bucket != null && !bucket.equals(key.getBucket())) { matches = false; } - + if (fileSize > 0 && !Long.valueOf(fileSize).equals(key.getFileSizeUpperBound())) { + matches = false; + } + if (matches && count != null && count > 0) { FileCountBySize record = new FileCountBySize(); record.setVolume(key.getVolume()); diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java index db9301e4795e..638495b2eb70 100644 --- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java +++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java @@ -952,6 +952,32 @@ public void testGetFileCounts() throws Exception { resultSet = (List) response.getEntity(); assertEquals(0, resultSet.size()); + // Test for "fileSize" query param on its own. + response = utilizationEndpoint.getFileCounts(null, null, 131072); + resultSet = (List) response.getEntity(); + assertEquals(1, resultSet.size()); + assertTrue(resultSet.stream().allMatch(o -> o.getVolume().equals("vol1") && + o.getBucket().equals("bucket1") && o.getFileSize() == 131072L)); + + // Test for "volume" + "fileSize" query params, without bucket. + response = utilizationEndpoint.getFileCounts("vol1", null, 131072); + resultSet = (List) response.getEntity(); + assertEquals(1, resultSet.size()); + assertTrue(resultSet.stream().allMatch(o -> o.getVolume().equals("vol1") && + o.getFileSize() == 131072L)); + + // Test for "bucket" + "fileSize" query params, without volume. + response = utilizationEndpoint.getFileCounts(null, "bucket1", 1024); + resultSet = (List) response.getEntity(); + assertEquals(2, resultSet.size()); + assertTrue(resultSet.stream().allMatch(o -> o.getBucket().equals("bucket1") && + o.getFileSize() == 1024L)); + + // Test for a fileSize that is not a bin upper bound, without volume and bucket. + response = utilizationEndpoint.getFileCounts(null, null, 1310725); + resultSet = (List) response.getEntity(); + assertEquals(0, resultSet.size()); + // Test for "volume" + "bucket" + "fileSize" query params. response = utilizationEndpoint.getFileCounts("vol1", "bucket1", 131072); resultSet = (List) response.getEntity(); From 44e641a061f6776c67a921ae95e9fb77cf95fdc4 Mon Sep 17 00:00:00 2001 From: ermahesh Date: Fri, 4 Sep 2026 13:56:40 -0500 Subject: [PATCH 2/3] HDDS-16375. Extract fileCount endpoint assertions to keep testGetFileCounts under the method length limit The added filter coverage pushed testGetFileCounts to 162 lines, over the Checkstyle MethodLength default of 150. Move the endpoint query assertions, which were already a self-contained block, into a private helper. No change to what is asserted. --- .../org/apache/hadoop/ozone/recon/api/TestEndpoints.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java index 638495b2eb70..0d869a3b64ce 100644 --- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java +++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java @@ -915,6 +915,15 @@ public void testGetFileCounts() throws Exception { assertEquals(2L, rocksCount3.longValue(), "Expected RocksDB bin 1024 to have count 2 for vol2/bucket1"); // --- Now test the query endpoints of the utilization service --- + verifyFileCountQueries(); + } + + /** + * Verify the filtering behaviour of the fileCount endpoint against the + * bins written by {@link #testGetFileCounts()}: vol1/bucket1:1024, + * vol1/bucket1:131072 and vol2/bucket1:1024, each with count 2. + */ + private void verifyFileCountQueries() { Response response = utilizationEndpoint.getFileCounts(null, null, 0); List resultSet = (List) response.getEntity(); From 4b9fd51d5f9646b85390b4985d828d194a561440 Mon Sep 17 00:00:00 2001 From: ermahesh Date: Fri, 4 Sep 2026 16:09:28 -0500 Subject: [PATCH 3/3] HDDS-16375. Compare fileSize as a primitive to avoid boxing in the scan loop Long.valueOf(fileSize).equals(...) allocated a Long per scanned row for values outside the Integer cache, and went through equals(Object). Comparing the primitive fileSize against the unboxed bin upper bound is allocation-free. FileSizeCountKey#getFileSizeUpperBound is never null for keys decoded from the table, since fromProto reads a proto int64; the class's own equals and hashCode already rely on that. --- .../org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java index 877a89cb2901..5800f0032054 100644 --- a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java +++ b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/api/UtilizationEndpoint.java @@ -116,7 +116,7 @@ public Response getFileCounts( if (bucket != null && !bucket.equals(key.getBucket())) { matches = false; } - if (fileSize > 0 && !Long.valueOf(fileSize).equals(key.getFileSizeUpperBound())) { + if (fileSize > 0 && fileSize != key.getFileSizeUpperBound()) { matches = false; }