Core I/O components for Eclipse Jetty providing essential I/O utilities, buffer management, and network connection handling
—
Jetty IO provides a sophisticated buffer management system built around reference counting and pooling for efficient memory usage in high-throughput network applications.
The ByteBufferPool interface provides pooled ByteBuffer instances wrapped in RetainableByteBuffer for automatic memory management.
/**
* Pool for RetainableByteBuffer instances with reference counting
*/
interface ByteBufferPool {
/**
* Acquire a buffer from the pool
* @param size minimum buffer size required
* @param direct whether to prefer direct buffers
* @return RetainableByteBuffer instance
*/
RetainableByteBuffer acquire(int size, boolean direct);
/** Clear all non-retained buffers from the pool */
void clear();
// Default implementations
ByteBufferPool NON_POOLING = new NonPooling();
ByteBufferPool SIZED_NON_POOLING = new Sized(new NonPooling(), 1024, true);
class Wrapper implements ByteBufferPool {
private final ByteBufferPool wrapped;
public Wrapper(ByteBufferPool wrapped);
public ByteBufferPool getWrapped();
public RetainableByteBuffer acquire(int size, boolean direct);
public void clear();
}
class Sized implements ByteBufferPool {
public Sized(ByteBufferPool pool, int size, boolean direct);
public RetainableByteBuffer acquire(int size, boolean direct);
}
class NonPooling implements ByteBufferPool {
public RetainableByteBuffer acquire(int size, boolean direct);
public void clear();
}
class Accumulator {
public Accumulator();
public int getLength();
public void append(ByteBuffer buffer);
public ByteBuffer[] toByteBuffers();
public void writeTo(WritableByteChannel channel) throws IOException;
}
}Usage Examples:
// Basic buffer acquisition and release
ByteBufferPool pool = new ArrayByteBufferPool();
RetainableByteBuffer buffer = pool.acquire(1024, false);
try {
ByteBuffer bb = buffer.getByteBuffer();
// Use buffer for I/O operations
bb.put("Hello World".getBytes());
} finally {
buffer.release(); // Always release when done
}
// Using wrapper for additional functionality
ByteBufferPool wrappedPool = new ByteBufferPool.Wrapper(pool) {
@Override
public RetainableByteBuffer acquire(int size, boolean direct) {
System.out.println("Acquiring buffer of size: " + size);
return super.acquire(size, direct);
}
};
// Using sized pool for consistent buffer sizes
ByteBufferPool sizedPool = new ByteBufferPool.Sized(pool, 4096, true);
RetainableByteBuffer fixedBuffer = sizedPool.acquire(100, false); // Returns 4096 byte bufferReference-counted ByteBuffer wrapper that integrates with the pooling system.
/**
* Reference-counted ByteBuffer with pool integration
*/
interface RetainableByteBuffer extends Retainable {
/** Get the wrapped ByteBuffer */
ByteBuffer getByteBuffer();
/** Check if this buffer is currently retained */
boolean isRetained();
/** Check if underlying buffer is direct */
boolean isDirect();
/** Get number of remaining bytes */
int remaining();
/** Check if buffer has remaining bytes */
boolean hasRemaining();
/** Get buffer capacity */
int capacity();
/** Clear the buffer (reset position/limit) */
void clear();
// Static factory methods
static RetainableByteBuffer wrap(ByteBuffer buffer);
static RetainableByteBuffer wrap(ByteBuffer buffer, Retainable retainable);
// Constants
RetainableByteBuffer EMPTY = new EmptyRetainableByteBuffer();
}Usage Examples:
// Creating retainable buffers
ByteBuffer rawBuffer = ByteBuffer.allocate(1024);
RetainableByteBuffer retainable = RetainableByteBuffer.wrap(rawBuffer);
// With custom retainable for cleanup
RetainableByteBuffer customRetainable = RetainableByteBuffer.wrap(rawBuffer, () -> {
// Custom cleanup logic
System.out.println("Buffer released");
});
// Sharing buffer reference
retainable.retain(); // Increment reference count
// Pass to another component...
// Both components must call release() when done
// Buffer operations
ByteBuffer bb = retainable.getByteBuffer();
bb.put("data".getBytes());
System.out.println("Remaining: " + retainable.remaining());
System.out.println("Is direct: " + retainable.isDirect());Core reference counting abstraction for automatic resource management.
/**
* Reference counting abstraction for borrowed resources
*/
interface Retainable {
/** Check if reference counting is enabled */
boolean canRetain();
/** Increment reference count */
void retain();
/**
* Decrement reference count
* @return true when reference count reaches zero
*/
boolean release();
class Wrapper implements Retainable {
private final Retainable wrapped;
public Wrapper(Retainable wrapped);
public Retainable getWrapped();
public boolean canRetain();
public void retain();
public boolean release();
}
class ReferenceCounter implements Retainable {
public ReferenceCounter();
public boolean canRetain();
public void retain();
public boolean release();
}
}Usage Examples:
// Basic reference counting
Retainable resource = new Retainable.ReferenceCounter();
// Share resource (increment count)
resource.retain();
processInBackground(resource); // Will call release() when done
// Original holder releases
boolean shouldCleanup = resource.release(); // Returns false (count > 0)
// Background processing completes
boolean shouldCleanup2 = resource.release(); // Returns true (count = 0)
if (shouldCleanup2) {
// Perform cleanup
}
// Wrapper for adding behavior
Retainable wrappedResource = new Retainable.Wrapper(resource) {
@Override
public boolean release() {
boolean result = super.release();
if (result) {
System.out.println("Resource fully released");
}
return result;
}
};High-performance array-based buffer pool implementation.
/**
* High-performance array-based byte buffer pool
*/
class ArrayByteBufferPool implements ByteBufferPool {
public ArrayByteBufferPool();
public ArrayByteBufferPool(int minSize, int factor, int maxSize);
public ArrayByteBufferPool(int minSize, int factor, int maxSize, int maxBucketSize);
public ArrayByteBufferPool(int minSize, int factor, int maxSize, int maxBucketSize, long maxHeapMemory, long maxDirectMemory);
public RetainableByteBuffer acquire(int size, boolean direct);
public void clear();
// Configuration methods
public int getMinSize();
public int getFactor();
public int getMaxSize();
public int getMaxBucketSize();
public long getMaxHeapMemory();
public long getMaxDirectMemory();
// Statistics
public long getHeapMemory();
public long getDirectMemory();
public String toString();
}Configuration Example:
// Default configuration
ArrayByteBufferPool defaultPool = new ArrayByteBufferPool();
// Custom configuration
ArrayByteBufferPool customPool = new ArrayByteBufferPool(
64, // minSize: smallest buffer size
2, // factor: size multiplication factor
65536, // maxSize: largest buffer size
64, // maxBucketSize: max buffers per size bucket
1024*1024, // maxHeapMemory: max heap memory for pool
2*1024*1024 // maxDirectMemory: max direct memory for pool
);
// Monitor pool usage
System.out.println("Heap memory used: " + customPool.getHeapMemory());
System.out.println("Direct memory used: " + customPool.getDirectMemory());Utility for accumulating multiple ByteBuffers into a sequence.
/**
* Accumulator for ByteBuffer sequences
*/
class ByteBufferAccumulator implements Closeable {
public ByteBufferAccumulator(ByteBufferPool pool, boolean direct);
public int getLength();
public void append(byte[] bytes);
public void append(byte[] bytes, int offset, int length);
public void append(ByteBuffer buffer);
public ByteBuffer[] toByteBuffers();
public ByteBuffer toByteBuffer();
public void writeTo(WritableByteChannel channel) throws IOException;
public void close();
}Utility for aggregating ByteBuffers with size limits.
/**
* Aggregates ByteBuffers with size limits
*/
class ByteBufferAggregator {
public ByteBufferAggregator(ByteBufferPool pool, boolean direct, int size, int maxSize);
public boolean aggregate(ByteBuffer buffer);
public ByteBuffer takeByteBuffer();
public void close();
public int getSize();
public int getMaxSize();
}Usage Examples:
// Accumulating multiple buffers
ByteBufferAccumulator accumulator = new ByteBufferAccumulator(pool, false);
try {
accumulator.append("Hello ".getBytes());
accumulator.append("World".getBytes());
// Get as single buffer
ByteBuffer combined = accumulator.toByteBuffer();
// Or get as array
ByteBuffer[] buffers = accumulator.toByteBuffers();
// Write to channel
FileChannel channel = FileChannel.open(path, StandardOpenOption.WRITE);
accumulator.writeTo(channel);
} finally {
accumulator.close();
}
// Aggregating with size limits
ByteBufferAggregator aggregator = new ByteBufferAggregator(pool, false, 1024, 8192);
try {
ByteBuffer chunk1 = ByteBuffer.wrap("data1".getBytes());
ByteBuffer chunk2 = ByteBuffer.wrap("data2".getBytes());
boolean aggregated1 = aggregator.aggregate(chunk1); // true
boolean aggregated2 = aggregator.aggregate(chunk2); // true if fits
// Take aggregated result
ByteBuffer result = aggregator.takeByteBuffer();
} finally {
aggregator.close();
}Stream adapters for ByteBuffer operations.
/**
* InputStream backed by ByteBuffer
*/
class ByteBufferInputStream extends InputStream {
public ByteBufferInputStream(ByteBuffer buffer);
public int read();
public int read(byte[] b, int off, int len);
public int available();
public void close();
}
/**
* OutputStream that writes to ByteBuffer
*/
class ByteBufferOutputStream extends OutputStream {
public ByteBufferOutputStream(ByteBuffer buffer);
public void write(int b);
public void write(byte[] b, int off, int len);
public ByteBuffer getByteBuffer();
public void close();
}Usage Examples:
// Reading from ByteBuffer as InputStream
ByteBuffer buffer = ByteBuffer.wrap("Hello World".getBytes());
try (ByteBufferInputStream input = new ByteBufferInputStream(buffer)) {
int data;
while ((data = input.read()) != -1) {
System.out.print((char) data);
}
}
// Writing to ByteBuffer as OutputStream
ByteBuffer buffer = ByteBuffer.allocate(1024);
try (ByteBufferOutputStream output = new ByteBufferOutputStream(buffer)) {
output.write("Hello World".getBytes());
ByteBuffer result = output.getByteBuffer();
result.flip();
// Use result buffer
}Install with Tessl CLI
npx tessl i tessl/maven-org-eclipse-jetty--jetty-io