package voldemort.server.protocol.vold;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import org.apache.log4j.Logger;
import voldemort.VoldemortException;
import voldemort.store.Store;
import voldemort.utils.ByteArray;
import voldemort.utils.ByteUtils;
import voldemort.versioning.VectorClock;
import voldemort.versioning.Versioned;
public abstract class ClientRequestHandler {
private static final Logger logger = Logger.getLogger(VoldemortNativeRequestHandler.class);
protected Store<ByteArray, byte[], byte[]> store;
protected int protocolVersion;
public ClientRequestHandler(Store<ByteArray, byte[], byte[]> store, int protocolVersion) {
this.store = store;
this.protocolVersion = protocolVersion;
}
public abstract boolean parseRequest(DataInputStream inputStream) throws IOException;
public abstract void processRequest() throws VoldemortException;
public abstract void writeResponse(DataOutputStream outputStream) throws IOException;
public abstract int getResponseSize();
public abstract String getDebugMessage();
public static boolean skipByteArrayShort(DataInputStream inputStream, ByteBuffer buffer)
throws VoldemortException, IOException {
int dataSize = inputStream.readShort();
return ByteUtils.skipByteArray(buffer, dataSize);
}
public static boolean skipByteArray(DataInputStream inputStream, ByteBuffer buffer)
throws VoldemortException, IOException {
int dataSize = inputStream.readInt();
return ByteUtils.skipByteArray(buffer, dataSize);
}
public static ByteArray readKey(DataInputStream inputStream) throws IOException {
int keySize = inputStream.readInt();
byte[] key = new byte[keySize];
inputStream.readFully(key);
return new ByteArray(key);
}
public static byte[] readSingleTransform(DataInputStream inputStream, int protocolVersion)
throws IOException {
byte[] transforms = null;
if(protocolVersion > 2) {
if(inputStream.readBoolean())
transforms = readTransforms(inputStream);
}
return transforms;
}
public static byte[] readTransforms(DataInputStream inputStream) throws IOException {
int size = inputStream.readInt();
if(size == 0)
return null;
byte[] transforms = new byte[size];
inputStream.readFully(transforms);
return transforms;
}
public static void writeResults(DataOutputStream outputStream, List<Versioned<byte[]>> values)
throws IOException {
outputStream.writeInt(values.size());
for(Versioned<byte[]> v: values) {
byte[] clock = ((VectorClock) v.getVersion()).toBytes();
byte[] value = v.getValue();
outputStream.writeInt(clock.length + value.length);
outputStream.write(clock);
outputStream.write(value);
}
}
public static int getResultsSize(List<Versioned<byte[]>> values) {
int size = 4;
for(Versioned<byte[]> v: values) {
size += 4;
size += ((VectorClock) v.getVersion()).sizeInBytes();
size += v.getValue().length;
}
return size;
}
public static String getDebugMessageForKey(ByteArray key) {
if(key == null || key.get() == null) {
return "Key: ****Null***";
}
else {
byte[] keyBytes = key.get();
if(keyBytes.length > 256) {
keyBytes = Arrays.copyOfRange(keyBytes, 0, 256);
}
return " Key: " + ByteUtils.toHexString(keyBytes) + " KeySize "
+ key.length();
}
}
public static String getDebugMessageForValue(List<Versioned<byte[]>> values) {
long totalValueSize = 0;
String valueSizeStr = "[";
String valueHashStr = "[";
String versionsStr = "[";
for(Versioned<byte[]> b: values) {
int len = b.getValue().length;
totalValueSize += len;
valueSizeStr += len + ",";
valueHashStr += b.hashCode() + ",";
versionsStr += b.getVersion();
}
valueSizeStr += "]";
valueHashStr += "]";
versionsStr += "]";
return " numResults: " + values.size() + " totalResultSize: " + totalValueSize
+ " resultSizes: " + valueSizeStr + " resultHashes: " + valueHashStr + " versions: "
+ versionsStr;
}
}