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]

Reply via email to