package com.alimama.mdrill.fdtBlockCompress; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.RAMOutputStream; //FieldsWriter public class FdtCompressIndexOutput extends IndexOutput { private static final Log LOG = LogFactory.getLog(FdtCompressIndexOutput.class); private IndexOutput output; private RAMOutputStream ramoutput; private boolean isNeedFlush=false; private int blocksize=1024*512; public FdtCompressIndexOutput(IndexOutput output,int blocksize) { this.output = output; this.blocksize=blocksize; this.ramoutput=new RAMOutputStream(); isNeedFlush=false; } @Override public void flush() throws IOException { this.output.flush(); this.ramoutput.flush(); } private void syncBlock() throws IOException { if(this.isNeedFlush) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(bos); // long size=this.ramoutput.getFilePointer(); this.ramoutput.writeTo(gzip); gzip.finish(); gzip.close(); byte[] b = bos.toByteArray(); bos.close(); this.output.writeVInt(b.length); this.output.writeBytes(b, 0,b.length); this.ramoutput=new RAMOutputStream(); this.isNeedFlush=false; // LOG.info(b.length+"@"+size+","+this.output.getFilePointer()); } } @Override public void close() throws IOException { this.syncBlock(); this.output.close(); this.ramoutput.close(); } @Override public long getFilePointer() { long rtn= (this.output.getFilePointer()<<24)+this.ramoutput.getFilePointer(); return rtn; } @Override public void seek(long pos) throws IOException { throw new RuntimeException("not allowed"); } @Override public long length() throws IOException { throw new RuntimeException("not allowed"); } @Override public void writeByte(byte b) throws IOException { this.ramoutput.writeByte(b); this.isNeedFlush=true; if(this.ramoutput.getFilePointer()>this.blocksize) { this.syncBlock(); } } @Override public void writeBytes(byte[] b, int offset, int length) throws IOException { int begin=offset; int end=offset+length; while(begin<end) { int size=Math.min(1024, end-begin); this.ramoutput.writeBytes(b, begin, size); this.isNeedFlush=true; if(this.ramoutput.getFilePointer()>this.blocksize) { this.syncBlock(); } begin+=size; } } }