Skip to content

Commit 94fbfcf

Browse files
authored
[ISSUE #10268] Fix incorrect time range file selection in IndexStoreService.queryAsync (#10269)
Co-authored-by: lizhimins <lizhimins@users.noreply.github.com>
1 parent 840b18c commit 94fbfcf

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

tieredstore/src/main/java/org/apache/rocketmq/tieredstore/index/IndexStoreService.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,14 @@ public CompletableFuture<List<IndexItem>> queryAsync(
235235
try {
236236
readWriteLock.readLock().lock();
237237
ConcurrentNavigableMap<Long, IndexFile> pendingMap =
238-
this.timeStoreTable.subMap(beginTime, true, endTime, true);
238+
this.timeStoreTable.headMap(endTime, true);
239239
List<CompletableFuture<Void>> futureList = new ArrayList<>(pendingMap.size());
240240
ConcurrentSkipListMap<String /* queueId-offset */, IndexItem> result = new ConcurrentSkipListMap<>();
241241

242242
for (Map.Entry<Long, IndexFile> entry : pendingMap.descendingMap().entrySet()) {
243+
if (entry.getValue().getEndTimestamp() < beginTime) {
244+
break;
245+
}
243246
CompletableFuture<Void> completableFuture = entry.getValue()
244247
.queryAsync(topic, key, maxCount, beginTime, endTime)
245248
.thenAccept(itemList -> itemList.forEach(indexItem -> {

tieredstore/src/test/java/org/apache/rocketmq/tieredstore/index/IndexStoreServiceTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,4 +351,41 @@ public void concurrentGetTest() throws InterruptedException {
351351
executorService.shutdown();
352352
Assert.assertTrue(result.get());
353353
}
354+
355+
@Test
356+
public void queryCrossFileBoundaryTest() throws InterruptedException, ExecutionException {
357+
indexService = new IndexStoreService(fileAllocator, filePath);
358+
indexService.start();
359+
360+
// Create first file with early beginTime
361+
long file1Begin = System.currentTimeMillis();
362+
for (int i = 0; i < storeConfig.getTieredStoreIndexFileMaxIndexNum() - 1; i++) {
363+
indexService.putKey(TOPIC_NAME, TOPIC_ID, QUEUE_ID,
364+
Collections.singleton("crossKey"), i * 100L, MESSAGE_SIZE, file1Begin + i * 1000);
365+
}
366+
367+
// Create second file with later beginTime (beyond query range)
368+
long file2Begin = System.currentTimeMillis() + 100_000;
369+
indexService.createNewIndexFile(file2Begin);
370+
for (int i = 0; i < 5; i++) {
371+
indexService.putKey(TOPIC_NAME, TOPIC_ID, QUEUE_ID,
372+
Collections.singleton("crossKey"), i * 100L, MESSAGE_SIZE, file2Begin + i);
373+
}
374+
375+
Assert.assertEquals(2, indexService.getTimeStoreTable().size());
376+
377+
// Query range: beginTime is AFTER file1's beginTime but BEFORE file1's last item timestamp
378+
// This should select file1, NOT file2 (file2 beginTime > queryEnd)
379+
long queryBegin = file1Begin + 5_000;
380+
long queryEnd = file1Begin + 15_000;
381+
382+
List<IndexItem> results = indexService.queryAsync(
383+
TOPIC_NAME, "crossKey", 10, queryBegin, queryEnd).get();
384+
385+
// file1 has items at timestamps: file1Begin, file1Begin+1000, ..., file1Begin+(N-1)*1000
386+
// Items in range [file1Begin+5000, file1Begin+15000] should match
387+
// The bug (subMap) would return empty because file1's key < queryBegin
388+
Assert.assertFalse("Should find index items from file covering query range", results.isEmpty());
389+
Assert.assertTrue("Should find items within query time range", results.size() > 0);
390+
}
354391
}

0 commit comments

Comments
 (0)