AtomixLogStorageReader implements LogStorageReader { @Override public long read(final DirectBuffer readBuffer, final long address) { if (address < reader.getFirstIndex()) { return LogStorage.OP_RESULT_INVALID_ADDR; } if (address > reader.getLastIndex()) { return LogStorage.OP_RESULT_NO_DATA; } final var result = findEntry(address) .map(indexed -> wrapEntryData(indexed, readBuffer)) .orElse(LogStorage.OP_RESULT_NO_DATA); if (result < 0) { return result; } else if (result == 0) { return LogStorage.OP_RESULT_NO_DATA; } return reader.getNextIndex(); } AtomixLogStorageReader(
      final ZeebeIndexMapping zeebeIndexMapping, final RaftLogReader reader); @Override boolean isEmpty(); @Override long read(final DirectBuffer readBuffer, final long address); @Override long readLastBlock(final DirectBuffer readBuffer); @Override long lookUpApproximateAddress(final long position); @Override void close(); Optional<Indexed<ZeebeEntry>> findEntry(final long index);  }
@Test public void shouldReturnNoDataOnEmptyRead() { final var reader = storageRule.get().newReader(); final var result = reader.read(buffer, 1); assertThat(result).isEqualTo(LogStorage.OP_RESULT_NO_DATA); }
@Test public void shouldReadEntry() { final var reader = storageRule.get().newReader(); final var firstEntry = append(1, 4, allocateData(1)); final var secondEntry = append(5, 8, allocateData(2)); final var firstEntryResults = read(reader, firstEntry.index()); final var secondEntryResults = read(reader, secondEntry.index()); assertThat(firstEntryResults).isEqualTo(tuple(1, secondEntry.index())); assertThat(secondEntryResults).isEqualTo(tuple(2, secondEntry.index() + 1)); }