BEA Systems, Inc.

WebLogic Server 6.1 API Reference

weblogic.apache.xml.utils
Class FastStringBuffer

java.lang.Object
  |
  +--weblogic.apache.xml.utils.FastStringBuffer

public class FastStringBuffer
extends java.lang.Object

Bare-bones, unsafe, fast string buffer. No thread-safety, no parameter range checking, exposed fields. Note that in typical applications, thread-safety of a StringBuffer is a somewhat dubious concept in any case.

Note that Stree is using a single FastStringBuffer as a string pool, by recording start and length indices within a single buffer. This minimizes heap overhead, but of course requires more work when retrieving the data.

This has been recoded to operate as a "chunked buffer". Doing so reduces (or, when initial chunk size equals max chunk size, eliminates) the need to recopy existing information when an append exceeds the space available; we just allocate another chunk and flow across to it. (The array of chunks may need to grow, admittedly, but that's a much smaller object.) Some excess recopying may arise when we extract Strings which cross chunk boundaries; larger chunks make that less frequent.

The size values are parameterized, to allow tuning this code. In theory, RTFs might want to be tuned differently from the main document's text.

STATUS: I'm not getting as much performance gain out of this as I'd hoped, nor is the relationship between the tuning parameters and performance particularly intuitive. Under some conditions I do seem to be able to knock up to 19% off the execution time for our largest testcases, which is certainly nontrivial... but that same setting (fixed 1024-byte chunking for both main tree and RTFs) seems to _add_ that much proportional overhead to some of the smaller ones. We need to understand this better, improve the parameter selection/growth heuristics, and perhaps (if all else fails) consider exposing those parameters for advanced users to fiddle with as suits their needs.

Author:
Copyright © 2001 BEA Systems, Inc. All Rights Reserved.

Constructor Summary
FastStringBuffer()
          Construct a FastStringBuffer, using a default allocation policy.
FastStringBuffer(int initialAllocationUnit)
          Construct a FastStringBuffer, using the specified initial unit.
FastStringBuffer(int initialChunkBits, int chunkBits)
          Construct a FastStringBuffer, with allocation policy as per parameters.
 
Method Summary
 void append(char value)
          Append a single character onto the FastStringBuffer, growing the storage if necessary.
 void append(char[] chars, int start, int length)
          Append part of the contents of a Character Array onto the FastStringBuffer, growing the storage if necessary.
 void append(FastStringBuffer value)
          Append the contents of another FastStringBuffer onto this FastStringBuffer, growing the storage if necessary.
 void append(java.lang.String value)
          Append the contents of a String onto the FastStringBuffer, growing the storage if necessary.
 void append(java.lang.StringBuffer value)
          Append the contents of a StringBuffer onto the FastStringBuffer, growing the storage if necessary.
 java.lang.String getString(int start, int length)
           
 boolean isWhitespace(int start, int length)
           
 int length()
          Get the length of the list.
 void reset()
          Discard the content of the FastStringBuffer.
 void sendSAXcharacters(org.xml.sax.ContentHandler ch, int start, int length)
          Sends the specified range of characters as one or more SAX characters() events.
 void setLength(int l)
          Directly set how much of the FastStringBuffer's storage is to be considered part of its content.
 int size()
          Get the length of the list.
 java.lang.String toString()
          Note that this operation has been somewhat deoptimized by the shift to a chunked array, as there is no factory method to produce a String object directly from an array of arrays and hence a double copy is needed.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

FastStringBuffer

public FastStringBuffer(int initialChunkBits,
                        int chunkBits)
Construct a FastStringBuffer, with allocation policy as per parameters.

For coding convenience, I've expressed both allocation sizes in terms of a number of bits. That's needed for the final size of a chunk, to permit fast and efficient shift-and-mask addressing. It's less critical for the inital size, and may be reconsidered.

An alternative would be to accept integer sizes and round to powers of two; that's under consideration.

Parameters:
initialChunkBits - Length in characters of the initial allocation of a chunk, expressed in log-base-2. (That is, 10 means allocate 1024 characters.) Later chunks will use larger allocation units, to trade off allocation speed of large document against storage efficiency of small ones.
chunkBits - Number of character-offset bits that should be used for addressing within a chunk. Maximum length of a chunk is 2^chunkBits characters.

FastStringBuffer

public FastStringBuffer()
Construct a FastStringBuffer, using a default allocation policy.

FastStringBuffer

public FastStringBuffer(int initialAllocationUnit)
Construct a FastStringBuffer, using the specified initial unit. Resembles the previous version of this code.

ISSUE: Should this be considered initial size, or fixed size? Now configured as initial.

Parameters:
chunkSize - Characters per chunk; will round up to power of 2.
Method Detail

size

public final int size()
Get the length of the list. Synonym for length().

Returns:
the number of characters in the FastStringBuffer's content.

length

public final int length()
Get the length of the list. Synonym for size().

Returns:
the number of characters in the FastStringBuffer's content.

reset

public final void reset()
Discard the content of the FastStringBuffer. Does _not_ release any of the storage space.

setLength

public final void setLength(int l)
Directly set how much of the FastStringBuffer's storage is to be considered part of its content. This is a fast but hazardous operation. It is not protected against negative values, or values greater than the amount of storage currently available... and even if additional storage does exist, its contents are unpredictable. The only safe use for our setLength() is to truncate the FastStringBuffer to a shorter string.

QUERY: Given that this operation will be used relatively rarely, does it really need to be so highly optimized?

Parameters:
l - New length. If l<0 or l>=getLength(), this operation will not report an error but future operations will almost certainly fail.

toString

public final java.lang.String toString()
Note that this operation has been somewhat deoptimized by the shift to a chunked array, as there is no factory method to produce a String object directly from an array of arrays and hence a double copy is needed. By using ensureCapacity we hope to minimize the heap overhead of building the intermediate StringBuffer.

(It really is a pity that Java didn't design String as a final subclass of MutableString, rather than having StringBuffer be a separate hierarchy. We'd avoid a lot of double-buffering.)

Returns:
the contents of the FastStringBuffer as a standard Java string.
Overrides:
toString in class java.lang.Object

append

public final void append(char value)
Append a single character onto the FastStringBuffer, growing the storage if necessary.

NOTE THAT after calling append(), previously obtained references to m_array[][] may no longer be valid.... though in fact they should be in this instance.

Parameters:
value - character to be appended.

append

public final void append(java.lang.String value)
Append the contents of a String onto the FastStringBuffer, growing the storage if necessary.

NOTE THAT after calling append(), previously obtained references to m_array[] may no longer be valid.

Parameters:
value - String whose contents are to be appended.

append

public final void append(java.lang.StringBuffer value)
Append the contents of a StringBuffer onto the FastStringBuffer, growing the storage if necessary.

NOTE THAT after calling append(), previously obtained references to m_array[] may no longer be valid.

Parameters:
value - StringBuffer whose contents are to be appended.

append

public final void append(char[] chars,
                         int start,
                         int length)
Append part of the contents of a Character Array onto the FastStringBuffer, growing the storage if necessary.

NOTE THAT after calling append(), previously obtained references to m_array[] may no longer be valid.

Parameters:
chars - character array from which data is to be copied
start - offset in chars of first character to be copied, zero-based.
length - number of characters to be copied

append

public final void append(FastStringBuffer value)
Append the contents of another FastStringBuffer onto this FastStringBuffer, growing the storage if necessary.

NOTE THAT after calling append(), previously obtained references to m_array[] may no longer be valid.

Parameters:
value - FastStringBuffer whose contents are to be appended.

isWhitespace

public boolean isWhitespace(int start,
                            int length)

Parameters:
start - Offset of first character in the range.
length - Number of characters to send.
Returns:
true if the specified range of characters are all whitespace, as defined by XMLCharacterRecognizer.

CURRENTLY DOES NOT CHECK FOR OUT-OF-RANGE.


getString

public java.lang.String getString(int start,
                                  int length)

Parameters:
start - Offset of first character in the range.
length - Number of characters to send.
Returns:
a new String object initialized from the specified range of characters.

sendSAXcharacters

public void sendSAXcharacters(org.xml.sax.ContentHandler ch,
                              int start,
                              int length)
                       throws org.xml.sax.SAXException
Sends the specified range of characters as one or more SAX characters() events. Note that the buffer reference passed to the ContentHandler may be invalidated if the FastStringBuffer is edited; it's the user's responsibility to manage access to the FastStringBuffer to prevent this problem from arising.

Note too that there is no promise that the output will be sent as a single call. As is always true in SAX, one logical string may be split across multiple blocks of memory and hence delivered as several successive events.

Parameters:
ch - SAX ContentHandler object to receive the event.
start - Offset of first character in the range.
length - Number of characters to send.
Throws:
org.xml.sax.SAXException - may be thrown by handler's characters() method.

Documentation is available at
http://e-docs.bea.com/wls/docs61

WebLogic classes and methods that do not appear in this reference are not public and are not supported.