@Override public void commit() { commitLock.lock(); try { // flush write caches into write ahead log flushWriteCache(); // move uncommited data to committed for (int segment = 0; segment < locks.length; segment++) { locks[segment].writeLock().lock(); try { // dump index vals into WAL long[] table = uncommittedIndexTable[segment].table; for (int i = 0; i < table.length; ) { long offset = table[i++]; long val = table[i++]; if (offset == 0) continue; wal.walPutLong(offset, val); } moveAndClear(uncommittedIndexTable[segment], committedIndexTable[segment]); moveAndClear(uncommittedDataLongs[segment], committedDataLongs[segment]); } finally { locks[segment].writeLock().unlock(); } } structuralLock.lock(); try { // flush modified Long Stack pages into WAL long[] set = uncommittedStackPages.set; longStackPagesLoop: for (int i = 0; i < set.length; i++) { long offset = set[i]; if (offset == 0) continue longStackPagesLoop; byte[] val = (byte[]) uncommittedStackPages.values[i]; if (val == LONG_STACK_PAGE_TOMBSTONE) committedPageLongStack.put(offset, -1); else { if (CC.ASSERT) assertLongStackPage(offset, val); long walPointer = wal.walPutByteArray(offset, val, 0, val.length); committedPageLongStack.put(offset, walPointer); } } uncommittedStackPages.clear(); // update checksum headVol.putInt(HEAD_CHECKSUM, headChecksum(headVol)); // take backup of headVol headVol.getData(0, headVolBackup, 0, headVolBackup.length); wal.walPutByteArray(0, headVolBackup, 0, headVolBackup.length); wal.commit(); wal.seal(); replaySoft(); realVol.sync(); wal.destroyWalFiles(); } finally { structuralLock.unlock(); } } finally { commitLock.unlock(); } }
@Override protected void indexLongPut(long offset, long val) { if (CC.ASSERT && !structuralLock.isHeldByCurrentThread()) throw new AssertionError(); wal.walPutLong(offset, val); }