@Override protected byte[] loadLongStackPage(long pageOffset, boolean willBeModified) { if (CC.ASSERT && !structuralLock.isHeldByCurrentThread()) throw new AssertionError(); // if(CC.ASSERT && compactionInProgress) // throw new AssertionError(); // first try to get it from dirty pages in current TX byte[] page = uncommittedStackPages.get(pageOffset); if (page != null) { return page; } // try to get it from previous TX stored in WAL, but not yet replayed long walval = committedPageLongStack.get(pageOffset); if (walval != 0) { byte[] b = wal.walGetByteArray2(walval); // page is going to be modified, so put it back into uncommittedStackPages) if (willBeModified) { uncommittedStackPages.put(pageOffset, b); } return b; } // and finally read it from main store int pageSize = (int) (parity4Get(vol.getLong(pageOffset)) >>> 48); page = new byte[pageSize]; vol.getData(pageOffset, page, 0, pageSize); if (willBeModified) { uncommittedStackPages.put(pageOffset, page); } return page; }
@Override public void commit() { if (isSnapshot) return; if (!tx) { vol.sync(); return; } commitLock.lock(); try { StoreAppend[] snaps = snapshots == null ? STORE_APPENDS_ZERO_ARRAY : snapshots.toArray(STORE_APPENDS_ZERO_ARRAY); for (int i = 0; i < locks.length; i++) { Lock lock = locks[i].writeLock(); lock.lock(); try { long[] m = modified[i].table; for (int j = 0; j < m.length; j += 2) { long recid = m[j]; long recidOffset = recid * 8; if (recidOffset == 0) continue; indexTable.ensureAvailable(recidOffset + 8); long oldVal = indexTable.getLong(recidOffset); indexTable.putLong(recidOffset, m[j + 1]); for (StoreAppend snap : snaps) { LongLongMap m2 = snap.modified[i]; if (m2.get(recid) == 0) { m2.put(recid, oldVal); } } } modified[i].clear(); } finally { lock.unlock(); } } long offset = alloc(1, 1); vol.putUnsignedByte(offset, I_TX_VALID); vol.sync(); } finally { commitLock.unlock(); } }