package aliview.importer; import java.nio.ByteBuffer; import java.util.Arrays; import org.apache.log4j.Logger; public class ByteBufferAutogrow { private static final Logger logger = Logger.getLogger(ByteBufferAutogrow.class); private ByteBuffer backend; private double ALLOCATE_MULTIPLIER = 1.5; private double ALLOCATE_MULTIPLIER_AFTER_100MB = 1.1; private double MB = 1000*1000; private boolean DIRECT_BUFF = false; public ByteBufferAutogrow(int initialCapacity) { if(DIRECT_BUFF){ backend = ByteBuffer.allocateDirect(initialCapacity); }else{ backend = ByteBuffer.allocate(initialCapacity); } } public void append(String more) { if(more == null || more.length() == 0){ return; } byte[] moreBytes = more.getBytes(); // Ensure size if(backend.remaining() < moreBytes.length){ int exactSize = backend.position() + moreBytes.length; double multiplier = ALLOCATE_MULTIPLIER; if(exactSize > 100*MB ){ multiplier = ALLOCATE_MULTIPLIER_AFTER_100MB; } int newCapacity = (int) (exactSize * multiplier); logger.info("newCap=" + newCapacity); reallocate(newCapacity); } backend.put(moreBytes); } public void ensureCapacity(int requestCapacity) { if(requestCapacity > backend.limit()){ reallocate(requestCapacity); } } public void clear(){ backend.clear(); } /* * * method inspired by org.deftserver.io.buffer; * */ // Preserves position. private void reallocate(int newCapacity) { // logger.info("reallocate"); int oldPosition = backend.position(); if(backend.hasArray()){ byte[] newBuffer = new byte[newCapacity]; System.arraycopy(backend.array(), 0, newBuffer, 0, backend.position()); backend = ByteBuffer.wrap(newBuffer); backend.position(oldPosition); }else{ ByteBuffer newOne = ByteBuffer.allocateDirect(newCapacity); int endPos = backend.position(); for(int n = 0; n < endPos; n++){ newOne.put(backend.get(n)); } backend.clear(); backend = newOne; } } public byte[] getBytes(){ if(backend.hasArray()){ return Arrays.copyOfRange(backend.array(), 0, backend.position()); }else{ int length = backend.position(); byte[] retVal = new byte[length]; for(int n = 0; n < retVal.length; n++){ retVal[n] = backend.get(n); } return retVal; } } public String toString(){ return new String(getBytes()); } public int position() { return backend.position(); } }