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.HConstants;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by wangxiaoyi on 15/6/16.
*/
public class PStoreScanner implements RecordScanner{
private static final Log LOG = LogFactory.getLog(PStoreScanner.class);
protected Store store;
protected ScannerHeap heap;
protected final Scan scan;
// A flag whether use pread for scan
private boolean scanUsePread = false;
protected ReentrantLock lock = new ReentrantLock();
private final long readPt;
public PStoreScanner(Store store, final Scan scan, final long readPt, List<? extends RecordScanner> scanners){
this.store = store;
this.scan = scan;
this.readPt = readPt;
try {
this.heap = new ScannerHeap(scanners);
}catch (IOException ioe){
LOG.error(ioe.getMessage());
}
}
/**
* don't iterate just
*
* @return first element of the scanner
*/
public List<Cell> peek() {
List<Cell> cells = new LinkedList<>();
lock.lock();
try{
if(this.heap == null) return cells;
else cells = this.heap.peek();
}finally {
lock.unlock();
}
return cells;
}
/**
* @return weather there has more record
*/
public boolean hasNext() {
if(this.heap == null || ! this.heap.hasNext()){
close();
return false;
}
lock.lock();
try {
if(! Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW)) {
List<Cell> peek = this.heap.peek();
byte[] peekRow = peek.get(0).getRow();
if(Bytes.compareTo(peekRow, scan.getStopRow()) >= 0){
this.close();
return false;
}
}else {
return this.heap.hasNext();
}
}finally {
lock.unlock();
}
return true;
}
boolean checkReseek(){
return false;
}
/**
* return record
*/
public List<Cell> next() {
List<Cell> result = new LinkedList<>();
lock.lock();
try{
if (checkReseek()) {
return result;
}
result = heap.next();
}finally {
lock.unlock();
}
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.
*/
public void close(){
lock.lock();
try {
// under test, we dont have a this.store
if (this.store != null)
//todo : this.store.deleteChangedReaderObserver(this);
try {
if (this.heap != null)
this.heap.close();
}catch (IOException ioe){
LOG.error(ioe.getMessage());
}
this.heap = null;
//this.lastTop = null; // If both are null, we are closed.
}finally {
lock.unlock();
}
}
/**
* TODO: seek the record by rowkey
*
* @param rowkey
*/
@Override
public void seek(byte[] rowkey) {
}
}