|
BEA Systems, Inc. | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--weblogic.apache.xml.utils.FastStringBuffer
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.
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 |
public FastStringBuffer(int initialChunkBits, int chunkBits)
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.
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.public FastStringBuffer()
public FastStringBuffer(int initialAllocationUnit)
ISSUE: Should this be considered initial size, or fixed size? Now configured as initial.
chunkSize
- Characters per chunk; will round up to power of 2.Method Detail |
public final int size()
public final int length()
public final void reset()
public final void setLength(int l)
QUERY: Given that this operation will be used relatively rarely, does it really need to be so highly optimized?
l
- New length. If l<0 or l>=getLength(), this operation will
not report an error but future operations will almost certainly fail.public final java.lang.String toString()
(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.)
public final void append(char value)
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.
value
- character to be appended.public final void append(java.lang.String value)
NOTE THAT after calling append(), previously obtained references to m_array[] may no longer be valid.
value
- String whose contents are to be appended.public final void append(java.lang.StringBuffer value)
NOTE THAT after calling append(), previously obtained references to m_array[] may no longer be valid.
value
- StringBuffer whose contents are to be appended.public final void append(char[] chars, int start, int length)
NOTE THAT after calling append(), previously obtained references to m_array[] may no longer be valid.
chars
- character array from which data is to be copiedstart
- offset in chars of first character to be copied,
zero-based.length
- number of characters to be copiedpublic final void append(FastStringBuffer value)
NOTE THAT after calling append(), previously obtained references to m_array[] may no longer be valid.
value
- FastStringBuffer whose contents are
to be appended.public boolean isWhitespace(int start, int length)
start
- Offset of first character in the range.length
- Number of characters to send.CURRENTLY DOES NOT CHECK FOR OUT-OF-RANGE.
public java.lang.String getString(int start, int length)
start
- Offset of first character in the range.length
- Number of characters to send.public void sendSAXcharacters(org.xml.sax.ContentHandler ch, int start, int length) throws org.xml.sax.SAXException
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.
ch
- SAX ContentHandler object to receive the event.start
- Offset of first character in the range.length
- Number of characters to send.
|
Documentation is available at http://e-docs.bea.com/wls/docs61 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |