package org.fastcatsearch.ir.search;
import java.io.File;
import java.io.IOException;
import org.fastcatsearch.ir.common.IRException;
import org.fastcatsearch.ir.io.BufferedFileInput;
import org.fastcatsearch.ir.io.DataRef;
import org.fastcatsearch.ir.io.IOUtil;
import org.fastcatsearch.ir.io.IndexInput;
import org.fastcatsearch.ir.io.StreamInputRef;
import org.fastcatsearch.ir.settings.FieldSetting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class ReferenceableIndexReader implements ReferenceableReader {
protected static Logger logger = LoggerFactory.getLogger(ReferenceableIndexReader.class);
protected String indexId;
protected IndexInput dataInput;
protected IndexInput multiValueInput;
protected DataRef dataRef;
protected int dataSize;//색인된 한 문서의 필드데이터의 길이
protected boolean isMultiValue;
public ReferenceableIndexReader() {}
public void init(String indexId, FieldSetting refFieldSetting, File dataFile, File multiValueFile, int dataSize) throws IOException, IRException{
this.indexId = indexId;
this.dataSize = dataSize;
dataInput = new BufferedFileInput(dataFile);
isMultiValue = refFieldSetting.isMultiValue();
if(isMultiValue){
multiValueInput = new BufferedFileInput(multiValueFile);
dataRef = new StreamInputRef(multiValueInput, dataSize);
}else{
dataRef = new DataRef(dataSize);
}
// logger.debug("index reader init {}, {}, {}", indexId, dataSize, isMultiValue);
}
@Override
public DataRef getRef() throws IOException{
return dataRef;
}
@Override
public void read(int docNo) throws IOException{
if(isMultiValue){
//multi-value는 위치가 8byte씩 기록되어있다.
dataInput.seek(IOUtil.SIZE_OF_LONG * docNo);
long ptr = dataInput.readLong();
if(ptr != -1){
multiValueInput.seek(ptr);
int count = multiValueInput.readVInt();
// logger.debug("{} ref index read pos {}, seek {}, count {}, {}", indexId, multiValueInput.position(), ptr, count, multiValueInput);
dataRef.init(count);
}else{
dataRef.init(0);
}
}else{
long pos = ((long) dataSize) * docNo;
dataInput.seek(pos);
//이미 input의 position을 움직여 놓았으므로 더이상 아무것도 하지 않는다.
dataInput.readBytes(dataRef.bytesRef().bytes, 0, dataSize);
// logger.debug("fill group data to {} as {}", dataRef, IOUtil.readInt(dataRef.bytesRef().bytes, 0));
dataRef.init(1); //single value는 한개 읽음으로 표시.
}
}
public abstract ReferenceableIndexReader clone();
@Override
public void close() throws IOException {
dataInput.close();
if(isMultiValue && multiValueInput != null){
multiValueInput.close();
}
}
}