Author: costin Date: Wed Apr 23 07:26:07 2008 New Revision: 650885 URL: http://svn.apache.org/viewvc?rev=650885&view=rev Log: Add 'Appendable' to ByteChunk.
Temp. add a BufferInfo to collect data about buffer usage ( could do it with a profiler, seems nicer via JMX ). I may remove this before proposing to trunk. Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/BufferInfo.java (with props) Modified: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/ByteChunk.java (contents, props changed) tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/CharChunk.java (contents, props changed) Added: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/BufferInfo.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/BufferInfo.java?rev=650885&view=auto ============================================================================== --- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/BufferInfo.java (added) +++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/BufferInfo.java Wed Apr 23 07:26:07 2008 @@ -0,0 +1,67 @@ +/* + */ +package org.apache.tomcat.util.buf; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * For JMX - to see how many buffers we use. + * + * @author Costin Manolache + */ +public class BufferInfo { + static BufferInfo singleton = new BufferInfo(); + + // TODO: pass a 'domain' to identify where it's used. + // TODO: store an instance of BufferInfo in ByteChunk ? + // TODO: record destructions + public static BufferInfo get() { + return singleton; + } + + AtomicInteger allocatedBChunks = new AtomicInteger(); + AtomicInteger allocatedBChunksLazy = new AtomicInteger(); + AtomicInteger growBChunks = new AtomicInteger(); + AtomicInteger allocatedBChunksBytes = new AtomicInteger(); + AtomicInteger totalBChunks = new AtomicInteger(); + + AtomicInteger allocatedCChunks = new AtomicInteger(); + AtomicInteger growCChunks = new AtomicInteger(); + AtomicInteger allocatedCChunksBytes = new AtomicInteger(); + AtomicInteger allocatedCChunksLazy = new AtomicInteger(); + AtomicInteger totalCChunks = new AtomicInteger(); + + public int getAllocatedBChunks() { + return allocatedBChunks.get(); + } + public int getGrowBChunks() { + return growBChunks.get(); + } + public int getGrowCChunks() { + return growCChunks.get(); + } + public int getAllocatedBChunksBytes() { + return allocatedBChunksBytes.get(); + } + public int getAllocatedBChunksLazy() { + return allocatedBChunksLazy.get(); + } + public int getAllocatedCChunksLazy() { + return allocatedCChunksLazy.get(); + } + + + public int getTotalBChunks() { + return totalBChunks.get(); + } + public int getAllocatedCChunks() { + return allocatedCChunks.get(); + } + public int getAllocatedCChunksBytes() { + return allocatedCChunksBytes.get(); + } + public int getWrappedCChunks() { + return totalCChunks.get(); + } + +} Propchange: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/BufferInfo.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/ByteChunk.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/ByteChunk.java?rev=650885&r1=650884&r2=650885&view=diff ============================================================================== --- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/ByteChunk.java (original) +++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/ByteChunk.java Wed Apr 23 07:26:07 2008 @@ -63,7 +63,7 @@ * @author Costin Manolache * @author Remy Maucherat */ -public final class ByteChunk implements Cloneable, Serializable, CharSequence { +public final class ByteChunk implements Cloneable, Serializable, CharSequence, Appendable { /** Input interface, used when the buffer is emptiy * @@ -117,7 +117,7 @@ private ByteInputChannel in = null; private ByteOutputChannel out = null; - private boolean isOutput=false; + private boolean isOutput=false; // more like 'owns buffer' private boolean optimizedWrite=true; ByteBuffer bb = null; @@ -125,10 +125,12 @@ * Creates a new, uninitialized ByteChunk object. */ public ByteChunk() { + BufferInfo.get().totalBChunks.incrementAndGet(); } public ByteChunk( int initial ) { - allocate( initial, -1 ); + BufferInfo.get().totalBChunks.incrementAndGet(); + allocate( initial, -1 ); } //-------------------- @@ -192,15 +194,16 @@ * Resets the message buff to an uninitialized state. */ public void recycle() { - // buff = null; - enc=null; + // buff remails allocated, just offsest change + enc=null; start=0; end=0; isSet=false; } public void reset() { - buff=null; + isOutput = false; + buff=null; } // -------------------- Setup -------------------- @@ -209,6 +212,8 @@ isOutput=true; if( buff==null || buff.length < initial ) { buff=new byte[initial]; + BufferInfo.get().allocatedBChunksBytes.addAndGet(initial); + BufferInfo.get().allocatedBChunks.addAndGet(1); } this.limit=limit; start=0; @@ -224,6 +229,7 @@ * @param len the length of the bytes */ public void setBytes(byte[] b, int off, int len) { + isOutput = false; buff = b; start = off; end = start+ len; @@ -324,13 +330,15 @@ // -------------------- Adding data to the buffer -------------------- /** Append a char, by casting it to byte. This IS NOT intended for unicode. * + * TODO: throw an exception or support UTF8 if c is not ascii * @param c * @throws IOException */ - public void append( char c ) + public Appendable append( char c ) throws IOException { - append( (byte)c); + append((byte)c); + return this; } public void append( byte b ) @@ -346,9 +354,16 @@ } public void append( ByteChunk src ) - throws IOException + throws IOException + { + append( src.getBytes(), src.getStart(), src.getLength()); + } + + public void append( ByteChunk src, int start, int end) + throws IOException { - append( src.getBytes(), src.getStart(), src.getLength()); + append( src.getBytes(), src.getStart() + start, + end - start); } /** Add data to the buffer @@ -431,18 +446,39 @@ public int substract(ByteChunk src) throws IOException { - if ((end - start) == 0) { - if (in == null) - return -1; - int n = in.realReadBytes( buff, 0, buff.length ); - if (n < 0) - return -1; - } + if ((end - start) == 0) { + if (in == null) + return -1; + int n = in.realReadBytes( buff, 0, buff.length ); + if (n < 0) + return -1; + } + + int len = getLength(); + src.append(buff, start, len); + start = end; + return len; + + } + + public int substract(ByteChunk src, int max) + throws IOException { - int len = getLength(); - src.append(buff, start, len); - start = end; - return len; + if ((end - start) == 0) { + if (in == null) + return -1; + int n = in.realReadBytes( buff, 0, buff.length ); + if (n < 0) + return -1; + } + + int len = getLength(); + if (len > max) { + len = max; + } + src.append(buff, start, len); + start += len; + return len; } @@ -504,6 +540,8 @@ if( buff==null ) { if( desiredSize < 256 ) desiredSize=256; // take a minimum buff=new byte[desiredSize]; + BufferInfo.get().allocatedBChunksBytes.addAndGet(desiredSize); + BufferInfo.get().allocatedBChunksLazy.addAndGet(1); } // limit < buf.length ( the buffer is already big ) @@ -523,7 +561,7 @@ newSize > limit ) newSize=limit; tmp=new byte[newSize]; } - + BufferInfo.get().growBChunks.addAndGet(newSize - buff.length); System.arraycopy(buff, start, tmp, 0, end-start); buff = tmp; tmp = null; @@ -726,22 +764,27 @@ } public int indexOf( String src, int srcOff, int srcLen, int myOff ) { - char first=src.charAt( srcOff ); + char first=src.charAt( srcOff ); - // Look for first char - int srcEnd = srcOff + srcLen; + // Look for first char + int srcEnd = srcOff + srcLen; - for( int i=myOff+start; i <= (end - srcLen); i++ ) { - if( buff[i] != first ) continue; - // found first char, now look for a match + for( int i=myOff+start; i <= (end - srcLen); i++ ) { + if( buff[i] != first ) continue; + // found first char, now look for a match int myPos=i+1; - for( int srcPos=srcOff + 1; srcPos< srcEnd; ) { + for( int srcPos=srcOff + 1; srcPos< srcEnd; ) { if( buff[myPos++] != src.charAt( srcPos++ )) - break; + break; if( srcPos==srcEnd ) return i-start; // found it - } - } - return -1; + } + } + return -1; + } + + public int indexOfIngoreCase(ByteChunk toFind, int off) { + return indexOfIgnoreCase(buff, start + off, end, + toFind.getBuffer(), toFind.getStart(), toFind.getEnd()); } // -------------------- Hash code -------------------- @@ -804,6 +847,46 @@ return -1; } + public static int indexOfIgnoreCase( byte[] buff, int start, int end, + byte[] toFind, int toFindOff, int toFindLen ) { + byte first = toFind[0]; + // Look for first char + int toFindEnd = toFindLen + toFindOff; + int searchEnd = end - toFindLen; + + for (int i = start; i <= searchEnd; i++) { + if (Ascii.toLower(buff[i]) != first) continue; + // found first char, now look for a match + int myPos = i+1; + for (int srcPos = toFindOff + 1; srcPos < toFindEnd; ) { + if (Ascii.toLower(buff[myPos++]) != toFind[srcPos++]) + break; + if (srcPos == toFindEnd) return i - start; // found it + } + } + return -1; + } + + public static int indexOfIgnoreCase( byte[] buff, int start, int end, + char[] toFind, int toFindOff, int toFindEnd ) { + char first = toFind[0]; + // Look for first char + int toFindLen = toFindEnd - toFindOff; + int searchEnd = end - toFindLen; + + for (int i = start; i <= searchEnd; i++) { + if (Ascii.toLower(buff[i]) != first) continue; + // found first char, now look for a match + int myPos = i+1; + for (int srcPos = toFindOff + 1; srcPos < toFindEnd; ) { + if (Ascii.toLower(buff[myPos++]) != toFind[srcPos++]) + break; + if (srcPos == toFindEnd) return i - start; // found it + } + } + return -1; + } + /** Find a character, no side effects. * @return index of char if found, -1 if not */ @@ -862,7 +945,8 @@ /** - * Convert specified String to a byte array. This ONLY WORKS for ascii, UTF chars will be truncated. + * Convert specified String to a byte array. This ONLY WORKS for ascii, UTF + * chars will be truncated. * * @param value to convert to byte array * @return the byte array value @@ -874,6 +958,13 @@ } return result; } + + public static ByteChunk fromString(String value) { + byte[] buff = convertToBytes(value); + ByteChunk res = new ByteChunk(); + res.setBytes(buff, 0, buff.length); + return res; + } // --------- To make it easier to use - same-name methods with ByteBuffer public char charAt(int index) { @@ -893,6 +984,27 @@ if (seqEnd + start > end) res.setBytes(buff, start + seqStart, start + seqEnd); return res; + } + + public Appendable append(CharSequence csq) throws IOException { + if (csq instanceof ByteChunk) { + append((ByteChunk) csq); + } + for (int i = 0; i < csq.length(); i++) { + append(csq.charAt(i)); + } + return this; + } + + public Appendable append(CharSequence csq, int start, int end) + throws IOException { + if (csq instanceof ByteChunk) { + append((ByteChunk) csq, start, end); + } + for (int i = start; i < end; i++) { + append(csq.charAt(i)); + } + return this; } } Propchange: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/ByteChunk.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/CharChunk.java URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/CharChunk.java?rev=650885&r1=650884&r2=650885&view=diff ============================================================================== --- tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/CharChunk.java (original) +++ tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/CharChunk.java Wed Apr 23 07:26:07 2008 @@ -79,10 +79,12 @@ * Creates a new, uninitialized CharChunk object. */ public CharChunk() { + BufferInfo.get().totalCChunks.incrementAndGet(); } public CharChunk(int size) { - allocate( size, -1 ); + BufferInfo.get().totalCChunks.incrementAndGet(); + allocate( size, -1 ); } // -------------------- @@ -120,6 +122,8 @@ isOutput=true; if( buff==null || buff.length < initial ) { buff=new char[initial]; + BufferInfo.get().allocatedCChunksBytes.addAndGet(initial); + BufferInfo.get().allocatedCChunks.addAndGet(1); } this.limit=limit; start=0; @@ -460,6 +464,8 @@ if( buff==null ) { if( desiredSize < 256 ) desiredSize=256; // take a minimum buff=new char[desiredSize]; + BufferInfo.get().allocatedCChunksBytes.addAndGet(desiredSize); + BufferInfo.get().allocatedCChunksLazy.addAndGet(1); } // limit < buf.length ( the buffer is already big ) @@ -479,7 +485,7 @@ newSize > limit ) newSize=limit; tmp=new char[newSize]; } - + BufferInfo.get().growBChunks.addAndGet(newSize - buff.length); System.arraycopy(buff, start, tmp, start, end-start); buff = tmp; tmp = null; Propchange: tomcat/sandbox/tomcat-lite/tomcat-coyote/org/apache/tomcat/util/buf/CharChunk.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]