| | |
| | | } |
| | | } |
| | | |
| | | Record<K, V> getNewestRecord() throws ChangelogException |
| | | { |
| | | try { |
| | | final long lastBlockStart = getClosestBlockStartBeforeOrAtPosition(getFileLength()); |
| | | positionToRecordFromBlockStart(lastBlockStart); |
| | | ByteString candidate = readNextRecord(); |
| | | ByteString record = candidate; |
| | | while (candidate != null) |
| | | { |
| | | record = candidate; |
| | | candidate = readNextRecord(); |
| | | } |
| | | return record == null ? null : parser.decodeRecord(record); |
| | | } |
| | | catch (IOException e) |
| | | { |
| | | throw new ChangelogException(ERR_CHANGELOG_CANNOT_READ_NEWEST_RECORD.get(file.getPath()), e); |
| | | } |
| | | } |
| | | } |
| | |
| | | /** Indicates if log is enabled for write. */ |
| | | private final boolean isWriteEnabled; |
| | | |
| | | private Record<K, V> newestRecord; |
| | | |
| | | /** |
| | | * Creates a new log file. |
| | | * |
| | |
| | | { |
| | | checkLogIsEnabledForWrite(); |
| | | writer.write(record); |
| | | newestRecord = record; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | Record<K, V> getNewestRecord() throws ChangelogException |
| | | { |
| | | // TODO : need a more efficient way to retrieve it |
| | | DBCursor<Record<K, V>> cursor = null; |
| | | try |
| | | if (newestRecord == null) |
| | | { |
| | | cursor = getCursor(); |
| | | Record<K, V> record = null; |
| | | while (cursor.next()) |
| | | { |
| | | record = cursor.getRecord(); |
| | | } |
| | | return record; |
| | | newestRecord = getReader().getNewestRecord(); |
| | | } |
| | | finally |
| | | { |
| | | StaticUtils.close(cursor); |
| | | } |
| | | return newestRecord; |
| | | } |
| | | |
| | | /** |
| | |
| | | ERR_CHANGELOG_UNABLE_TO_DELETE_LAST_LOG_ROTATION_TIME_FILE_289=Could not delete \ |
| | | file '%s' that stored the previous last log rotation time |
| | | ERR_CHANGELOG_CURSOR_ABORTED_290=Cursor on log '%s' has been aborted after \ |
| | | a purge or a clear |
| | | a purge or a clear |
| | | ERR_CHANGELOG_CANNOT_READ_NEWEST_RECORD_291=Could not position and read newest record from log file '%s' |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /** Test that changes are visible immediately to a reader after a write. */ |
| | | /** Test that changes are properly ordered. */ |
| | | @Test |
| | | public void testWriteAndReadOnSameLogFile() throws Exception |
| | | public void testAppendingChangesAreOrdered() throws Exception |
| | | { |
| | | try (LogFile<String, String> writeLog = getLogFile(RECORD_PARSER); |
| | | LogFile<String, String> readLog = getLogFile(RECORD_PARSER)) |
| | | try (LogFile<String, String> writeLog = getLogFile(RECORD_PARSER)) |
| | | { |
| | | for (int i = 1; i <= 100; i++) |
| | | { |
| | |
| | | writeLog.append(record); |
| | | assertThat(writeLog.getNewestRecord()).as("write changelog " + i).isEqualTo(record); |
| | | assertThat(writeLog.getOldestRecord()).as("write changelog " + i).isEqualTo(Record.from("key01", "value1")); |
| | | assertThat(readLog.getNewestRecord()).as("read changelog " + i).isEqualTo(record); |
| | | assertThat(readLog.getOldestRecord()).as("read changelog " + i).isEqualTo(Record.from("key01", "value1")); |
| | | } |
| | | } |
| | | } |