package com.alibaba.doris.dataserver.store.log.db.impl;
import java.io.IOException;
import java.nio.ByteBuffer;
import com.alibaba.doris.dataserver.store.log.LogStorageException;
import com.alibaba.doris.dataserver.store.log.db.ClumpConfigure;
import com.alibaba.doris.dataserver.store.log.db.LogClumpHead;
import com.alibaba.doris.dataserver.store.log.db.LogFile;
import com.alibaba.doris.dataserver.store.log.db.ReadWindow;
import com.alibaba.doris.dataserver.store.log.db.LogFile.AccessMode;
import com.alibaba.doris.dataserver.store.log.entry.ClumpHeadEntry;
import com.alibaba.doris.dataserver.store.log.entry.LogEntry;
import com.alibaba.doris.dataserver.store.log.serialize.LogSerializer;
import com.alibaba.doris.dataserver.store.log.serialize.LogSerializerFactory;
import com.alibaba.doris.dataserver.store.log.utils.LogFileUtil;
/**
* @author ajun Email:jack.yuj@alibaba-inc.com
*/
public class DefaultReadWindowImpl implements ReadWindow {
public DefaultReadWindowImpl(ClumpConfigure config, String clumpName) {
this.config = config;
this.clumpName = clumpName;
this.bufferSize = config.getReadBufferSize();
this.readBuffer = ByteBuffer.allocate(bufferSize);
this.readBuffer.flip();
prepare();
}
private void prepare() {
head = new DefaultLogClumpHeadImpl(config, clumpName);
head.loadLogHeader();
ClumpHeadEntry headEntry = head.getClumpHeadEntry();
this.serializer = LogSerializerFactory.getInstance().getSerializer(headEntry.getLogFileVersion());
logData = new LogFile(LogFileUtil.generateDataFileName(config.getPath(), clumpName));
try {
logData.open(AccessMode.R);
} catch (IOException e) {
throw new LogStorageException(e);
}
}
public boolean hasNext() {
if (readBuffer.hasRemaining()) {
return true;
} else {
return logData.isEOF() == false && head.getClumpHeadEntry().getVnodeNum() > 0;
}
}
public LogEntry next() {
LogEntry entry = null;
boolean needBreak = false;
do {
if (readBuffer.hasRemaining()) {
entry = serializer.readLogEntry(readBuffer);
if (null != entry) {
return entry;
}
}
if (!needBreak) {
fillBuffer();
needBreak = true;
} else {
break;
}
} while (true);
// TODO: But The better way maybe we need throw one exception, is it right?
return null;
}
public void close() {
logData.close();
}
public long size() {
return logData.length();
}
private void fillBuffer() {
readBuffer.compact();
try {
logData.read(readBuffer);
readBuffer.flip();
} catch (IOException e) {
throw new LogStorageException(e);
}
}
private LogFile logData;
private ByteBuffer readBuffer;
private int bufferSize;
private LogClumpHead head;
private ClumpConfigure config;
private LogSerializer serializer;
private String clumpName;
}