@Override public long allocatePages(long pageCount) throws IOException { if (pageCount <= 0) { return 0; } Stats stats = new Stats(); mPageManager.addTo(stats); pageCount -= stats.freePages; if (pageCount <= 0) { return 0; } for (int i = 0; i < pageCount; i++) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { mPageManager.allocAndRecyclePage(); } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } } return pageCount; }
@Override public void scanFreeList(LongConsumer dst) throws IOException { CommitLock.Shared shared = mCommitLock.acquireShared(); try { scanFreeList(I_MANAGER_HEADER + _PageManager.I_REGULAR_QUEUE, dst); scanFreeList(I_MANAGER_HEADER + _PageManager.I_RECYCLE_QUEUE, dst); } finally { shared.release(); } }
@Override public void deletePage(long id) throws IOException { checkId(id); CommitLock.Shared shared = mCommitLock.acquireShared(); try { mPageManager.deletePage(id); } catch (IOException e) { throw e; } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } mPageArray.uncachePage(id); }
@Override public long allocPage() throws IOException { CommitLock.Shared shared = mCommitLock.acquireShared(); try { return mPageManager.allocPage(); } catch (DatabaseException e) { if (e.isRecoverable()) { throw e; } throw closeOnFailure(e); } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } }
@Override public void commit(boolean resume, long header, final CommitCallback callback) throws IOException { // Acquire a shared lock to prevent concurrent commits after callback has released // exclusive lock. CommitLock.Shared shared = mCommitLock.acquireShared(); try { mHeaderLatch.acquireShared(); final int commitNumber = mCommitNumber + 1; mHeaderLatch.releaseShared(); try { if (!resume) { mPageManager.commitStart(header, I_MANAGER_HEADER); } if (callback != null) { // Invoke the callback to ensure all dirty pages get written. callback.prepare(resume, header); } } catch (DatabaseException e) { if (e.isRecoverable()) { throw e; } else { throw closeOnFailure(e); } } try { commitHeader(header, commitNumber); mPageManager.commitEnd(header, I_MANAGER_HEADER); } catch (Throwable e) { throw closeOnFailure(e); } } finally { shared.release(); } }