package org.apache.lucene.index;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map.Entry;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.OpenBitSet;
import org.apache.solr.request.BlockBufferPool;
import org.apache.solr.request.BlockBufferPool.BlockArray;
import org.apache.solr.search.BitDocSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DocValuesWriteImpl implements DocValuesWriter{
// public static Logger log = LoggerFactory.getLogger(DocValuesWriteImpl.class);
private static int TERM_NULL_NUMBER=-1;
public IndexOutput outputQuickTis = null;
public IndexOutput outputQuickTisTxt = null;
public IndexOutput outputQuickTisVal = null;
private HashMap<Integer, Long> fieldPosTis = new HashMap<Integer, Long>();
private HashMap<Integer, Long> fieldPosTisTxt = new HashMap<Integer, Long>();
private HashMap<Integer, Long> fieldPosTisVal = new HashMap<Integer, Long>();
public int current_alloc_size = BlockBufferPool.interval;
private BlockArray<Integer> doc2Tm = BlockBufferPool.INT_POOL.calloc(current_alloc_size, BlockBufferPool.INT_CREATE, TERM_NULL_NUMBER);
// BitDocSet bits = new BitDocSet(new OpenBitSet(10000000));
private int maxdocid=0;
public void collectDoc(int docid, int termNum) {
if (this.current_alloc_size <= docid) {
this.current_alloc_size = docid + BlockBufferPool.interval;
this.doc2Tm = BlockBufferPool.INT_POOL.reCalloc(this.doc2Tm,this.current_alloc_size, BlockBufferPool.INT_CREATE, TERM_NULL_NUMBER);
}
maxdocid=Math.max(maxdocid, docid);
doc2Tm.set(docid, termNum);
// bits.add(docid);
}
public void collectTmIndex(String termValue) throws IOException {
outputQuickTisTxt.writeString(termValue);
}
public void collectTm(long termValue) throws IOException {
outputQuickTisVal.writeLong(termValue);
}
String fl="";
public void start(int fieldNumber,String field) {
this.fl=field;
// log.info("start:"+this.fl+"@"+fieldNumber);
this.maxdocid=0;
outputQuickTis.startBits();
fieldPosTis.put(fieldNumber, outputQuickTis.getFilePointer());
fieldPosTisTxt.put(fieldNumber, outputQuickTisTxt.getFilePointer());
fieldPosTisVal.put(fieldNumber, outputQuickTisVal.getFilePointer());
// bits = new BitDocSet(new OpenBitSet(10000000));
// debugindex=0;
}
// int debugindex=0;
public void flushFieldDoc(int termNumCount) throws IOException {
int size=Math.min(doc2Tm.getSize(), (maxdocid+1));
outputQuickTis.writeInt(size);
outputQuickTis.writeInt(termNumCount);
int useBits=useBits(termNumCount);
outputQuickTis.writeInt(useBits);
for(int i=0;i<size;i++)
{
int tm=doc2Tm.get(i);
if(tm==TERM_NULL_NUMBER||tm<0||tm>=termNumCount)
{
// if(debugindex++<200)
// {
// log.info("flushFieldDoc:"+i+","+tm+","+termNumCount+","+bits.exists(i));
// }
outputQuickTis.writeBits(termNumCount,useBits);
}else{
outputQuickTis.writeBits(tm,useBits);
}
}
outputQuickTis.flushBits();
BlockBufferPool.INT_POOL.allset(this.doc2Tm, BlockBufferPool.INT_CREATE, TERM_NULL_NUMBER);
}
public static int useBits(int tm)
{
for(int i=1;i<32;i++)
{
if((tm >> i)==0)
{
return i;
}
}
return 32;
}
public void flushPosTo(IndexOutput outputSize) throws IOException {
outputSize.writeInt(fieldPosTis.size());
for (Entry<Integer, Long> e : fieldPosTis.entrySet()) {
outputSize.writeInt(e.getKey());
outputSize.writeLong(e.getValue());
}
outputSize.writeInt(fieldPosTisTxt.size());
for (Entry<Integer, Long> e : fieldPosTisTxt.entrySet()) {
outputSize.writeInt(e.getKey());
outputSize.writeLong(e.getValue());
}
outputSize.writeInt(fieldPosTisVal.size());
for (Entry<Integer, Long> e : fieldPosTisVal.entrySet()) {
outputSize.writeInt(e.getKey());
outputSize.writeLong(e.getValue());
}
}
protected void finalize() throws Throwable {
super.finalize();
this.free();
}
public void free() {
BlockBufferPool.INT_POOL.recycleByteBlocks(this.doc2Tm);
}
@Override
public void close() throws IOException {
IOUtils.closeWhileHandlingException(outputQuickTis,outputQuickTisTxt,outputQuickTisVal);
}
}