/* * Copyright 2008-2009 LinkedIn, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package voldemort.serialization; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import voldemort.common.VoldemortOpCode; import voldemort.utils.ByteUtils; import voldemort.versioning.VectorClock; import voldemort.versioning.Version; import voldemort.versioning.Versioned; public final class VoldemortOperation { private final byte opCode; private final String key; private final byte[] value; private final VectorClock version; private VoldemortOperation(byte opCode, String key, byte[] value, VectorClock version) { this.opCode = opCode; this.key = key; this.value = value; this.version = version; } public VoldemortOperation(byte[] bytes) { if(bytes == null || bytes.length <= 1) throw new SerializationException("Not enough bytes to serialize"); DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(bytes)); try { this.opCode = inputStream.readByte(); switch(opCode) { case VoldemortOpCode.GET_OP_CODE: this.version = null; this.key = inputStream.readUTF(); this.value = null; break; case VoldemortOpCode.PUT_OP_CODE: this.version = new VectorClock(bytes, 1); this.key = inputStream.readUTF(); int valueSize = inputStream.readInt(); this.value = new byte[valueSize]; ByteUtils.read(inputStream, this.value); break; case VoldemortOpCode.DELETE_OP_CODE: this.version = new VectorClock(bytes, 1); this.key = inputStream.readUTF(); this.value = null; break; default: throw new SerializationException("Unknown opcode: " + bytes[0]); } } catch(IOException e) { throw new SerializationException(e); } } public byte[] getBytes() { try { ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); DataOutputStream output = new DataOutputStream(byteOutput); output.writeByte(opCode); if(opCode != VoldemortOpCode.GET_OP_CODE) output.write(version.toBytes()); output.writeUTF(key); if(opCode == VoldemortOpCode.PUT_OP_CODE) { output.writeInt(value.length); output.write(value); } return byteOutput.toByteArray(); } catch(IOException e) { throw new SerializationException(e); } } public VoldemortOperation makeGetOperation(String key) { return new VoldemortOperation(VoldemortOpCode.GET_OP_CODE, key, null, null); } public VoldemortOperation makePutOperation(String key, Versioned<byte[]> versioned) { return new VoldemortOperation(VoldemortOpCode.PUT_OP_CODE, key, versioned.getValue(), (VectorClock) versioned.getVersion()); } public VoldemortOperation makeDeleteOperation(String key, Version version) { return new VoldemortOperation(VoldemortOpCode.DELETE_OP_CODE, key, null, (VectorClock) version); } }