com.bigdata.journal.IBufferStrategy Maven / Gradle / Ivy
/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
[email protected]
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.bigdata.journal;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import com.bigdata.counters.CounterSet;
import com.bigdata.rawstore.IAddressManager;
import com.bigdata.rawstore.IMRMW;
import com.bigdata.rawstore.IRawStore;
/**
*
* Interface for implementations of a buffer strategy as identified by a
* {@link BufferMode}. This interface is designed to encapsulate the
* specifics of reading and writing slots and performing operations to make
* an atomic commit.
*
*
* @author Bryan Thompson
* @version $Id$
*/
public interface IBufferStrategy extends IRawStore, IMRMW {
/**
* The next offset at which a data item would be written on the store as an
* offset into the user extent.
*/
public long getNextOffset();
/**
* The buffer mode supported by the implementation
*
* @return The implemented buffer mode.
*/
public BufferMode getBufferMode();
/**
* The initial extent.
*/
public long getInitialExtent();
/**
* The maximum extent allowable before a buffer overflow operation will be
* rejected.
*
* Note: The semantics here differ from those defined by
* {@link Options#MAXIMUM_EXTENT}. The latter specifies the threshold at
* which a journal will overflow (onto another journal) while this specifies
* the maximum size to which a buffer is allowed to grow.
*
* Note: This is normally zero (0L), which basically means that
* the maximum extent is ignored by the {@link IBufferStrategy} but
* respected by the {@link AbstractJournal}, resulting in a soft limit
* on journal overflow.
*
* @return The maximum extent permitted for the buffer -or- 0L
* iff no limit is imposed.
*/
public long getMaximumExtent();
/**
* The current size of the journal in bytes. When the journal is backed by
* a disk file this is the actual size on disk of that file. The initial
* value for this property is set by {@link Options#INITIAL_EXTENT}.
*/
public long getExtent();
/**
* The size of the user data extent in bytes.
*
* Note: The size of the user extent is always generally smaller than the
* value reported by {@link #getExtent()} since the latter also reports the
* space allocated to the journal header and root blocks.
*/
public long getUserExtent();
/**
* The size of the journal header, including MAGIC, version, and both root
* blocks. This is used as an offset when computing the address of a record
* in an underlying file and is ignored by buffer modes that are not backed
* by a file (e.g., transient) or that are memory mapped (since the map is
* setup to skip over the header)
*/
public int getHeaderSize();
/**
* Either truncates or extends the journal.
*
* Note: Implementations of this method MUST be synchronized so that the
* operation is atomic with respect to concurrent writers.
*
* @param extent
* The new extent of the journal. This value represent the total
* extent of the journal, including any root blocks together with
* the user extent.
*
* @exception IllegalArgumentException
* The user extent MAY NOT be increased beyond the maximum
* offset for which the journal was provisioned by
* {@link Options#OFFSET_BITS}.
*/
public void truncate(long extent);
/**
* Write the root block onto stable storage (ie, flush it through to disk).
*
* @param rootBlock
* The root block. Which root block is indicated by
* {@link IRootBlockView#isRootBlock0()}.
*
* @param forceOnCommit
* Governs whether or not the journal is forced to stable storage
* and whether or not the file metadata for the journal is forced
* to stable storage. See {@link Options#FORCE_ON_COMMIT}.
*/
public void writeRootBlock(IRootBlockView rootBlock,
ForceEnum forceOnCommitEnum);
// /**
// * Rolls back the store to the prior commit point by restoring the last
// * written root block.
// *
// * @throws IllegalStateException
// * if the store is not open
// * @throws IllegalStateException
// * if no prior root block is on hand to be restored.
// *
// * @todo Right now the rollback is a single step to the previous root block.
// * However, we could in fact maintain an arbitrary history for
// * rollback by writing the rootblocks onto the store (in the user
// * extent) and saving a reference to the prior root block on the
// * {@link ICommitRecord} before we write the new root block.
// */
// public void rollback();
/**
* Read the specified root block from the backing file.
*/
public ByteBuffer readRootBlock(boolean rootBlock0);
/**
* A block operation that transfers the serialized records (aka the written
* on portion of the user extent) en mass from the buffer onto an output
* file. The buffered records are written "in order" starting at the current
* position on the output file. The file is grown if necessary. The file
* position is advanced to the last byte written on the file.
*
* Note: Implementations of this method MUST be synchronized so that the
* operation is atomic with respect to concurrent writers.
*
* @param out
* The file to which the buffer contents will be transferred.
*
* @return The #of bytes written.
*
* @throws IOException
*/
public long transferTo(RandomAccessFile out) throws IOException;
/**
* Seals the store against further writes and discards any write caches
* since they will no longer be used. Buffered writes are NOT forced to the
* disk so the caller SHOULD be able to guarantee that concurrent writers
* are NOT running. The method should be implemented such that concurrent
* readers are NOT disturbed.
*
* @throws IllegalStateException
* if the store is closed.
* @throws IllegalStateException
* if the store is read-only.
*/
public void closeForWrites();
/**
* Return the performance counter hierarchy.
*/
public CounterSet getCounters();
public IAddressManager getAddressManager();
/**
* A method that removes assumptions of how a specific strategy determines
* whether a transaction commit is required.
*
* @param block
* The root block held by the client, can be checked against the
* state of the Buffer Strategy
* @return whether any modification has occurred.
*/
public boolean requiresCommit(IRootBlockView block);
/**
* A method that removes assumptions of how a specific strategy commits
* data. For most strategies the action is void since the client WORM DISK
* strategy writes data as allocated. For the Read Write Strategy more data
* must be managed as part of the protocol outside of the RootBlock, and
* this is the method that triggers that management. The caller MUST provide
* appropriate synchronization.
*/
public void commit();
/**
* A method that requires the implementation to discard its buffered write
* set (if any). The caller is responsible for any necessary synchronization
* as part of the abort protocol.
*/
public void abort();
/**
* Return true
if the store has been modified since the last
* {@link #commit()} or {@link #abort()}.
*
* @return true if store has been modified since last {@link #commit()} or
* {@link #abort()}.
*/
public boolean isDirty();
/**
* The RWStrategy requires meta allocation info in the root block, this
* method is the hook to enable access. The metaStartAddr is the address in
* the file where the allocation blocks are stored.
*
* @return the metaStartAddr for the root block if any
*/
public long getMetaStartAddr();
/**
* The RWStrategy requires meta allocation info in the root block, this
* method is the hook to enable access. The metaBitsAddr is the address in
* the file where the metaBits that control the allocation of the allocation
* blocks themselves is stored.
*
* @return the metaBitsAddr for the root block if any
*/
public long getMetaBitsAddr();
/**
* @return the number of bits available in the address to define offset
*/
public int getOffsetBits();
/**
* @return the maximum record size supported by this strategy
*/
public int getMaxRecordSize();
/**
* Return true
if the store uses per-record checksums. When
* true
, an additional 4 bytes are written after the record on
* the disk. Those bytes contain the checksum of the record.
*/
public boolean useChecksums();
// /**
// * Determines whether there are outstanding writes to the underlying store
// */
// public boolean isFlushed();
}