use of org.apache.phoenix.util.TrustedByteArrayOutputStream in project phoenix by apache.
the class PhoenixIndexBuilder method combineOnDupKey.
public static byte[] combineOnDupKey(byte[] oldOnDupKeyBytes, byte[] newOnDupKeyBytes) {
// If new ON DUPLICATE KEY is null, then reset back to null
if (oldOnDupKeyBytes == null || newOnDupKeyBytes == null) {
if (newOnDupKeyBytes == null) {
return newOnDupKeyBytes;
}
return doNotSkipFirstOnDupKey(newOnDupKeyBytes);
}
// then we can just keep that one as the new one has no impact.
if (isDupKeyIgnore(newOnDupKeyBytes)) {
return oldOnDupKeyBytes;
}
boolean isOldDupKeyIgnore = isDupKeyIgnore(oldOnDupKeyBytes);
try (TrustedByteArrayOutputStream stream = new TrustedByteArrayOutputStream(Math.max(0, oldOnDupKeyBytes.length - ON_DUP_KEY_HEADER_BYTE_SIZE) + newOnDupKeyBytes.length);
ByteArrayInputStream oldStream = new ByteArrayInputStream(oldOnDupKeyBytes);
ByteArrayInputStream newStream = new ByteArrayInputStream(newOnDupKeyBytes);
DataOutputStream output = new DataOutputStream(stream);
DataInputStream oldInput = new DataInputStream(oldStream);
DataInputStream newInput = new DataInputStream(newStream)) {
boolean execute1 = oldInput.readBoolean();
// ignore
newInput.readBoolean();
int repeating2 = newInput.readShort();
if (isOldDupKeyIgnore) {
// Will force subsequent ON DUPLICATE KEY UPDATE statement to execute
output.writeBoolean(false);
output.writeShort(repeating2);
output.write(newOnDupKeyBytes, ON_DUP_KEY_HEADER_BYTE_SIZE, newOnDupKeyBytes.length - ON_DUP_KEY_HEADER_BYTE_SIZE);
} else {
int repeating1 = oldInput.readShort();
if (Bytes.compareTo(oldOnDupKeyBytes, ON_DUP_KEY_HEADER_BYTE_SIZE, oldOnDupKeyBytes.length - ON_DUP_KEY_HEADER_BYTE_SIZE, newOnDupKeyBytes, Bytes.SIZEOF_SHORT + Bytes.SIZEOF_BOOLEAN, newOnDupKeyBytes.length - ON_DUP_KEY_HEADER_BYTE_SIZE) == 0) {
// If both old and new ON DUPLICATE KEY UPDATE clauses match,
// reduce the size of data we're sending over the wire.
// TODO: optimization size of RPC more.
output.writeBoolean(execute1);
output.writeShort(repeating1 + repeating2);
output.write(newOnDupKeyBytes, ON_DUP_KEY_HEADER_BYTE_SIZE, newOnDupKeyBytes.length - ON_DUP_KEY_HEADER_BYTE_SIZE);
} else {
output.writeBoolean(execute1);
// retain first ON DUPLICATE KEY UPDATE having repeated
output.writeShort(repeating1);
output.write(oldOnDupKeyBytes, ON_DUP_KEY_HEADER_BYTE_SIZE, oldOnDupKeyBytes.length - ON_DUP_KEY_HEADER_BYTE_SIZE);
// statement is effected by the repeating amount
for (int i = 0; i < repeating2; i++) {
output.write(newOnDupKeyBytes, ON_DUP_KEY_HEADER_BYTE_SIZE, newOnDupKeyBytes.length - ON_DUP_KEY_HEADER_BYTE_SIZE);
}
}
}
return stream.toByteArray();
} catch (IOException e) {
// Shouldn't be possible with ByteInput/Output streams
throw new RuntimeException(e);
}
}
Aggregations