use of com.actiontech.dble.backend.mysql.nio.handler.util.HeapItem in project dble by actiontech.
the class MultiNodeSelectHandler method rowResponse.
@Override
public boolean rowResponse(final byte[] row, RowDataPacket rowPacketNull, boolean isLeft, BackendConnection conn) {
if (errorResponse.get() || noNeedRows) {
return true;
}
BlockingQueue<HeapItem> queue = queues.get(conn);
if (queue == null)
return true;
RowDataPacket rp = new RowDataPacket(fieldCount);
rp.read(row);
HeapItem item = new HeapItem(row, rp, (MySQLConnection) conn);
try {
queue.put(item);
} catch (InterruptedException e) {
LOGGER.info("rowResponse error", e);
}
return false;
}
use of com.actiontech.dble.backend.mysql.nio.handler.util.HeapItem in project dble by actiontech.
the class MultiNodeMergeHandler method rowResponse.
@Override
public boolean rowResponse(byte[] row, RowDataPacket rowPacket, boolean isLeft, BackendConnection conn) {
if (terminate.get() || noNeedRows)
return true;
if (isEasyMerge) {
nextHandler.rowResponse(null, rowPacket, this.isLeft, conn);
} else {
MySQLConnection mySQLConn = (MySQLConnection) conn;
BlockingQueue<HeapItem> queue = queues.get(mySQLConn);
if (queue == null)
return true;
HeapItem item = new HeapItem(row, rowPacket, mySQLConn);
try {
queue.put(item);
} catch (InterruptedException e) {
// ignore error
}
}
return false;
}
use of com.actiontech.dble.backend.mysql.nio.handler.util.HeapItem in project dble by actiontech.
the class MultiNodeSelectHandler method ownThreadJob.
private void ownThreadJob() {
try {
ArrayMinHeap<HeapItem> heap = new ArrayMinHeap<>(new Comparator<HeapItem>() {
@Override
public int compare(HeapItem o1, HeapItem o2) {
RowDataPacket row1 = o1.getRowPacket();
RowDataPacket row2 = o2.getRowPacket();
if (row1 == null || row2 == null) {
if (row1 == row2)
return 0;
if (row1 == null)
return -1;
return 1;
}
return rowComparator.compare(row1, row2);
}
});
// init heap
for (Map.Entry<BackendConnection, BlockingQueue<HeapItem>> entry : queues.entrySet()) {
HeapItem firstItem = entry.getValue().take();
heap.add(firstItem);
}
while (!heap.isEmpty()) {
if (isFail())
return;
HeapItem top = heap.peak();
if (top.isNullItem()) {
heap.poll();
} else {
BlockingQueue<HeapItem> topItemQueue = queues.get(top.getIndex());
HeapItem item = topItemQueue.take();
heap.replaceTop(item);
// limit
this.selectRows++;
if (rrs.getLimitSize() >= 0) {
if (selectRows <= rrs.getLimitStart()) {
continue;
} else if (selectRows > (rrs.getLimitStart() < 0 ? 0 : rrs.getLimitStart()) + rrs.getLimitSize()) {
noNeedRows = true;
while (!heap.isEmpty()) {
HeapItem itemToDiscard = heap.poll();
if (!itemToDiscard.isNullItem()) {
BlockingQueue<HeapItem> discardQueue = queues.get(itemToDiscard.getIndex());
while (true) {
if (discardQueue.take().isNullItem() || isFail()) {
break;
}
}
}
}
continue;
}
}
outputHandler.rowResponse(top.getRowData(), top.getRowPacket(), false, top.getIndex());
}
}
Iterator<Map.Entry<BackendConnection, BlockingQueue<HeapItem>>> iterator = this.queues.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<BackendConnection, BlockingQueue<HeapItem>> entry = iterator.next();
entry.getValue().clear();
session.releaseConnectionIfSafe(entry.getKey(), false);
iterator.remove();
}
outputHandler.rowEofResponse(null, false, null);
doSqlStat(session.getSource());
} catch (Exception e) {
String msg = "Merge thread error, " + e.getLocalizedMessage();
LOGGER.info(msg, e);
session.onQueryError(msg.getBytes());
}
}
use of com.actiontech.dble.backend.mysql.nio.handler.util.HeapItem in project dble by actiontech.
the class MultiNodeMergeHandler method terminateThread.
@Override
protected void terminateThread() throws Exception {
for (Entry<MySQLConnection, BlockingQueue<HeapItem>> entry : this.queues.entrySet()) {
// add EOF to signal atoMerge thread
entry.getValue().clear();
entry.getValue().put(new HeapItem(null, null, entry.getKey()));
}
recycleConn();
}
use of com.actiontech.dble.backend.mysql.nio.handler.util.HeapItem in project dble by actiontech.
the class MultiNodeMergeHandler method ownThreadJob.
@Override
protected void ownThreadJob(Object... objects) {
try {
ArrayMinHeap<HeapItem> heap = new ArrayMinHeap<>(new Comparator<HeapItem>() {
@Override
public int compare(HeapItem o1, HeapItem o2) {
RowDataPacket row1 = o1.getRowPacket();
RowDataPacket row2 = o2.getRowPacket();
if (row1 == null || row2 == null) {
if (row1 == row2)
return 0;
if (row1 == null)
return -1;
return 1;
}
return rowComparator.compare(row1, row2);
}
});
// init heap
for (Map.Entry<MySQLConnection, BlockingQueue<HeapItem>> entry : queues.entrySet()) {
HeapItem firstItem = entry.getValue().take();
heap.add(firstItem);
}
while (!heap.isEmpty()) {
if (terminate.get())
return;
HeapItem top = heap.peak();
if (top.isNullItem()) {
heap.poll();
} else {
BlockingQueue<HeapItem> topItemQueue = queues.get(top.getIndex());
HeapItem item = topItemQueue.take();
heap.replaceTop(item);
if (nextHandler.rowResponse(top.getRowData(), top.getRowPacket(), this.isLeft, top.getIndex())) {
noNeedRows = true;
while (!heap.isEmpty()) {
HeapItem itemToDiscard = heap.poll();
if (!itemToDiscard.isNullItem()) {
BlockingQueue<HeapItem> discardQueue = queues.get(itemToDiscard.getIndex());
while (true) {
if (discardQueue.take().isNullItem() || terminate.get()) {
break;
}
}
}
}
}
}
}
if (LOGGER.isInfoEnabled()) {
String executeQueries = getRoutesSql(route);
LOGGER.info(executeQueries + " heap send eof: ");
}
nextHandler.rowEofResponse(null, this.isLeft, queues.keySet().iterator().next());
} catch (Exception e) {
String msg = "Merge thread error, " + e.getLocalizedMessage();
LOGGER.info(msg, e);
session.onQueryError(msg.getBytes());
}
}
Aggregations