package org.apache.hadoop.hbase.regionserver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
/**
* Created by wangxiaoyi on 15/6/8.
*
* store the scanner for sorted query
*/
public class ScannerHeap {
private static final Log LOG = LogFactory.getLog(RecordScanner.class);
protected PriorityQueue<RecordScanner> heap = null;
//current scanner
protected RecordScanner curr = null;
protected RecordScannerComparator comparator;
public ScannerHeap(List<? extends RecordScanner> scanners, RecordScannerComparator comparator) throws IOException{
this.comparator = comparator;
if( !scanners.isEmpty()){
this.heap = new PriorityQueue<>(scanners.size(), comparator);
for(RecordScanner scanner : scanners){
if(scanner.peek() != null){
heap.add(scanner);
}else {
scanner.close();
}
}
}
this.curr = getCurrentScanner();
}
public ScannerHeap(List<? extends RecordScanner> scanners) throws IOException{
this.comparator = new RecordScannerComparator();
if( !scanners.isEmpty()){
this.heap = new PriorityQueue<>(scanners.size(), comparator);
for(RecordScanner scanner : scanners){
if(!scanner.peek().isEmpty()){
heap.add(scanner);
} else {
scanner.close();
}
}
}
this.curr = getCurrentScanner();
}
public RecordScanner getCurrentScanner(){
if (curr != null)
return curr;
else {
if(heap != null && !heap.isEmpty())
return heap.poll();
else
return null;
}
}
/**
* don't iterate just
*
* @return first element of the scanner
*/
public List<Cell> peek() {
if(curr == null)
return new LinkedList<>();
else
return curr.peek();
}
/**
* @return weather there has more record
*/
public boolean hasNext() {
if(curr == null)
return false;
else {
return curr.hasNext();
}
}
/**
* return record
*/
public List<Cell> next() {
List<Cell> result = new LinkedList<>();
if(curr != null){
result = curr.next();
if(! curr.hasNext()){
try {
curr.close();
}catch (IOException ioe){
LOG.error(ioe.getMessage());
}
curr = heap.poll();
}else {
RecordScanner topScanner = heap.peek();
List<Cell> nextResult = curr.peek();//下一组数据同 堆顶元素进行比较
if(topScanner != null && Bytes.compareTo(nextResult.get(0).getRow(), topScanner.peek().get(0).getRow()) >= 0){
heap.add(curr);
curr = heap.poll();
}
}
}
return result;
}
/**
* Closes this stream and releases any system resources associated
* with it. If the stream is already closed then invoking this
* method has no effect.
*
* @throws IOException if an I/O error occurs
*/
public void close() throws IOException {
if(curr != null){
curr.close();
}
if(heap != null){
RecordScanner scanner ;
while ((scanner = heap.poll()) != null){
scanner.close();
}
}
}
//todo: seek with rowkey
public boolean seek(byte [] row){
return false;
}
}