com.bigdata.io
Class DirectBufferPool

java.lang.Object
  extended by com.bigdata.io.DirectBufferPool

public class DirectBufferPool
extends Object

An instance of this class manages a JVM-wide pool of direct (aka native) ByteBuffers. Methods are provided to acquire a ByteBuffer from the pool and to release a ByteBuffer back to the pool.

Note: There is a bug in the release of large temporary direct ByteBuffers which motivates this class. For regular journals that overflow, the write cache is allocated once and handed off from journal to journal. However, there is no such opportunity for temporary stores. Unfortunately it is NOT an option to simply disable the write cache for temporary stores since NIO will allocate (and fail to release) an "temporary" direct buffer for the operation which transfers the data from the TransientBufferStrategy to disk. Therefore the data is copied into a temporary buffer allocated from this pool and then the buffer is either handed off to the DiskOnlyStrategy for use as its write cache (in which case the TemporaryRawStore holds a reference to the buffer and releases it back to those pool when it is finalized) or the buffer is immediately released back to this pool.

Note: Precisely because of the bug which motivates this class, we DO NOT release buffers back to the JVM. This means that the size of a DirectBufferPool can only increase, but at least you get to (re-)use the memory that you have allocated rather than leaking it to the native heap.

Version:
$Id: DirectBufferPool.java 2265 2009-10-26 12:51:06Z thompsonbry $
Author:
Bryan Thompson
See Also:
http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=8fab76d1d4479fffffffffa5abfb09c719a30?bug_id=6210541

Nested Class Summary
static interface DirectBufferPool.Options
          Options for provisioning the static instance of the DirectBufferPool.
 
Field Summary
protected static boolean INFO
           
static DirectBufferPool INSTANCE
          A JVM-wide pool of direct ByteBuffers used for a variety of purposes.
protected static org.apache.log4j.Logger log
           
 
Constructor Summary
protected DirectBufferPool(int poolCapacity, int bufferCapacity)
          Create a direct ByteBuffer pool.
 
Method Summary
 ByteBuffer acquire()
          Return a direct ByteBuffer.
 ByteBuffer acquire(long timeout, TimeUnit unit)
           
 int getBufferCapacity()
          The capacity of the ByteBuffers managed by this pool as specified to the ctor.
 CounterSet getCounters()
          Return the CounterSet for the DirectBufferPool.
 int getPoolCapacity()
          The capacity of the buffer as specified to the ctor.
 int getPoolSize()
          The approximate #of ByteBuffers currently managed by this pool.
 void release(ByteBuffer b)
          Release a direct ByteBuffer allocated by this pool back to the pool.
 boolean release(ByteBuffer b, long timeout, TimeUnit units)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

log

protected static final org.apache.log4j.Logger log

INFO

protected static final boolean INFO

INSTANCE

public static final DirectBufferPool INSTANCE
A JVM-wide pool of direct ByteBuffers used for a variety of purposes.

Note: acquire() requests will block once the pool capacity has been reached until a buffer is release(ByteBuffer)ed.

Constructor Detail

DirectBufferPool

protected DirectBufferPool(int poolCapacity,
                           int bufferCapacity)
Create a direct ByteBuffer pool.

Note: When the poolSize is bounded then acquire() MAY block. This can introduce deadlocks into the application. You can use a timeout to limit the sensitivity to deadlocks or you can use an unbounded pool and accept that OutOfMemoryErrors will arise if there is too much concurrent demand for the buffers supplied by this pool.

Parameters:
poolCapacity - The maximum capacity of the pool. Use Integer.MAX_VALUE to have a pool with an unbounded number of buffers.
bufferCapacity - The capacity of the ByteBuffers managed by this pool.
See Also:
INSTANCE
Method Detail

getPoolCapacity

public int getPoolCapacity()
The capacity of the buffer as specified to the ctor.


getPoolSize

public int getPoolSize()
The approximate #of ByteBuffers currently managed by this pool.


getBufferCapacity

public int getBufferCapacity()
The capacity of the ByteBuffers managed by this pool as specified to the ctor.


acquire

public ByteBuffer acquire()
                   throws InterruptedException,
                          TimeoutException
Return a direct ByteBuffer. The capacity of the buffer is determined by the configuration of this pool. The position will be equal to zero, the limit will be equal to the capacity, and the mark will not be set.

Note: This method will block if there are no free buffers in the pool and the pool was configured with a maximum capacity. In addition it MAY block if there is not enough free memory to fulfill the request.

Returns:
A direct ByteBuffer.
Throws:
InterruptedException - if the caller's Thread is interrupted awaiting a buffer.
TimeoutException

acquire

public ByteBuffer acquire(long timeout,
                          TimeUnit unit)
                   throws InterruptedException,
                          TimeoutException
Throws:
InterruptedException
TimeoutException

release

public void release(ByteBuffer b)
             throws InterruptedException
Release a direct ByteBuffer allocated by this pool back to the pool.

Parameters:
b - The buffer.
Throws:
InterruptedException

release

public boolean release(ByteBuffer b,
                       long timeout,
                       TimeUnit units)
                throws InterruptedException
Throws:
InterruptedException

getCounters

public CounterSet getCounters()
Return the CounterSet for the DirectBufferPool.

Returns:
The counters.


Copyright © 2006-2009 SYSTAP, LLC. All Rights Reserved.