/** * Set a persistence capable data structure for callback during the commit * protocol. * <p> * Note: the committers must be reset after restart or whenever the * committers are discarded (the committers are themselves transient * objects). * * @param rootSlot * The slot in the root block where the address of the * {@link ICommitter} will be recorded. * * @param committer * The commiter. */ @Override final public void setCommitter(final int rootSlot, final ICommitter committer) { assertOpen(); _committers[rootSlot] = committer; }
/** * Set a persistence capable data structure for callback during the commit * protocol. * <p> * Note: the committers must be reset after restart or whenever the * committers are discarded (the committers are themselves transient * objects). * * @param rootSlot * The slot in the root block where the address of the * {@link ICommitter} will be recorded. * * @param committer * The commiter. */ @Override final public void setCommitter(final int rootSlot, final ICommitter committer) { assertOpen(); _committers[rootSlot] = committer; }
@Override public void force(final boolean metadata) { assertOpen(); _bufferStrategy.force(metadata); }
/** * Returns a read-only view of the most recently committed * {@link ICommitRecord} containing the root addresses. * * @return The current {@link ICommitRecord} and never <code>null</code>. */ public ICommitRecord getCommitRecord() { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final ICommitRecord commitRecord = _commitRecord; if (commitRecord == null) throw new AssertionError(); return commitRecord; } finally { lock.unlock(); } }
@Override public void force(final boolean metadata) { assertOpen(); _bufferStrategy.force(metadata); }
/** * Returns a read-only view of the most recently committed * {@link ICommitRecord} containing the root addresses. * * @return The current {@link ICommitRecord} and never <code>null</code>. */ public ICommitRecord getCommitRecord() { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final ICommitRecord commitRecord = _commitRecord; if (commitRecord == null) throw new AssertionError(); return commitRecord; } finally { lock.unlock(); } }
@Override final public long getRootAddr(final int index) { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final ICommitRecord commitRecord = _commitRecord; if (commitRecord == null) throw new AssertionError(); return commitRecord.getRootAddr(index); } finally { lock.unlock(); } }
@Override final public long getRootAddr(final int index) { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final ICommitRecord commitRecord = _commitRecord; if (commitRecord == null) throw new AssertionError(); return commitRecord.getRootAddr(index); } finally { lock.unlock(); } }
/** * Return the first commit record whose timestamp is strictly greater than * the given commitTime. * * @param commitTime * The commit time. * * @return The commit record -or- <code>null</code> if there is no commit * record whose timestamp is strictly greater than * <i>commitTime</i>. */ public ICommitRecord getCommitRecordStrictlyGreaterThan(final long commitTime) { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final CommitRecordIndex commitRecordIndex = _commitRecordIndex; if (commitRecordIndex == null) throw new AssertionError(); return commitRecordIndex.findNext(commitTime); } finally { lock.unlock(); } }
/** * Registers a named index (core impl). Once registered the index will * participate in atomic commits. * <p> * Note: A named index must be registered outside of any transaction before * it may be used inside of a transaction. * <p> * Note: You MUST {@link #commit()} before the registered index will be * either restart-safe or visible to new transactions. * * @param name * The name. * @param ndx * The persistence capable data structure. */ final private void _register(final String name, final ICheckpointProtocol ndx) { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); synchronized (_name2Addr) { // add to the persistent name map. _name2Addr.registerIndex(name, ndx); } } finally { lock.unlock(); } }
/** * Return the first commit record whose timestamp is strictly greater than * the given commitTime. * * @param commitTime * The commit time. * * @return The commit record -or- <code>null</code> if there is no commit * record whose timestamp is strictly greater than * <i>commitTime</i>. */ public ICommitRecord getCommitRecordStrictlyGreaterThan(final long commitTime) { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final CommitRecordIndex commitRecordIndex = _commitRecordIndex; if (commitRecordIndex == null) throw new AssertionError(); return commitRecordIndex.findNext(commitTime); } finally { lock.unlock(); } }
/** * Return the mutable view of the named persistence capable data structure * (aka the "live" or {@link ITx#UNISOLATED} view). * * @return The mutable view of the persistence capable data structure. */ @Override final public ICheckpointProtocol getUnisolatedIndex(final String name) { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); if (name == null) throw new IllegalArgumentException(); if (Thread.interrupted()) { throw new RuntimeException(new InterruptedException()); } // Note: NullPointerException can be thrown here if asynchronously // closed (should be fixed by the ReadLock). synchronized (_name2Addr) { return _name2Addr.getIndex(name); } } finally { lock.unlock(); } }
/** * Return a read-only view of the last committed state of the * {@link CommitRecordIndex}. * * @return The read-only view of the {@link CommitRecordIndex}. */ public CommitRecordIndex getReadOnlyCommitRecordIndex() { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final CommitRecordIndex commitRecordIndex = getCommitRecordIndex( _rootBlock.getCommitRecordIndexAddr(), true/* readOnly */); // return new ReadOnlyIndex(commitRecordIndex); return commitRecordIndex; } finally { lock.unlock(); } }
/** * Return a read-only view of the last committed state of the * {@link CommitRecordIndex}. * * @return The read-only view of the {@link CommitRecordIndex}. */ public CommitRecordIndex getReadOnlyCommitRecordIndex() { final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final CommitRecordIndex commitRecordIndex = getCommitRecordIndex( _rootBlock.getCommitRecordIndexAddr(), true/* readOnly */); // return new ReadOnlyIndex(commitRecordIndex); return commitRecordIndex; } finally { lock.unlock(); } }
@Override public ByteBuffer read(final long addr) { assertOpen(); assertCanRead(); return _bufferStrategy.read(addr); }
@Override public ByteBuffer read(final long addr) { assertOpen(); assertCanRead(); return _bufferStrategy.read(addr); }
/** * {@inheritDoc} * * @todo the {@link CommitRecordIndex} is a possible source of thread * contention since transactions need to use this code path in order * to locate named indices but the {@link WriteExecutorService} can * also write on this index. I have tried some different approaches to * handling this. */ @Override public ICommitRecord getCommitRecord(final long commitTime) { if (isHistoryGone(commitTime)) return null; final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final CommitRecordIndex commitRecordIndex = _commitRecordIndex; if (commitRecordIndex == null) throw new AssertionError(); return commitRecordIndex.find(commitTime); } finally { lock.unlock(); } }
/** * {@inheritDoc} * * @todo the {@link CommitRecordIndex} is a possible source of thread * contention since transactions need to use this code path in order * to locate named indices but the {@link WriteExecutorService} can * also write on this index. I have tried some different approaches to * handling this. */ @Override public ICommitRecord getCommitRecord(final long commitTime) { if (isHistoryGone(commitTime)) return null; final ReadLock lock = _fieldReadWriteLock.readLock(); lock.lock(); try { assertOpen(); final CommitRecordIndex commitRecordIndex = _commitRecordIndex; if (commitRecordIndex == null) throw new AssertionError(); return commitRecordIndex.find(commitTime); } finally { lock.unlock(); } }
/** * Make sure that the journal has at least the specified number of bytes of * unused capacity remaining in the user extent. * <p> * Note: You need an exclusive write lock on the journal to extend it. * * @param minFree * The minimum #of bytes free for the user extent. * * @return The #of bytes of free space remaining in the user extent. */ public long ensureMinFree(final long minFree) { assertOpen(); if (minFree < 0L) throw new IllegalArgumentException(); final IBufferStrategy buf = _bufferStrategy; final long remaining = buf.getUserExtent() - buf.getNextOffset(); if (remaining < minFree) { buf.truncate(buf.getExtent() + minFree); } return buf.getUserExtent() - buf.getNextOffset(); }
/** * Make sure that the journal has at least the specified number of bytes of * unused capacity remaining in the user extent. * <p> * Note: You need an exclusive write lock on the journal to extend it. * * @param minFree * The minimum #of bytes free for the user extent. * * @return The #of bytes of free space remaining in the user extent. */ public long ensureMinFree(final long minFree) { assertOpen(); if (minFree < 0L) throw new IllegalArgumentException(); final IBufferStrategy buf = _bufferStrategy; final long remaining = buf.getUserExtent() - buf.getNextOffset(); if (remaining < minFree) { buf.truncate(buf.getExtent() + minFree); } return buf.getUserExtent() - buf.getNextOffset(); }