@@ -58,7 +58,8 @@ public class KafkaTopicStatsClient implements TopicStatsClient {
5858 private static final Logger log = Logger .getLogger (KafkaTopicStatsClient .class .getName ());
5959
6060 // Default average message size estimate (in bytes) when we can't calculate it
61- private static final long DEFAULT_AVG_MESSAGE_SIZE = 1024 ; // 1KB
61+ private static final long DEFAULT_AVG_MESSAGE_SIZE =
62+ 1024 ; // 1KB
6263
6364 private final CloudRegion region ;
6465 private final KafkaAdminLifecycle lifecycle ;
@@ -130,6 +131,66 @@ public ApiFuture<Offset> getLatestOffset(String topicName, Partition partition)
130131 log );
131132 }
132133
134+ /**
135+ * Gets the latest (newest) offsets for all partitions of a topic in a single call.
136+ *
137+ * <p>This is more efficient than calling {@link #getLatestOffset} in a loop, as it batches all
138+ * partition queries into a single Kafka admin request.
139+ *
140+ * @param topicName The Kafka topic name.
141+ * @param partitionCount The number of partitions in the topic.
142+ * @return A future containing a map of partition to latest offset.
143+ */
144+ public ApiFuture <Map <Partition , Offset >> getLatestOffsets (String topicName , int partitionCount ) {
145+ Map <TopicPartition , OffsetSpec > request = new HashMap <>();
146+ for (int p = 0 ; p < partitionCount ; p ++) {
147+ request .put (new TopicPartition (topicName , p ), OffsetSpec .latest ());
148+ }
149+
150+ return KafkaFutureUtils .executeWithHandling (
151+ () -> {
152+ ListOffsetsResult result = lifecycle .adminClient ().listOffsets (request );
153+ Map <Partition , Offset > offsets = new HashMap <>();
154+ for (int p = 0 ; p < partitionCount ; p ++) {
155+ TopicPartition tp = new TopicPartition (topicName , p );
156+ ListOffsetsResultInfo info = result .partitionResult (tp ).get ();
157+ offsets .put (Partition .of (p ), Offset .of (info .offset ()));
158+ }
159+ return offsets ;
160+ },
161+ "getting latest offsets for all partitions" ,
162+ log );
163+ }
164+
165+ /**
166+ * Gets the earliest (oldest) offsets for all partitions of a topic in a single call.
167+ *
168+ * @param topicName The Kafka topic name.
169+ * @param partitionCount The number of partitions in the topic.
170+ * @return A future containing a map of partition to earliest offset.
171+ */
172+ public ApiFuture <Map <Partition , Offset >> getEarliestOffsets (
173+ String topicName , int partitionCount ) {
174+ Map <TopicPartition , OffsetSpec > request = new HashMap <>();
175+ for (int p = 0 ; p < partitionCount ; p ++) {
176+ request .put (new TopicPartition (topicName , p ), OffsetSpec .earliest ());
177+ }
178+
179+ return KafkaFutureUtils .executeWithHandling (
180+ () -> {
181+ ListOffsetsResult result = lifecycle .adminClient ().listOffsets (request );
182+ Map <Partition , Offset > offsets = new HashMap <>();
183+ for (int p = 0 ; p < partitionCount ; p ++) {
184+ TopicPartition tp = new TopicPartition (topicName , p );
185+ ListOffsetsResultInfo info = result .partitionResult (tp ).get ();
186+ offsets .put (Partition .of (p ), Offset .of (info .offset ()));
187+ }
188+ return offsets ;
189+ },
190+ "getting earliest offsets for all partitions" ,
191+ log );
192+ }
193+
133194 /**
134195 * Gets the offset for a specific timestamp.
135196 *
0 commit comments