@Test public void open_ignores_rollback() { File f = TT.tempDbFile(); WriteAheadLog wal = new WriteAheadLog(f.getPath()); wal.walPutLong(1L, 11L); wal.commit(); wal.walPutLong(2L, 33L); wal.rollback(); wal.walPutLong(3L, 33L); wal.commit(); wal.seal(); wal.close(); wal = new WriteAheadLog(f.getPath()); wal.open( new WALSequence( new Object[] {WALSequence.beforeReplayStart}, new Object[] {WALSequence.writeLong, 1L, 11L}, new Object[] {WALSequence.commit}, // 2L is ignored, rollback section is skipped on hard replay new Object[] {WALSequence.writeLong, 3L, 33L}, new Object[] {WALSequence.commit})); wal.destroyWalFiles(); wal.close(); f.delete(); }
@Test @org.junit.Ignore public void large_node_size() { for (int i : new int[] {10, 200, 6000}) { int max = i * 100; File f = TT.tempDbFile(); DB db = DBMaker.fileDB(f).transactionDisable().make(); Map m = db.treeMapCreate("map") .nodeSize(i) .keySerializer(BTreeKeySerializer.INTEGER) .valueSerializer(Serializer.INTEGER) .make(); for (int j = 0; j < max; j++) { m.put(j, j); } db.close(); db = DBMaker.fileDB(f).deleteFilesAfterClose().transactionDisable().make(); m = db.treeMap("map"); for (Integer j = 0; j < max; j++) { assertEquals(j, m.get(j)); } db.close(); } }
@Test public void lazy_file_create() { File f = TT.tempDbFile(); f.delete(); File f2 = new File(f.getPath() + ".wal.0"); WriteAheadLog wal = new WriteAheadLog(f.getPath()); wal.open(WriteAheadLog.NOREPLAY); assertTrue(!f2.exists()); wal.walPutLong(111L, 111L); assertTrue(f2.exists()); wal.close(); f2.delete(); }
@Test public void replay_commit_over_file_edge() { String f = TT.tempDbFile().getPath(); WriteAheadLog wal = new WriteAheadLog(f); byte[] b = TT.randomByteArray(20 * 1024 * 1024); wal.walPutRecord(11L, b, 0, b.length); wal.walPutRecord(33L, b, 0, b.length); wal.commit(); wal.close(); wal = new WriteAheadLog(f); wal.open( new WALSequence( new Object[] {WALSequence.beforeReplayStart}, new Object[] {WALSequence.writeRecord, 11L, 16L, b}, new Object[] {WALSequence.writeRecord, 33L, 4294967312L, b}, new Object[] {WALSequence.commit})); }
@Test public void overflow_record() { File f = TT.tempDbFile(); f.delete(); File f0 = new File(f.getPath() + ".wal.0"); File f1 = new File(f.getPath() + ".wal.1"); WriteAheadLog wal = new WriteAheadLog(f.getPath()); wal.open(WriteAheadLog.NOREPLAY); long lastPos = 0; while (!f1.exists()) { lastPos = wal.fileOffset; wal.walPutRecord(111L, new byte[100], 0, 100); assertTrue(f0.exists()); } assertTrue(WriteAheadLog.MAX_FILE_SIZE - 1000 < lastPos); assertTrue(WriteAheadLog.MAX_FILE_SIZE + 120 > lastPos); wal.destroyWalFiles(); }
@Test public void empty_commit() { String f = TT.tempDbFile().getPath(); WriteAheadLog wal = new WriteAheadLog(f); byte[] b = TT.randomByteArray(1024); wal.walPutRecord(33L, b, 0, b.length); wal.commit(); wal.commit(); wal.seal(); wal.close(); wal = new WriteAheadLog(f); wal.open( new WALSequence( new Object[] {WALSequence.beforeReplayStart}, new Object[] {WALSequence.writeRecord, 33L, 16L, b}, new Object[] {WALSequence.commit}, new Object[] {WALSequence.commit})); }
@Test public void cut_broken_end_rollback() { String f = TT.tempDbFile().getPath(); WriteAheadLog wal = new WriteAheadLog(f); wal.walPutLong(1L, 11L); wal.commit(); wal.walPutLong(2L, 22L); wal.commit(); wal.walPutLong(3L, 33L); wal.rollback(); wal.walPutLong(4L, 44L); wal.curVol.sync(); wal.close(); wal = new WriteAheadLog(f); wal.open( new WALSequence( new Object[] {WALSequence.beforeReplayStart}, new Object[] {WALSequence.writeLong, 1L, 11L}, new Object[] {WALSequence.commit}, new Object[] {WALSequence.writeLong, 2L, 22L}, new Object[] {WALSequence.commit})); }
@Test public void test() { File f = TT.tempDbFile(); WriteAheadLog wal = new WriteAheadLog(f.getPath()); for (int i = 0; i < commitNum; i++) { for (int j = 0; j < 6; j++) { wal.walPutLong(111L, i); } wal.commit(); } int cutPoint = new Random(cutPointSeed).nextInt((int) wal.curVol.length()); wal.curVol.sync(); wal.curVol.clear(cutPoint, wal.curVol.length()); File f2 = wal.curVol.getFile(); wal.close(); wal = new WriteAheadLog(f.getPath()); final AtomicLong i = new AtomicLong(); final AtomicLong c = new AtomicLong(); wal.open( new WriteAheadLog.WALReplay() { @Override public void beforeReplayStart() {} @Override public void afterReplayFinished() {} @Override public void writeLong(long offset, long value) { assertEquals(111L, offset); assertEquals(i.get(), value); assertTrue(c.getAndIncrement() < 6); } @Override public void writeRecord(long recid, long walId, Volume vol, long volOffset, int length) { fail(); } @Override public void writeByteArray( long offset, long walId, Volume vol, long volOffset, int length) { fail(); } @Override public void commit() { assertEquals(6, c.get()); c.set(0); i.incrementAndGet(); } @Override public void rollback() { fail(); } @Override public void writeTombstone(long recid) { fail(); } @Override public void writePreallocate(long recid) { fail(); } }); assertEquals(0, c.get()); f.delete(); f2.delete(); }