Package com.sleepycat.je.log

Source Code of com.sleepycat.je.log.LogBuffer

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2005
*      Sleepycat Software.  All rights reserved.
*
* $Id: LogBuffer.java,v 1.37 2005/06/09 15:05:18 cwl Exp $
*/

package com.sleepycat.je.log;

import java.nio.ByteBuffer;

import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.latch.Latch;
import com.sleepycat.je.utilint.DbLsn;

/**
* DbLogBuffers hold outgoing, newly written log entries.
*/
class LogBuffer implements LogSource {

    private static final String DEBUG_NAME = LogBuffer.class.getName();

    /* Storage */
    private ByteBuffer buffer;

    /* Information about what log entries are held here. */
    private long firstLsn;
    private long lastLsn;

    /* The read latch serializes access to and modification of the LSN info. */
    private Latch readLatch;

    /*
     * Buffer may be rewritten because an IOException previously occurred.
     */
    private boolean rewriteAllowed;

    LogBuffer(int capacity, EnvironmentImpl env)
  throws DatabaseException {

        if (env.useDirectNIO()) {
            buffer = ByteBuffer.allocateDirect(capacity);
        } else {
            buffer = ByteBuffer.allocate(capacity);
        }
        readLatch = new Latch(DEBUG_NAME, env);
        reinit();
    }

    /*
     * Used by LogManager for the case when we have a temporary buffer in hand
     * and no LogBuffers in the LogBufferPool are large enough to hold the
     * current entry being written.  We just wrap the temporary ByteBuffer
     * in a LogBuffer and pass it to FileManager. [#12674].
     */
    LogBuffer(ByteBuffer buffer, long firstLsn)
  throws DatabaseException {

  this.buffer = buffer;
        this.firstLsn = firstLsn;
        this.lastLsn = firstLsn;
  rewriteAllowed = false;
    }

    void reinit()
  throws DatabaseException {

        readLatch.acquire();
        buffer.clear();
        firstLsn = DbLsn.NULL_LSN;
        lastLsn = DbLsn.NULL_LSN;
  rewriteAllowed = false;
        readLatch.release();
    }

    /*
     * Write support
     */
       
    /**
     * 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 {

        readLatch.acquire();
  try {
      if (lastLsn != DbLsn.NULL_LSN) {
    assert (DbLsn.compareTo(lsn, lastLsn) > 0);
      }
      lastLsn = lsn;
      if (firstLsn == DbLsn.NULL_LSN) {
    firstLsn = lsn;
      }
  } finally {
      readLatch.release();
  }
    }

    /**
     * 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();
    }

    /*
     * Read support
     */

    /**
     * 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 {

        /* Latch before we look at the LSNs. */
        readLatch.acquire();
        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 {
            readLatch.release();
            return false;
        }
    }

    /*
     * LogSource support
     */

    /**
     * @see LogSource#release
     */
    public void release()
  throws DatabaseException  {

      readLatch.releaseIfOwner();
    }

    boolean getRewriteAllowed() {
  return rewriteAllowed;
    }

    void setRewriteAllowed() {
  rewriteAllowed = true;
    }

    /**
     * @see LogSource#getBytes
     */
    public ByteBuffer getBytes(long fileOffset) {

        /*
         * Make a copy of this buffer (doesn't copy data, only buffer state)
         * and position it to read the requested data.
   *
   * Note that we catch Exception here because it is possible that
   * another thread is modifying the state of buffer simultaneously.
   * Specifically, this can happen if another thread is writing this log
   * buffer out and it does (e.g.) a flip operation on it.  The actual
   * mark/pos of the buffer may be caught in an unpredictable state.  We
   * could add another latch to protect this buffer, but that's heavier
   * weight than we need.  So the easiest thing to do is to just retry
   * the duplicate operation.  See [#9822].
         */
        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);
        /* Log Buffer should always hold a whole entry. */
        assert (copy.remaining() >= numBytes) :
            "copy.remaining=" + copy.remaining() +
            " numBytes=" + numBytes;
        return copy;
    }
}
TOP

Related Classes of com.sleepycat.je.log.LogBuffer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.