package org.araqne.storage.api;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RCDirectBuffer {
private static Logger dbLogger = LoggerFactory.getLogger("A");
private static AtomicLong iid = new AtomicLong(0);
private final long oid;
private AtomicInteger refCount = new AtomicInteger(0);
private ByteBuffer buffer;
private boolean destroyed = false;
private String poolName;
private String usageName;
private boolean isDestroyed;
private RCDirectBufferManager manager;
public RCDirectBuffer(RCDirectBufferManager manager, ByteBuffer buffer) {
if (dbLogger.isDebugEnabled())
this.oid = iid.incrementAndGet();
else
this.oid = 0;
this.manager = manager;
this.buffer = buffer;
}
public RCDirectBuffer(RCDirectBufferManager manager, ByteBuffer buffer, String poolName, String usageName) {
if (dbLogger.isDebugEnabled())
this.oid = iid.incrementAndGet();
else
this.oid = 0;
this.manager = manager;
this.buffer = buffer;
this.poolName = poolName;
this.usageName = usageName;
}
public RCDirectBuffer(RCDirectBufferManager manager, long oid, ByteBuffer buffer,
String poolName, String usageName) {
this.oid = oid;
this.manager = manager;
this.buffer = buffer;
this.poolName = poolName;
this.usageName = usageName;
}
public long getOID() {
return oid;
}
public ByteBuffer get() {
return buffer;
}
private void destroy() {
try {
if (buffer == null)
return;
if (!buffer.isDirect())
return;
isDestroyed = true;
manager.clean(this, poolName, usageName);
} catch (Throwable t) {
}
}
public RCDirectBuffer addRef() {
synchronized (this) {
if (!isDestroyed) {
refCount.incrementAndGet();
return this;
} else {
return null;
}
}
}
public RCDirectBuffer release() {
synchronized (this) {
int afterDec = refCount.decrementAndGet();
if (afterDec == 0 && !destroyed) {
destroy();
}
}
return null;
}
public RCDirectBuffer asReadOnlyBuffer() {
return new RCDirectBufferReadOnly(manager, this, poolName, usageName);
}
public class RCDirectBufferReadOnly extends RCDirectBuffer {
public RCDirectBufferReadOnly(RCDirectBufferManager manager, RCDirectBuffer buffer, String poolName, String usageName) {
super(manager, buffer.oid, buffer.get().asReadOnlyBuffer(), poolName, usageName);
}
public RCDirectBuffer addRef() {
throw new ReadOnlyRCDirectBufferException("addRef");
}
public RCDirectBuffer release() {
throw new ReadOnlyRCDirectBufferException("release");
}
public class ReadOnlyRCDirectBufferException extends UnsupportedOperationException {
private static final long serialVersionUID = 1L;
private String operation;
ReadOnlyRCDirectBufferException(String operation) {
this.operation = operation;
}
@Override
public String getMessage() {
return "ReadOnly RCDirectBuffer does not support " + operation + " operation";
}
}
}
}