package com.sleepycat.je.log; import java.nio.ByteBuffer; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.dbi.EnvironmentImpl; import com.sleepycat.je.utilint.DbLsn; import de.ovgu.cide.jakutil.*; /** * DbLogBuffers hold outgoing, newly written log entries. */ class LogBuffer implements LogSource { private static final String DEBUG_NAME=LogBuffer.class.getName(); private ByteBuffer buffer; private long firstLsn; private long lastLsn; LogBuffer( int capacity, EnvironmentImpl env) throws DatabaseException { this.hook481(capacity); this.hook482(capacity); this.hook479(env); reinit(); } LogBuffer( ByteBuffer buffer, long firstLsn) throws DatabaseException { this.buffer=buffer; this.firstLsn=firstLsn; this.lastLsn=firstLsn; } void reinit() throws DatabaseException { buffer.clear(); firstLsn=DbLsn.NULL_LSN; lastLsn=DbLsn.NULL_LSN; } /** * Return first LSN held in this buffer. Assumes the log write latch is * held. */ long getFirstLsn(){ return firstLsn; } /** * This LSN has been written to the log. */ void registerLsn( long lsn) throws DatabaseException { if (lastLsn != DbLsn.NULL_LSN) { assert (DbLsn.compareTo(lsn,lastLsn) > 0); } lastLsn=lsn; if (firstLsn == DbLsn.NULL_LSN) { firstLsn=lsn; } } /** * Check capacity of buffer. Assumes that the log write latch is held. * @return true if this buffer can hold this many more bytes. */ boolean hasRoom( int numBytes){ return (numBytes <= (buffer.capacity() - buffer.position())); } /** * @return the actual data buffer. */ ByteBuffer getDataBuffer(){ return buffer; } /** * @return capacity in bytes */ int getCapacity(){ return buffer.capacity(); } /** * Support for reading a log entry out of a still-in-memory log * @return true if this buffer holds the entry at this LSN. The buffer will * be latched for read. Returns false if LSN is not here, and * releases the read latch. */ boolean containsLsn( long lsn) throws DatabaseException { boolean found=false; if ((firstLsn != DbLsn.NULL_LSN) && ((DbLsn.compareTo(firstLsn,lsn) <= 0) && (DbLsn.compareTo(lastLsn,lsn) >= 0))) { found=true; } if (found) { return true; } else { this.hook480(); return false; } } /** * @see LogSource#getBytes */ public ByteBuffer getBytes( long fileOffset){ ByteBuffer copy=null; while (true) { try { copy=buffer.duplicate(); copy.position((int)(fileOffset - DbLsn.getFileOffset(firstLsn))); break; } catch ( IllegalArgumentException IAE) { continue; } } return copy; } /** * @see LogSource#getBytes */ public ByteBuffer getBytes( long fileOffset, int numBytes){ ByteBuffer copy=getBytes(fileOffset); assert (copy.remaining() >= numBytes) : "copy.remaining=" + copy.remaining() + " numBytes="+ numBytes; return copy; } protected void hook479( EnvironmentImpl env) throws DatabaseException { } protected void hook480() throws DatabaseException { } protected void hook481( int capacity) throws DatabaseException { } protected void hook482( int capacity) throws DatabaseException { } }