package io.mycat.sqlengine.tmp;
import io.mycat.server.packet.RowDataPacket;
import java.util.ArrayList;
import java.util.List;
/**
* 最小堆排序,适用于倒序排序
*
* @author coderczp-2014-12-8
*/
public class MinHeap implements HeapItf {
private RowDataCmp cmp;
private List<RowDataPacket> data;
public MinHeap(RowDataCmp cmp, int size) {
this.cmp = cmp;
this.data = new ArrayList<>();
}
@Override
public void buildHeap() {
int len = data.size();
for (int i = len / 2 - 1; i >= 0; i--) {
heapify(i, len);
}
}
private void heapify(int i, int size) {
int l = left(i);
int r = right(i);
int smallest = i;
if (l < size && cmp.compare(data.get(l), data.get(i)) < 0)
smallest = l;
if (r < size && cmp.compare(data.get(r), data.get(smallest)) < 0)
smallest = r;
if (i == smallest)
return;
swap(i, smallest);
heapify(smallest, size);
}
private int right(int i) {
return (i + 1) << 1;
}
private int left(int i) {
return ((i + 1) << 1) - 1;
}
private void swap(int i, int j) {
RowDataPacket tmp = data.get(i);
RowDataPacket elementAt = data.get(j);
data.set(i, elementAt);
data.set(j, tmp);
}
public RowDataPacket getRoot() {
return data.get(0);
}
public void setRoot(RowDataPacket root) {
data.set(0, root);
heapify(0, data.size());
}
public List<RowDataPacket> getData() {
return data;
}
public void add(RowDataPacket row) {
data.add(row);
}
@Override
public boolean addIfRequired(RowDataPacket row) {
// 淘汰堆里最小的数据
RowDataPacket root = getRoot();
if (cmp.compare(row, root) > 0) {
setRoot(row);
return true;
}
return false;
}
@Override
public void heapSort(int size) {
final int total = data.size();
//容错处理
if (size <= 0 || size > total) {
size = total;
}
final int min = size == total ? 0 : (total - size - 1);
//末尾与头交换,交换后调整最大堆
for (int i = total - 1; i > min; i--) {
swap(0, i);
heapify(0, i);
}
}
}