content: 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);
  	}
  	
  }
  