diff --git a/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java b/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java index 9eb3b3ab0634033d5a579c3c106c6c6d235d6c83..bdb851bab1121c9b7aa7157feea7f43af2d1e54f 100644 --- a/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java +++ b/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java @@ -461,26 +461,38 @@ public class MappedFileQueue { */ public MappedFile findMappedFileByOffset(final long offset, final boolean returnFirstOnNotFound) { try { - MappedFile mappedFile = this.getFirstMappedFile(); - if (mappedFile != null) { - int index = (int) ((offset / this.mappedFileSize) - (mappedFile.getFileFromOffset() / this.mappedFileSize)); + MappedFile firstMappedFile = this.getFirstMappedFile(); + if (firstMappedFile != null) { + int index = (int) ((offset / this.mappedFileSize) - (firstMappedFile.getFileFromOffset() / this.mappedFileSize)); if (index < 0 || index >= this.mappedFiles.size()) { - LOG_ERROR.warn("Offset for {} not matched. Request offset: {}, index: {}, " + - "mappedFileSize: {}, mappedFiles count: {}", - mappedFile, + LOG_ERROR.warn("Offset for {} not matched. Request offset: {}, index: {}, mappedFileSize: {}, mappedFiles count: {}", + firstMappedFile, offset, index, this.mappedFileSize, this.mappedFiles.size()); - } + } else { + MappedFile targetFile = null; + try { + targetFile = this.mappedFiles.get(index); + } catch (Exception ignored) { + } - try { - return this.mappedFiles.get(index); - } catch (Exception e) { - if (returnFirstOnNotFound) { - return mappedFile; + if (targetFile != null && offset >= targetFile.getFileFromOffset() + && offset < targetFile.getFileFromOffset() + this.mappedFileSize) { + return targetFile; } - LOG_ERROR.warn("findMappedFileByOffset failure. ", e); + + for (MappedFile tmpMappedFile : this.mappedFiles) { + if (offset >= tmpMappedFile.getFileFromOffset() + && offset < tmpMappedFile.getFileFromOffset() + this.mappedFileSize) { + return tmpMappedFile; + } + } + } + + if (returnFirstOnNotFound) { + return firstMappedFile; } } } catch (Exception e) { diff --git a/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java b/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java index 92f1876b2f09a095fd319b03d9a94f180fc18d23..8f76051d1f849bd382ad998af91dee6a07ace65f 100644 --- a/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java +++ b/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java @@ -229,6 +229,24 @@ public class MappedFileQueueTest { assertThat(mappedFileQueue.getMappedFiles().size()).isEqualTo(45); } + @Test + public void testFindMappedFile_ByIteration() { + MappedFileQueue mappedFileQueue = + new MappedFileQueue("target/unit_test_store/g/", 1024, null); + for (int i =0 ; i < 3; i++) { + MappedFile mappedFile = mappedFileQueue.getLastMappedFile(1024 * i); + mappedFile.wrotePosition.set(1024); + } + + assertThat(mappedFileQueue.findMappedFileByOffset(1028).getFileFromOffset()).isEqualTo(1024); + + // Switch two MappedFiles and verify findMappedFileByOffset method + MappedFile tmpFile = mappedFileQueue.getMappedFiles().get(1); + mappedFileQueue.getMappedFiles().set(1, mappedFileQueue.getMappedFiles().get(2)); + mappedFileQueue.getMappedFiles().set(2, tmpFile); + assertThat(mappedFileQueue.findMappedFileByOffset(1028).getFileFromOffset()).isEqualTo(1024); + } + @After public void destory() { File file = new File("target/unit_test_store");