DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=4514>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=4514 getNodeValueString in DeferredDocumentImpl.java return after 4 minutes when returning a BIG string value Summary: getNodeValueString in DeferredDocumentImpl.java return after 4 minutes when returning a BIG string value Product: Xerces-J Version: 1.4.3 Platform: All OS/Version: Windows NT/2K Status: NEW Severity: Major Priority: Other Component: DOM AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] CC: [EMAIL PROTECTED] I returned a big string value by SOAP. The client side takes 4 minutes with 100% CPU until returning from getNodeValueString method. The problem is that the code is using StringBuffer.insert for each chunk (line 1007). This is very unefficient because StringBuffer.insert cause shifting and recopy of the buffer for each chunk. When the value is big (I had 70,000 chunks) - the function don't return immediatly (this takes me 4 minutes with 100% CPU on Pentium III 500). I fixed it by using a vector to save each chunk, then iterate the vector backward and use StringBuffer.append. The function return immediatly! Here is the fixed method: (I ADD "//////////////////" before and after each change). /** * Returns the value of the given node. * @param free True to free the string index. */ public String getNodeValueString(int nodeIndex, boolean free) { if (nodeIndex == -1) { return null; } int chunk = nodeIndex >> CHUNK_SHIFT; int index = nodeIndex & CHUNK_MASK; int valueIndex = free ? clearChunkIndex(fNodeValue, chunk, index) : getChunkIndex(fNodeValue, chunk, index); if (valueIndex == -1) { return null; } int type = getChunkIndex(fNodeType, chunk, index); if (type == Node.TEXT_NODE) { int prevSib = getRealPrevSibling (nodeIndex); if (prevSib != -1 && getNodeType (prevSib, false) == Node.TEXT_NODE) { StringBuffer str = new StringBuffer(); //////////////////////////////// // The previous implementation was using str.insert // It was very not efficient // I save each chunk string in a vector then use str.append Vector chunkStrings = new Vector(); chunkStrings.add (fStringPool.toString(valueIndex)); //////////////////////////////// do { chunk = prevSib >> CHUNK_SHIFT; index = prevSib & CHUNK_MASK; valueIndex = getChunkIndex(fNodeValue, chunk, index); // NOTE: This has to be done backwards because the // children are placed backwards. //////////////////////////////// //str.insert(0, fStringPool.toString(valueIndex)); chunkStrings.add(fStringPool.toString(valueIndex)); //////////////////////////////// prevSib = getChunkIndex(fNodePrevSib, chunk, index); if (prevSib == -1) { break; } } while (getNodeType(prevSib, false) == Node.TEXT_NODE); //////////////////////////////// // backwards iteration and append each string to stringBuffer for (int i=chunkStrings.size()-1; i>=0; i--) { str.append((String)chunkStrings.elementAt(i)); } chunkStrings.clear(); //////////////////////////////// return str.toString(); } } return fStringPool.toString(valueIndex); } // getNodeValueString(int,boolean):String Regards, Stephane Dahan --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
