use of io.mycat.backend.mysql.MySQLMessage in project Mycat_plus by coderczp.
the class DataNodeMergeManager method run.
@Override
public void run() {
if (!running.compareAndSet(false, true)) {
return;
}
boolean nulpack = false;
try {
for (; ; ) {
final PackWraper pack = packs.poll();
if (pack == null) {
nulpack = true;
break;
}
if (pack == END_FLAG_PACK) {
hasEndFlag = true;
if (packs.peek() != null) {
packs.add(pack);
continue;
}
/**
* 最后一个节点datenode发送了row eof packet说明了整个
* 分片数据全部接收完成,进而将结果集全部发给你Mycat 客户端
*/
final int warningCount = 0;
final EOFPacket eofp = new EOFPacket();
final ByteBuffer eof = ByteBuffer.allocate(9);
BufferUtil.writeUB3(eof, eofp.calcPacketSize());
eof.put(eofp.packetId);
eof.put(eofp.fieldCount);
BufferUtil.writeUB2(eof, warningCount);
BufferUtil.writeUB2(eof, eofp.status);
final ServerConnection source = multiQueryHandler.getSession().getSource();
final byte[] array = eof.array();
Iterator<UnsafeRow> iters = null;
if (unsafeRowGrouper != null) {
/**
* group by里面需要排序情况
*/
if (globalSorter != null) {
iters = unsafeRowGrouper.getResult(globalSorter);
} else {
iters = unsafeRowGrouper.getResult(globalMergeResult);
}
} else if (globalSorter != null) {
iters = globalSorter.sort();
} else if (!isStreamOutputResult) {
iters = globalMergeResult.sort();
}
if (iters != null) {
multiQueryHandler.outputMergeResult(source, array, iters, isMiddleResultDone);
}
break;
}
unsafeRow = new UnsafeRow(fieldCount);
bufferHolder = new BufferHolder(unsafeRow, 0);
unsafeRowWriter = new UnsafeRowWriter(bufferHolder, fieldCount);
bufferHolder.reset();
/**
*构造一行row,将对应的col填充.
*/
MySQLMessage mm = new MySQLMessage(pack.rowData);
mm.readUB3();
mm.read();
int nullnum = 0;
for (int i = 0; i < fieldCount; i++) {
byte[] colValue = mm.readBytesWithLength();
if (colValue != null)
unsafeRowWriter.write(i, colValue);
else {
if (mergeColsIndex != null && mergeColsIndex.length > 0) {
if (Arrays.binarySearch(mergeColsIndex, i) < 0) {
nullnum++;
}
}
unsafeRow.setNullAt(i);
}
}
if (mergeColsIndex != null && mergeColsIndex.length > 0) {
if (nullnum == (fieldCount - mergeColsIndex.length)) {
if (!hasEndFlag) {
packs.add(pack);
continue;
}
}
}
unsafeRow.setTotalSize(bufferHolder.totalSize());
if (unsafeRowGrouper != null) {
unsafeRowGrouper.addRow(unsafeRow);
} else if (globalSorter != null) {
globalSorter.insertRow(unsafeRow);
} else {
globalMergeResult.insertRow(unsafeRow);
}
unsafeRow = null;
bufferHolder = null;
unsafeRowWriter = null;
}
} catch (final Exception e) {
e.printStackTrace();
multiQueryHandler.handleDataProcessException(e);
} finally {
running.set(false);
if (nulpack && !packs.isEmpty()) {
this.run();
}
}
}
use of io.mycat.backend.mysql.MySQLMessage in project Mycat_plus by coderczp.
the class CompressUtil method decompressMysqlPacket.
/**
* 解压数据包,同时做分包处理
*
* @param data
* @param decompressUnfinishedDataQueue
* @return
*/
public static List<byte[]> decompressMysqlPacket(byte[] data, ConcurrentLinkedQueue<byte[]> decompressUnfinishedDataQueue) {
MySQLMessage msg = new MySQLMessage(data);
// 包头
// -----------------------------------------
// 压缩的包长
int packetLength = msg.readUB3();
// 压缩的包号
byte packetId = msg.read();
// 压缩前的长度
int oldLen = msg.readUB3();
// 未压缩, 直接返回
if (packetLength == data.length - 4) {
return Lists.newArrayList(data);
// 压缩不成功的, 直接返回
} else if (oldLen == 0) {
byte[] readBytes = msg.readBytes();
return splitPack(readBytes, decompressUnfinishedDataQueue);
// 解压
} else {
byte[] de = decompress(data, 7, data.length - 7);
return splitPack(de, decompressUnfinishedDataQueue);
}
}
use of io.mycat.backend.mysql.MySQLMessage in project Mycat_plus by coderczp.
the class CompressUtil method compressMysqlPacket.
/**
* 压缩数据包
* @param data
* @param con
* @param compressUnfinishedDataQueue
* @return
*/
private static ByteBuffer compressMysqlPacket(byte[] data, AbstractConnection con, ConcurrentLinkedQueue<byte[]> compressUnfinishedDataQueue) {
ByteBuffer byteBuf = con.allocate();
// TODO: 数据量大的时候, 此处是是性能的堵点
byteBuf = con.checkWriteBuffer(byteBuf, data.length, false);
MySQLMessage msg = new MySQLMessage(data);
while (msg.hasRemaining()) {
// 包体的长度
int packetLength = 0;
// 可读的长度
int readLength = msg.length() - msg.position();
if (readLength > 3) {
packetLength = msg.readUB3();
msg.move(-3);
}
// 校验数据包完整性
if (readLength < packetLength + 4) {
byte[] packet = msg.readBytes(readLength);
if (packet.length != 0) {
// 不完整的包
compressUnfinishedDataQueue.add(packet);
}
} else {
byte[] packet = msg.readBytes(packetLength + 4);
if (packet.length != 0) {
if (packet.length <= NO_COMPRESS_PACKET_LENGTH) {
// 压缩长度
BufferUtil.writeUB3(byteBuf, packet.length);
// 压缩序号
byteBuf.put(packet[3]);
// 压缩前的长度设置为0
BufferUtil.writeUB3(byteBuf, 0);
// 包体
byteBuf.put(packet);
} else {
// 压缩
byte[] compress = compress(packet);
BufferUtil.writeUB3(byteBuf, compress.length);
byteBuf.put(packet[3]);
BufferUtil.writeUB3(byteBuf, packet.length);
byteBuf.put(compress);
}
}
}
}
return byteBuf;
}
use of io.mycat.backend.mysql.MySQLMessage in project Mycat-Server by MyCATApache.
the class CommandPacket method read.
public void read(byte[] data) {
MySQLMessage mm = new MySQLMessage(data);
packetLength = mm.readUB3();
packetId = mm.read();
command = mm.read();
arg = mm.readBytes();
}
use of io.mycat.backend.mysql.MySQLMessage in project Mycat-Server by MyCATApache.
the class HandshakePacket method read.
public void read(byte[] data) {
MySQLMessage mm = new MySQLMessage(data);
packetLength = mm.readUB3();
packetId = mm.read();
protocolVersion = mm.read();
serverVersion = mm.readBytesWithNull();
threadId = mm.readUB4();
seed = mm.readBytesWithNull();
serverCapabilities = mm.readUB2();
serverCharsetIndex = mm.read();
serverStatus = mm.readUB2();
mm.move(13);
restOfScrambleBuff = mm.readBytesWithNull();
}
Aggregations