You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by "xiangfu0 (via GitHub)" <gi...@apache.org> on 2026/02/15 16:43:02 UTC

[PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

xiangfu0 opened a new pull request, #17706:
URL: https://github.com/apache/pinot/pull/17706

   ## Summary\n- Add batched/streaming SegmentZKMetadata enumeration API in PinotHelixResourceManager via ZKMetadataProvider\n- Add configurable batch size support (default 1000) for retention scanning\n- Migrate heavy controller callsites from list-based getSegmentsZKMetadata(...) to iterative processing where applicable\n\n## Testing\n- Not run (per request).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


Re: [PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

Posted by "Jackie-Jiang (via GitHub)" <gi...@apache.org>.
Jackie-Jiang commented on code in PR #17706:
URL: https://github.com/apache/pinot/pull/17706#discussion_r2819085356


##########
pinot-controller/src/main/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManager.java:
##########
@@ -217,8 +217,8 @@ boolean shouldEnsureConsuming(String tableNameWithType) {
 
   private void runSegmentLevelValidation(TableConfig tableConfig) {
     String realtimeTableName = tableConfig.getTableName();
-
-    List<SegmentZKMetadata> segmentsZKMetadata = _pinotHelixResourceManager.getSegmentsZKMetadata(realtimeTableName);
+    List<SegmentZKMetadata> segmentsZKMetadata = new ArrayList<>();
+    _pinotHelixResourceManager.forEachSegmentsZKMetadata(realtimeTableName, segmentsZKMetadata::add);

Review Comment:
   This is not reducing memory footprint



##########
pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/minion/generator/BaseTaskGenerator.java:
##########
@@ -161,32 +162,58 @@ public int getMaxAttemptsPerTask(String minionTag) {
    * @return the list of segment zk metadata for available segments in the table.
    */
   public List<SegmentZKMetadata> getSegmentsZKMetadataForTable(String tableNameWithType) {
+    return getSegmentsZKMetadataInIdealState(tableNameWithType, null);
+  }
+
+  public List<SegmentZKMetadata> getNonConsumingSegmentsZKMetadataForRealtimeTable(String tableNameWithType) {
     IdealState idealState = _clusterInfoAccessor.getIdealState(tableNameWithType);
+    if (idealState == null) {
+      return new ArrayList<>();
+    }
+    return getSegmentsZKMetadataInIdealState(tableNameWithType, segmentZKMetadata -> {
+      String segmentName = segmentZKMetadata.getSegmentName();
+      Map<String, String> instanceStateMap = idealState.getInstanceStateMap(segmentName);
+      return segmentZKMetadata.getStatus().isCompleted() // skip consuming segments
+          && instanceStateMap != null && !instanceStateMap.containsValue(SegmentStateModel.CONSUMING);
+      // The last check is for an edge case where
+      //   1. SegmentZKMetadata was updated to DONE in segment commit protocol, but
+      //   2. IdealState for the segment was not updated to ONLINE due to some issue in the controller.
+      // We avoid picking up such segments to allow RealtimeSegmentValidationManager to fix them.
+    });
+  }
+
+  private List<SegmentZKMetadata> getSegmentsZKMetadataInIdealState(String tableNameWithType,
+      Predicate<SegmentZKMetadata> segmentMetadataFilter) {
+    IdealState idealState = _clusterInfoAccessor.getIdealState(tableNameWithType);
+    if (idealState == null) {
+      return new ArrayList<>();
+    }
     Set<String> segmentsForTable = idealState.getPartitionSet();
-    List<SegmentZKMetadata> segmentZKMetadataList = _clusterInfoAccessor.getSegmentsZKMetadata(tableNameWithType);
+    if (segmentsForTable == null || segmentsForTable.isEmpty()) {
+      return new ArrayList<>();
+    }
+
     List<SegmentZKMetadata> selectedSegmentZKMetadataList = new ArrayList<>();
-    for (SegmentZKMetadata segmentZKMetadata : segmentZKMetadataList) {
-      if (segmentsForTable.contains(segmentZKMetadata.getSegmentName())) {
+    boolean[] callbackInvoked = new boolean[1];

Review Comment:
   Why do we need to track this?



##########
pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/minion/generator/BaseTaskGenerator.java:
##########
@@ -161,32 +162,58 @@ public int getMaxAttemptsPerTask(String minionTag) {
    * @return the list of segment zk metadata for available segments in the table.
    */
   public List<SegmentZKMetadata> getSegmentsZKMetadataForTable(String tableNameWithType) {
+    return getSegmentsZKMetadataInIdealState(tableNameWithType, null);
+  }
+
+  public List<SegmentZKMetadata> getNonConsumingSegmentsZKMetadataForRealtimeTable(String tableNameWithType) {
     IdealState idealState = _clusterInfoAccessor.getIdealState(tableNameWithType);
+    if (idealState == null) {
+      return new ArrayList<>();
+    }
+    return getSegmentsZKMetadataInIdealState(tableNameWithType, segmentZKMetadata -> {
+      String segmentName = segmentZKMetadata.getSegmentName();
+      Map<String, String> instanceStateMap = idealState.getInstanceStateMap(segmentName);
+      return segmentZKMetadata.getStatus().isCompleted() // skip consuming segments
+          && instanceStateMap != null && !instanceStateMap.containsValue(SegmentStateModel.CONSUMING);
+      // The last check is for an edge case where
+      //   1. SegmentZKMetadata was updated to DONE in segment commit protocol, but
+      //   2. IdealState for the segment was not updated to ONLINE due to some issue in the controller.
+      // We avoid picking up such segments to allow RealtimeSegmentValidationManager to fix them.
+    });
+  }
+
+  private List<SegmentZKMetadata> getSegmentsZKMetadataInIdealState(String tableNameWithType,
+      Predicate<SegmentZKMetadata> segmentMetadataFilter) {
+    IdealState idealState = _clusterInfoAccessor.getIdealState(tableNameWithType);
+    if (idealState == null) {
+      return new ArrayList<>();
+    }
     Set<String> segmentsForTable = idealState.getPartitionSet();
-    List<SegmentZKMetadata> segmentZKMetadataList = _clusterInfoAccessor.getSegmentsZKMetadata(tableNameWithType);
+    if (segmentsForTable == null || segmentsForTable.isEmpty()) {
+      return new ArrayList<>();
+    }
+
     List<SegmentZKMetadata> selectedSegmentZKMetadataList = new ArrayList<>();
-    for (SegmentZKMetadata segmentZKMetadata : segmentZKMetadataList) {
-      if (segmentsForTable.contains(segmentZKMetadata.getSegmentName())) {
+    boolean[] callbackInvoked = new boolean[1];
+    _clusterInfoAccessor.forEachSegmentsZKMetadata(tableNameWithType, segmentZKMetadata -> {
+      callbackInvoked[0] = true;
+      if (segmentsForTable.contains(segmentZKMetadata.getSegmentName())
+          && (segmentMetadataFilter == null || segmentMetadataFilter.test(segmentZKMetadata))) {
         selectedSegmentZKMetadataList.add(segmentZKMetadata);

Review Comment:
   This is not reducing memory footprint



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


Re: [PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

Posted by "xiangfu0 (via GitHub)" <gi...@apache.org>.
xiangfu0 commented on code in PR #17706:
URL: https://github.com/apache/pinot/pull/17706#discussion_r2813257361


##########
pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotSegmentRestletResource.java:
##########
@@ -770,12 +770,9 @@ public Map<String, Map<String, String>> getZookeeperMetadata(
     String tableNameWithType =
         ResourceUtils.getExistingTableNamesWithType(_pinotHelixResourceManager, tableName, tableType, LOGGER).get(0);
     Map<String, Map<String, String>> segmentToMetadataMap = new HashMap<>();
-    List<SegmentZKMetadata> segmentZKMetadataList =
-        _pinotHelixResourceManager.getSegmentsZKMetadata(tableNameWithType);
-
-    for (SegmentZKMetadata segmentZKMetadata : segmentZKMetadataList) {
+    _pinotHelixResourceManager.forEachSegmentsZKMetadata(tableNameWithType, segmentZKMetadata -> {

Review Comment:
   For propertyStore, underlying it's also wrapping a for loop on top of zkclient to call each path to fetch the znRecord then construct the segment metadata.
   
   So there is no difference in terms of the zk overhead.
   
   GetChildren for all segment name is always just one zk call to fetch all.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


Re: [PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

Posted by "krishan1390 (via GitHub)" <gi...@apache.org>.
krishan1390 commented on code in PR #17706:
URL: https://github.com/apache/pinot/pull/17706#discussion_r2811493920


##########
pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotSegmentRestletResource.java:
##########
@@ -770,12 +770,9 @@ public Map<String, Map<String, String>> getZookeeperMetadata(
     String tableNameWithType =
         ResourceUtils.getExistingTableNamesWithType(_pinotHelixResourceManager, tableName, tableType, LOGGER).get(0);
     Map<String, Map<String, String>> segmentToMetadataMap = new HashMap<>();
-    List<SegmentZKMetadata> segmentZKMetadataList =
-        _pinotHelixResourceManager.getSegmentsZKMetadata(tableNameWithType);
-
-    for (SegmentZKMetadata segmentZKMetadata : segmentZKMetadataList) {
+    _pinotHelixResourceManager.forEachSegmentsZKMetadata(tableNameWithType, segmentZKMetadata -> {

Review Comment:
   Won't this actually be slower due to more ZK point calls rather than earlier getChildren() calls ? 
   
   I think if use cases require all data, then earlier getChildren() calls is probably a better choice. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


Re: [PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

Posted by "xiangfu0 (via GitHub)" <gi...@apache.org>.
xiangfu0 closed pull request #17706: Add batched SegmentZKMetadata iteration API and migrate controller usages
URL: https://github.com/apache/pinot/pull/17706


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


Re: [PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

Posted by "xiangfu0 (via GitHub)" <gi...@apache.org>.
xiangfu0 commented on PR #17706:
URL: https://github.com/apache/pinot/pull/17706#issuecomment-3908009622

   Per request: changed /segments/{tableName}/zkmetadata to use getSegmentsZKMetadata(...) instead of forEachSegmentsZKMetadata(...) so this endpoint still uses the full-segment materialization path (single metadata read flow) and avoids extra per-segment round trips. Commit on this branch: 948bcc5fd507a52b4d32cefe6e2a26c694448663f. This should resolve the performance concern comment.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


Re: [PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #17706:
URL: https://github.com/apache/pinot/pull/17706#discussion_r2815081613


##########
pinot-plugins/pinot-minion-tasks/pinot-minion-builtin-tasks/src/test/java/org/apache/pinot/plugin/minion/tasks/realtimetoofflinesegments/RealtimeToOfflineSegmentsTaskGeneratorTest.java:
##########
@@ -242,6 +242,11 @@ public void testGenerateTasksNoMinionMetadata() {
     when(mockClusterInfoProvide.getIdealState(REALTIME_TABLE_NAME)).thenReturn(getIdealState(REALTIME_TABLE_NAME,
         Lists.newArrayList(segmentZKMetadata1.getSegmentName(), segmentZKMetadata2.getSegmentName())));
 
+    RealtimeToOfflineSegmentsTaskGenerator debugGenerator = new RealtimeToOfflineSegmentsTaskGenerator();
+    debugGenerator.init(mockClusterInfoProvide);
+    System.out.println("Segments before generation (debug): "
+        + debugGenerator.getNonConsumingSegmentsZKMetadataForRealtimeTable(REALTIME_TABLE_NAME));
+

Review Comment:
   Debug code should not be committed to production. This block creates a debug generator and prints to System.out, which violates the project's logging standards. Please remove this debug code and use SLF4J logging if debugging is still needed.
   ```suggestion
   
   ```



##########
pinot-common/src/main/java/org/apache/pinot/common/metadata/ZKMetadataProvider.java:
##########
@@ -725,6 +729,54 @@ public static List<SegmentZKMetadata> getSegmentsZKMetadata(ZkHelixPropertyStore
     }
   }
 
+  /**
+   * Applies the given consumer on segment ZK metadata for the given table in batches.
+   *
+   * @param batchSize  batch size for ZK get calls

Review Comment:
   The Javadoc comment is incomplete. It describes the parameters but doesn't specify what the method does at a high level. Consider adding a brief description like "Iterates over all segment ZK metadata for the given table and applies the provided consumer function to each segment metadata in batches." Also, the parameter descriptions should use proper @param tags.
   ```suggestion
      * Iterates over all segment ZK metadata for the given table and applies the provided consumer function
      * to each segment metadata in batches.
      *
      * @param propertyStore Helix property store used to fetch segment ZK metadata
      * @param tableNameWithType table name with type (e.g. "myTable_OFFLINE") whose segment metadata is processed
      * @param batchSize batch size for ZK get calls
   ```



##########
pinot-controller/src/main/java/org/apache/pinot/controller/ControllerConf.java:
##########
@@ -273,6 +273,9 @@ public static class ControllerPeriodicTasksConf {
     public static final String AGED_SEGMENTS_DELETION_BATCH_SIZE =
         "controller.retentionManager.agedSegmentsDeletionBatchSize";
     public static final int DEFAULT_AGED_SEGMENTS_DELETION_BATCH_SIZE = 1000;
+    public static final String SEGMENTS_ZK_METADATA_BATCH_SIZE =
+        "controller.retentionManager.segmentsZkMetadataBatchSize";

Review Comment:
   Inconsistent naming convention: The configuration property uses `segmentsZkMetadataBatchSize` (lowercase 'k') but the codebase consistently uses 'ZK' (uppercase) in other contexts like `SegmentZKMetadata`, `forEachSegmentsZKMetadata`, etc. For consistency with the rest of the codebase, consider using `segmentsZKMetadataBatchSize` instead.
   ```suggestion
           "controller.retentionManager.segmentsZKMetadataBatchSize";
   ```



##########
pinot-common/src/main/java/org/apache/pinot/common/metadata/ZKMetadataProvider.java:
##########
@@ -725,6 +729,54 @@ public static List<SegmentZKMetadata> getSegmentsZKMetadata(ZkHelixPropertyStore
     }
   }
 
+  /**
+   * Applies the given consumer on segment ZK metadata for the given table in batches.
+   *
+   * @param batchSize  batch size for ZK get calls
+   * @param consumer function invoked for each non-null segment metadata
+   */
+  public static void forEachSegmentZKMetadata(ZkHelixPropertyStore<ZNRecord> propertyStore, String tableNameWithType,
+      int batchSize, Consumer<SegmentZKMetadata> consumer) {
+    Preconditions.checkArgument(batchSize > 0, "Segment metadata batchSize must be greater than 0: %s", batchSize);
+
+    String segmentsPath = constructPropertyStorePathForResource(tableNameWithType);
+    List<String> segmentNames = getSegments(propertyStore, tableNameWithType);
+    if (segmentNames == null || segmentNames.isEmpty()) {
+      LOGGER.debug("No segments found under path: {}", segmentsPath);
+      return;
+    }
+
+    for (int startIndex = 0; startIndex < segmentNames.size(); startIndex += batchSize) {
+      int endIndex = Math.min(startIndex + batchSize, segmentNames.size());
+      List<String> segmentNameBatch = segmentNames.subList(startIndex, endIndex);
+
+      List<String> segmentPathBatch = new ArrayList<>(segmentNameBatch.size());
+      for (String segmentName : segmentNameBatch) {
+        segmentPathBatch.add(constructPropertyStorePathForSegment(tableNameWithType, segmentName));
+      }
+
+      List<ZNRecord> znRecords = propertyStore.get(segmentPathBatch, null, AccessOption.PERSISTENT);
+      int numNullRecords = 0;
+      if (znRecords != null) {
+        for (int i = 0; i < segmentNameBatch.size(); i++) {
+          ZNRecord znRecord = i < znRecords.size() ? znRecords.get(i) : null;
+          if (znRecord == null) {
+            numNullRecords++;
+          } else {
+            consumer.accept(new SegmentZKMetadata(znRecord));
+          }
+        }
+      } else {
+        numNullRecords = segmentNameBatch.size();
+      }
+
+      if (numNullRecords > 0) {
+        LOGGER.warn("Failed to read {}/{} segment ZK metadata under path: {} for table: {}",
+            numNullRecords, segmentNameBatch.size(), segmentsPath, tableNameWithType);
+      }
+    }
+  }

Review Comment:
   The new `forEachSegmentZKMetadata` method lacks dedicated unit test coverage. Since this is a core API method that will be widely used across the codebase, it should have comprehensive tests covering edge cases like: empty segment lists, null ZNRecords, batch boundaries, and proper consumer invocation. Consider adding unit tests in a ZKMetadataProviderTest class.



##########
pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/minion/generator/BaseTaskGenerator.java:
##########
@@ -161,32 +162,54 @@ public int getMaxAttemptsPerTask(String minionTag) {
    * @return the list of segment zk metadata for available segments in the table.
    */
   public List<SegmentZKMetadata> getSegmentsZKMetadataForTable(String tableNameWithType) {
+    return getSegmentsZKMetadataInIdealState(tableNameWithType, null);
+  }
+
+  public List<SegmentZKMetadata> getNonConsumingSegmentsZKMetadataForRealtimeTable(String tableNameWithType) {
     IdealState idealState = _clusterInfoAccessor.getIdealState(tableNameWithType);
+    return getSegmentsZKMetadataInIdealState(tableNameWithType, segmentZKMetadata -> {
+      String segmentName = segmentZKMetadata.getSegmentName();
+      return segmentZKMetadata.getStatus().isCompleted() // skip consuming segments
+          && !idealState.getInstanceStateMap(segmentName).containsValue(SegmentStateModel.CONSUMING);

Review Comment:
   Potential NullPointerException: `idealState` could be null when retrieved on line 169, but it's dereferenced on line 173 without null checking. If `getIdealState` returns null, this will throw an NPE when accessing `idealState.getInstanceStateMap(segmentName)`. Consider adding a null check or restructuring the code to handle this case.
   ```suggestion
       if (idealState == null) {
         return new ArrayList<>();
       }
       return getSegmentsZKMetadataInIdealState(tableNameWithType, segmentZKMetadata -> {
         String segmentName = segmentZKMetadata.getSegmentName();
         Map<String, String> instanceStateMap = idealState.getInstanceStateMap(segmentName);
         return segmentZKMetadata.getStatus().isCompleted() // skip consuming segments
             && instanceStateMap != null
             && !instanceStateMap.containsValue(SegmentStateModel.CONSUMING);
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


Re: [PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

Posted by "xiangfu0 (via GitHub)" <gi...@apache.org>.
xiangfu0 commented on PR #17706:
URL: https://github.com/apache/pinot/pull/17706#issuecomment-3907986550

   Addressed: changed  back to full-list path for endpoint-path use case to avoid batched point-lookup overhead; updated to iterate over  and map entries directly. Commit: 7b2e5f1e562b31f49b03120ec9b7e2dfcfa58b8f. This should satisfy the performance concern in the open review comment.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


Re: [PR] Add batched SegmentZKMetadata iteration API and migrate controller usages [pinot]

Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #17706:
URL: https://github.com/apache/pinot/pull/17706#issuecomment-3904875259

   ### :x: 40 Tests Failed:
   | Tests completed | Failed | Passed | Skipped |
   |---|---|---|---|
   | 7476 | 40 | 7436 | 0 |
   <details><summary>View the top 3 failed test(s) by shortest run time</summary>
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRealtimeLLCCleanup</code></pre>
   > <details><summary>Stack Traces | 0.004s run time</summary>
   > 
   > > <pre><code class="language-python">
   > > Wanted but not invoked:
   > > pinotHelixResourceManager.deleteSegments(
   > >     &amp;lt;any string&amp;gt;,
   > >     &amp;lt;any List&amp;gt;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.deleteSegments(PinotHelixResourceManager.java:1027)
   > > 
   > > However, there were exactly 11 interactions with this mock:
   > > pinotHelixResourceManager.getAllTables();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.periodictask.ControllerPeriodicTask.runTask(ControllerPeriodicTask.java:75)
   > > 
   > > pinotHelixResourceManager.getTableConfig(
   > >     &amp;quot;testTable_REALTIME&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.processTable(RetentionManager.java:115)
   > > 
   > > pinotHelixResourceManager.getOfflineTableConfig(
   > >     &amp;quot;testTable&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForTable(RetentionManager.java:173)
   > > 
   > > pinotHelixResourceManager.getHelixAdmin();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:212)
   > > 
   > > pinotHelixResourceManager.getHelixClusterName();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:213)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &amp;quot;testTable_REALTIME&amp;quot;,
   > >     1000,
   > >     org.apache.pinot.controller.helix.core.retention.RetentionManager$$Lambda$1651/0x00000007c0c9d440@36f1d1d9
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:215)
   > > 
   > > pinotHelixResourceManager.hasOfflineTable(
   > >     &amp;quot;testTable&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.getSegmentsToDeleteFromDeepstore(RetentionManager.java:329)
   > > 
   > > pinotHelixResourceManager.getLastLLCCompletedSegments(
   > >     &amp;quot;testTable_REALTIME&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:239)
   > > 
   > > pinotHelixResourceManager.getLineageUpdaterLock(
   > >     &amp;quot;testTable_REALTIME&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageSegmentLineageCleanupForTable(RetentionManager.java:464)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.postprocess(RetentionManager.java:133)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManagerTest.testRealtimeLLCCleanup(RetentionManagerTest.java:621)
   > > 
   > > </code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRealtimeLastLLCCleanup</code></pre>
   > <details><summary>Stack Traces | 0.005s run time</summary>
   > 
   > > <pre><code class="language-python">
   > > Wanted but not invoked:
   > > pinotHelixResourceManager.deleteSegments(
   > >     &amp;lt;any string&amp;gt;,
   > >     &amp;lt;any List&amp;gt;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.deleteSegments(PinotHelixResourceManager.java:1027)
   > > 
   > > However, there were exactly 12 interactions with this mock:
   > > pinotHelixResourceManager.getAllTables();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.periodictask.ControllerPeriodicTask.runTask(ControllerPeriodicTask.java:75)
   > > 
   > > pinotHelixResourceManager.getTableConfig(
   > >     &amp;quot;testTable_REALTIME&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.processTable(RetentionManager.java:115)
   > > 
   > > pinotHelixResourceManager.getOfflineTableConfig(
   > >     &amp;quot;testTable&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForTable(RetentionManager.java:173)
   > > 
   > > pinotHelixResourceManager.getHelixAdmin();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:212)
   > > 
   > > pinotHelixResourceManager.getHelixClusterName();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:213)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &amp;quot;testTable_REALTIME&amp;quot;,
   > >     1000,
   > >     org.apache.pinot.controller.helix.core.retention.RetentionManager$$Lambda$1651/0x00000007c0c9d440@74245401
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:215)
   > > 
   > > pinotHelixResourceManager.hasOfflineTable(
   > >     &amp;quot;testTable&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.getSegmentsToDeleteFromDeepstore(RetentionManager.java:329)
   > > 
   > > pinotHelixResourceManager.getLastLLCCompletedSegments(
   > >     &amp;quot;testTable_REALTIME&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:239)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &amp;quot;testTable_REALTIME&amp;quot;,
   > >     org.apache.pinot.controller.helix.core.PinotHelixResourceManager$$Lambda$1652/0x00000007c0c9c840@5d26e55
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.getLastLLCCompletedSegments(PinotHelixResourceManager.java:1011)
   > > 
   > > pinotHelixResourceManager.getLineageUpdaterLock(
   > >     &amp;quot;testTable_REALTIME&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageSegmentLineageCleanupForTable(RetentionManager.java:464)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.postprocess(RetentionManager.java:133)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManagerTest.testRealtimeLastLLCCleanup(RetentionManagerTest.java:659)
   > > 
   > > </code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRealtimeLLCCleanup</code></pre>
   > <details><summary>Stack Traces | 0.006s run time</summary>
   > 
   > > <pre><code class="language-python">
   > > Wanted but not invoked:
   > > pinotHelixResourceManager.deleteSegments(
   > >     &lt;any string&gt;,
   > >     &lt;any List&gt;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.deleteSegments(PinotHelixResourceManager.java:1027)
   > > 
   > > However, there were exactly 11 interactions with this mock:
   > > pinotHelixResourceManager.getAllTables();
   > > -&gt; at org.apache.pinot.controller.helix.core.periodictask.ControllerPeriodicTask.runTask(ControllerPeriodicTask.java:75)
   > > 
   > > pinotHelixResourceManager.getTableConfig(
   > >     &quot;testTable_REALTIME&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.processTable(RetentionManager.java:115)
   > > 
   > > pinotHelixResourceManager.getOfflineTableConfig(
   > >     &quot;testTable&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForTable(RetentionManager.java:173)
   > > 
   > > pinotHelixResourceManager.getHelixAdmin();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:212)
   > > 
   > > pinotHelixResourceManager.getHelixClusterName();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:213)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &quot;testTable_REALTIME&quot;,
   > >     1000,
   > >     org.apache.pinot.controller.helix.core.retention.RetentionManager$$Lambda$1651/0x00000007c0c9d440@36f1d1d9
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:215)
   > > 
   > > pinotHelixResourceManager.hasOfflineTable(
   > >     &quot;testTable&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.getSegmentsToDeleteFromDeepstore(RetentionManager.java:329)
   > > 
   > > pinotHelixResourceManager.getLastLLCCompletedSegments(
   > >     &quot;testTable_REALTIME&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:239)
   > > 
   > > pinotHelixResourceManager.getLineageUpdaterLock(
   > >     &quot;testTable_REALTIME&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageSegmentLineageCleanupForTable(RetentionManager.java:464)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.postprocess(RetentionManager.java:133)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManagerTest.testRealtimeLLCCleanup(RetentionManagerTest.java:621)
   > > 
   > > </code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMillisWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.006s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithDaysWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.007s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMillisNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.007s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMillisWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.007s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMillisWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.007s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithSecondsNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.007s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithSecondsWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.007s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithDaysWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.008s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithHoursNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.008s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMinutesWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.008s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithSecondsWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.008s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithDaysWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.009s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithHoursNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.009s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMillisNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.009s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMillisWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.009s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithSecondsNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.009s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRealtimeLastLLCCleanup</code></pre>
   > <details><summary>Stack Traces | 0.01s run time</summary>
   > 
   > > <pre><code class="language-python">
   > > Wanted but not invoked:
   > > pinotHelixResourceManager.deleteSegments(
   > >     &lt;any string&gt;,
   > >     &lt;any List&gt;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.deleteSegments(PinotHelixResourceManager.java:1027)
   > > 
   > > However, there were exactly 12 interactions with this mock:
   > > pinotHelixResourceManager.getAllTables();
   > > -&gt; at org.apache.pinot.controller.helix.core.periodictask.ControllerPeriodicTask.runTask(ControllerPeriodicTask.java:75)
   > > 
   > > pinotHelixResourceManager.getTableConfig(
   > >     &quot;testTable_REALTIME&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.processTable(RetentionManager.java:115)
   > > 
   > > pinotHelixResourceManager.getOfflineTableConfig(
   > >     &quot;testTable&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForTable(RetentionManager.java:173)
   > > 
   > > pinotHelixResourceManager.getHelixAdmin();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:212)
   > > 
   > > pinotHelixResourceManager.getHelixClusterName();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:213)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &quot;testTable_REALTIME&quot;,
   > >     1000,
   > >     org.apache.pinot.controller.helix.core.retention.RetentionManager$$Lambda$1651/0x00000007c0c9d440@74245401
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:215)
   > > 
   > > pinotHelixResourceManager.hasOfflineTable(
   > >     &quot;testTable&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.getSegmentsToDeleteFromDeepstore(RetentionManager.java:329)
   > > 
   > > pinotHelixResourceManager.getLastLLCCompletedSegments(
   > >     &quot;testTable_REALTIME&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForRealtimeTable(RetentionManager.java:239)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &quot;testTable_REALTIME&quot;,
   > >     org.apache.pinot.controller.helix.core.PinotHelixResourceManager$$Lambda$1652/0x00000007c0c9c840@5d26e55
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.getLastLLCCompletedSegments(PinotHelixResourceManager.java:1011)
   > > 
   > > pinotHelixResourceManager.getLineageUpdaterLock(
   > >     &quot;testTable_REALTIME&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageSegmentLineageCleanupForTable(RetentionManager.java:464)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.postprocess(RetentionManager.java:133)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManagerTest.testRealtimeLastLLCCleanup(RetentionManagerTest.java:659)
   > > 
   > > </code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithHoursWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.01s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithHoursWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.01s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithHoursWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.01s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMinutesWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.01s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithDaysWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.011s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMinutesWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.011s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithHoursWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.012s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithSecondsWithBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.012s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMinutesWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.013s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithSecondsWithBatchSizeAndLessSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.014s run time</summary>
   > 
   > > <pre><code class="language-python">expected [13] but found [5]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMinutesNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.015s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMinutesNoBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.016s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMinutesNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.018s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithDaysNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.022s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithMinutesNoBatchSizeAndMoreSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.023s run time</summary>
   > 
   > > <pre><code class="language-python">expected [true] but found [false]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testRetentionWithDaysNoBatchSizeAndSegmentsInDeepStore</code></pre>
   > <details><summary>Stack Traces | 0.024s run time</summary>
   > 
   > > <pre><code class="language-python">expected [14] but found [6]</code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testManageRetentionForHybridTable</code></pre>
   > <details><summary>Stack Traces | 0.04s run time</summary>
   > 
   > > <pre><code class="language-python">
   > > Wanted but not invoked:
   > > pinotHelixResourceManager.deleteSegments(
   > >     &amp;quot;myTable_REALTIME&amp;quot;,
   > >     &amp;lt;any List&amp;gt;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.deleteSegments(PinotHelixResourceManager.java:1027)
   > > 
   > > However, there were exactly 2 interactions with this mock:
   > > pinotHelixResourceManager.getPropertyStore();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForHybridTable(RetentionManager.java:255)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &amp;quot;myTable_REALTIME&amp;quot;,
   > >     1000,
   > >     org.apache.pinot.controller.helix.core.retention.RetentionManager$$Lambda$1641/0x00000007c0c98840@a1c4454
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForHybridTable(RetentionManager.java:277)
   > > 
   > > </code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testManageRetentionForHybridTable</code></pre>
   > <details><summary>Stack Traces | 0.05s run time</summary>
   > 
   > > <pre><code class="language-python">
   > > Wanted but not invoked:
   > > pinotHelixResourceManager.deleteSegments(
   > >     &quot;myTable_REALTIME&quot;,
   > >     &lt;any List&gt;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.deleteSegments(PinotHelixResourceManager.java:1027)
   > > 
   > > However, there were exactly 2 interactions with this mock:
   > > pinotHelixResourceManager.getPropertyStore();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForHybridTable(RetentionManager.java:255)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &quot;myTable_REALTIME&quot;,
   > >     1000,
   > >     org.apache.pinot.controller.helix.core.retention.RetentionManager$$Lambda$1641/0x00000007c0c98840@a1c4454
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForHybridTable(RetentionManager.java:277)
   > > 
   > > </code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testOffByDefaultForUntrackedSegmentsDeletion</code></pre>
   > <details><summary>Stack Traces | 0.228s run time</summary>
   > 
   > > <pre><code class="language-python">
   > > Wanted but not invoked:
   > > pinotHelixResourceManager.deleteSegments(
   > >     &amp;quot;testTable_OFFLINE&amp;quot;,
   > >     &amp;lt;any List&amp;gt;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.deleteSegments(PinotHelixResourceManager.java:1027)
   > > 
   > > However, there were exactly 7 interactions with this mock:
   > > pinotHelixResourceManager.getAllTables();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.periodictask.ControllerPeriodicTask.runTask(ControllerPeriodicTask.java:75)
   > > 
   > > pinotHelixResourceManager.getTableConfig(
   > >     &amp;quot;testTable_OFFLINE&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.processTable(RetentionManager.java:115)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &amp;quot;testTable_OFFLINE&amp;quot;,
   > >     1000,
   > >     org.apache.pinot.controller.helix.core.retention.RetentionManager$$Lambda$1650/0x00000007c0c9d040@2ef00277
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForOfflineTable(RetentionManager.java:189)
   > > 
   > > pinotHelixResourceManager.hasOfflineTable(
   > >     &amp;quot;testTable&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.getSegmentsToDeleteFromDeepstore(RetentionManager.java:329)
   > > 
   > > pinotHelixResourceManager.getLineageUpdaterLock(
   > >     &amp;quot;testTable_OFFLINE&amp;quot;
   > > );
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageSegmentLineageCleanupForTable(RetentionManager.java:464)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.postprocess(RetentionManager.java:133)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&amp;gt; at org.apache.pinot.controller.helix.core.retention.RetentionManagerTest.testOffByDefaultForUntrackedSegmentsDeletion(RetentionManagerTest.java:411)
   > > 
   > > </code></pre>
   > 
   > </details>
   
   
   > <pre><code class="language-python">org.apache.pinot.controller.helix.core.retention.RetentionManagerTest::testOffByDefaultForUntrackedSegmentsDeletion</code></pre>
   > <details><summary>Stack Traces | 0.23s run time</summary>
   > 
   > > <pre><code class="language-python">
   > > Wanted but not invoked:
   > > pinotHelixResourceManager.deleteSegments(
   > >     &quot;testTable_OFFLINE&quot;,
   > >     &lt;any List&gt;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.PinotHelixResourceManager.deleteSegments(PinotHelixResourceManager.java:1027)
   > > 
   > > However, there were exactly 7 interactions with this mock:
   > > pinotHelixResourceManager.getAllTables();
   > > -&gt; at org.apache.pinot.controller.helix.core.periodictask.ControllerPeriodicTask.runTask(ControllerPeriodicTask.java:75)
   > > 
   > > pinotHelixResourceManager.getTableConfig(
   > >     &quot;testTable_OFFLINE&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.processTable(RetentionManager.java:115)
   > > 
   > > pinotHelixResourceManager.forEachSegmentsZKMetadata(
   > >     &quot;testTable_OFFLINE&quot;,
   > >     1000,
   > >     org.apache.pinot.controller.helix.core.retention.RetentionManager$$Lambda$1650/0x00000007c0c9d040@2ef00277
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageRetentionForOfflineTable(RetentionManager.java:189)
   > > 
   > > pinotHelixResourceManager.hasOfflineTable(
   > >     &quot;testTable&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.getSegmentsToDeleteFromDeepstore(RetentionManager.java:329)
   > > 
   > > pinotHelixResourceManager.getLineageUpdaterLock(
   > >     &quot;testTable_OFFLINE&quot;
   > > );
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.manageSegmentLineageCleanupForTable(RetentionManager.java:464)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManager.postprocess(RetentionManager.java:133)
   > > 
   > > pinotHelixResourceManager.getSegmentDeletionManager();
   > > -&gt; at org.apache.pinot.controller.helix.core.retention.RetentionManagerTest.testOffByDefaultForUntrackedSegmentsDeletion(RetentionManagerTest.java:411)
   > > 
   > > </code></pre>
   > 
   > </details>
   
   </details>
   
   To view more test analytics, go to the [Test Analytics Dashboard](https://app.codecov.io/gh/apache/pinot/tests/xiangfu0%3Acodex%2Fadd-batch-segment-metadata-api)
   <sub>📋 Got 3 mins? [Take this short survey](https://forms.gle/22i53Qa1CySZjA6c7) to help us improve Test Analytics.</sub>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org