Packet toBackupAckPacket(long callId, boolean urgent) { byte[] bytes = new byte[BACKUP_RESPONSE_SIZE_IN_BYTES]; writeResponsePrologueBytes(bytes, BACKUP_ACK_RESPONSE, callId, urgent); return newResponsePacket(bytes, urgent); }
Packet toBackupAckPacket(long callId, boolean urgent) { byte[] bytes = new byte[BACKUP_RESPONSE_SIZE_IN_BYTES]; writeResponsePrologueBytes(bytes, BACKUP_ACK_RESPONSE, callId, urgent); return newResponsePacket(bytes, urgent); }
Packet toNormalResponsePacket(long callId, int backupAcks, boolean urgent, Object value) { byte[] bytes; boolean isData = value instanceof Data; if (isData) { Data data = (Data) value; int dataLengthInBytes = data.totalSize(); bytes = new byte[OFFSET_DATA_PAYLOAD + dataLengthInBytes]; writeInt(bytes, OFFSET_DATA_LENGTH, dataLengthInBytes, useBigEndian); // this is a crucial part. If data is NativeMemoryData, instead of calling Data.toByteArray which causes a // byte-array to be created and a intermediate copy of the data, we immediately copy the NativeMemoryData // into the bytes for the packet. data.copyTo(bytes, OFFSET_DATA_PAYLOAD); } else if (value == null) { // since there are many 'null' responses we optimize this case as well. bytes = new byte[OFFSET_NOT_DATA + INT_SIZE_IN_BYTES]; writeInt(bytes, OFFSET_NOT_DATA, CONSTANT_TYPE_NULL, useBigEndian); } else { // for regular object we currently can't guess how big the bytes will be; so we just hand it // over to the serializationService to deal with it. The negative part is that this does lead to // an intermediate copy of the data. bytes = serializationService.toBytes(value, OFFSET_NOT_DATA, false); } writeResponsePrologueBytes(bytes, NORMAL_RESPONSE, callId, urgent); // backup-acks (will fit in a byte) bytes[OFFSET_BACKUP_ACKS] = (byte) backupAcks; // isData bytes[OFFSET_IS_DATA] = (byte) (isData ? 1 : 0); //the remaining part of the byte array is already filled, so we are done. return newResponsePacket(bytes, urgent); }
Packet toNormalResponsePacket(long callId, int backupAcks, boolean urgent, Object value) { byte[] bytes; boolean isData = value instanceof Data; if (isData) { Data data = (Data) value; int dataLengthInBytes = data.totalSize(); bytes = new byte[OFFSET_DATA_PAYLOAD + dataLengthInBytes]; writeInt(bytes, OFFSET_DATA_LENGTH, dataLengthInBytes, useBigEndian); // this is a crucial part. If data is NativeMemoryData, instead of calling Data.toByteArray which causes a // byte-array to be created and a intermediate copy of the data, we immediately copy the NativeMemoryData // into the bytes for the packet. data.copyTo(bytes, OFFSET_DATA_PAYLOAD); } else if (value == null) { // since there are many 'null' responses we optimize this case as well. bytes = new byte[OFFSET_NOT_DATA + INT_SIZE_IN_BYTES]; writeInt(bytes, OFFSET_NOT_DATA, CONSTANT_TYPE_NULL, useBigEndian); } else { // for regular object we currently can't guess how big the bytes will be; so we just hand it // over to the serializationService to deal with it. The negative part is that this does lead to // an intermediate copy of the data. bytes = serializationService.toBytes(value, OFFSET_NOT_DATA, false); } writeResponsePrologueBytes(bytes, NORMAL_RESPONSE, callId, urgent); // backup-acks (will fit in a byte) bytes[OFFSET_BACKUP_ACKS] = (byte) backupAcks; // isData bytes[OFFSET_IS_DATA] = (byte) (isData ? 1 : 0); //the remaining part of the byte array is already filled, so we are done. return newResponsePacket(bytes, urgent); }