com.firefly.net.buffer.IOBufferPool Maven / Gradle / Ivy
package com.firefly.net.buffer;
import com.firefly.net.BufferPool;
import com.firefly.utils.io.BufferUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
public class IOBufferPool implements BufferPool {
private static Logger log = LoggerFactory.getLogger("firefly-system");
private static final int POOL_SIZE = 8;
@SuppressWarnings("unchecked")
private final SoftReference[] pool = new SoftReference[POOL_SIZE];
private final boolean directBuffer;
public IOBufferPool() {
this(true);
}
public IOBufferPool(boolean directBuffer) {
this.directBuffer = directBuffer;
}
@Override
public ByteBuffer acquire(int size) {
for (int i = 0; i < POOL_SIZE; i++) {
SoftReference ref = pool[i];
if (ref == null) {
continue;
}
ByteBuffer buf = ref.get();
if (buf == null) {
pool[i] = null;
continue;
}
if (buf.capacity() >= size) {
pool[i] = null;
buf.clear();
return buf;
}
}
int allocateSize = BufferUtils.normalizeBufferSize(size);
log.debug("acquire buffer size: {}", allocateSize);
return directBuffer ? ByteBuffer.allocateDirect(allocateSize) : ByteBuffer.allocate(allocateSize);
}
@Override
public void release(ByteBuffer buffer) {
for (int i = 0; i < POOL_SIZE; i++) {
SoftReference ref = pool[i];
if (ref == null || ref.get() == null) {
pool[i] = new SoftReference<>(buffer);
return;
}
}
// pool is full - replace one
final int capacity = buffer.capacity();
for (int i = 0; i < POOL_SIZE; i++) {
SoftReference ref = pool[i];
if (ref == null) {
pool[i] = new SoftReference<>(buffer);
return;
} else {
ByteBuffer pooled = ref.get();
if (pooled == null) {
pool[i] = new SoftReference<>(buffer);
return;
} else {
if (pooled.capacity() < capacity) {
pool[i] = new SoftReference<>(buffer);
return;
}
}
}
}
}
@Override
public int size() {
int count = 0;
for (int i = 0; i < POOL_SIZE; i++) {
SoftReference ref = pool[i];
if (ref != null && ref.get() != null) {
count++;
}
}
return count;
}
}