[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

mjs mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:09:25 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 66976e2378e4ffd0e46ce158b570794c8bf206ce
Author: mjs <mjs at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Nov 5 20:00:33 2003 +0000

            Reviewed by Darin.
    
    	- fixed 3473906 - getElementById takes about 44% of time on particular slow intel page
    
    	I fixed this by adding a per-document id --> element hash
    	table. This speeds up my local copy of the intel page by 60% (50
    	sec to 20 sec!) and does not cause any PLT slowdown.
    
            * khtml/xml/dom_docimpl.h: New QDict field for id to element hash table.
            * khtml/xml/dom_docimpl.cpp:
            (DocumentImpl::getElementById): Just look it up in the newly
    	added hash table.
            (DocumentImpl::addElementById): New method. Add to hash table if
    	no other element is set for that key (this lets the first element
    	of several with matching ids win).
            (DocumentImpl::removeElementById): New method. Remove from hash
    	table only if the key and value both match.
    
    	These Element changes to keep the id --> element hashtable working
    	seem needlessly tricky, due to lack of bottlenecks in attribute
    	changing.
    
            * khtml/xml/dom_elementimpl.cpp:
            (ElementImpl::updateId): New method that removes element from
    	hash table for old it
            (ElementImpl::setAttribute): If setting id, call updateId.
            (ElementImpl::setAttributeMap): If either the old or the new map
    	includes id, call updateId.
            (ElementImpl::attach): If we have an id, call updateId to set it
    	after attaching.
            (ElementImpl::detach): Newly added. If we have an id, call
    	updateId to clear it before detaching.
    	(NamedAttrMapImpl::setNamedItem): If the name is id, call updateId on
    	our element.
            (NamedAttrMapImpl::removeNamedItem): If the name is id, call updateId on
    	our element.
            (NamedAttrMapImpl::operator=): If old or new contents include id attribute,
    	call updateId on our element.
    	* khtml/xml/dom_elementimpl.h: Prototype new methods.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@5391 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 6c39c67..0db1d24 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,45 @@
+2003-11-05  Maciej Stachowiak  <mjs at apple.com>
+
+        Reviewed by Darin.
+
+	- fixed 3473906 - getElementById takes about 44% of time on particular slow intel page
+
+	I fixed this by adding a per-document id --> element hash
+	table. This speeds up my local copy of the intel page by 60% (50
+	sec to 20 sec!) and does not cause any PLT slowdown.
+	
+        * khtml/xml/dom_docimpl.h: New QDict field for id to element hash table.
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::getElementById): Just look it up in the newly
+	added hash table.
+        (DocumentImpl::addElementById): New method. Add to hash table if
+	no other element is set for that key (this lets the first element
+	of several with matching ids win).
+        (DocumentImpl::removeElementById): New method. Remove from hash
+	table only if the key and value both match.
+
+	These Element changes to keep the id --> element hashtable working
+	seem needlessly tricky, due to lack of bottlenecks in attribute
+	changing.
+	
+        * khtml/xml/dom_elementimpl.cpp:
+        (ElementImpl::updateId): New method that removes element from
+	hash table for old it
+        (ElementImpl::setAttribute): If setting id, call updateId.
+        (ElementImpl::setAttributeMap): If either the old or the new map
+	includes id, call updateId.
+        (ElementImpl::attach): If we have an id, call updateId to set it
+	after attaching.
+        (ElementImpl::detach): Newly added. If we have an id, call
+	updateId to clear it before detaching.
+	(NamedAttrMapImpl::setNamedItem): If the name is id, call updateId on
+	our element.
+        (NamedAttrMapImpl::removeNamedItem): If the name is id, call updateId on
+	our element.
+        (NamedAttrMapImpl::operator=): If old or new contents include id attribute,
+	call updateId on our element.
+	* khtml/xml/dom_elementimpl.h: Prototype new methods.
+
 2003-11-05  Ken Kocienda  <kocienda at apple.com>
 
         Reviewed by Maciej
diff --git a/WebCore/khtml/xml/dom_docimpl.cpp b/WebCore/khtml/xml/dom_docimpl.cpp
index 837cd82..528081c 100644
--- a/WebCore/khtml/xml/dom_docimpl.cpp
+++ b/WebCore/khtml/xml/dom_docimpl.cpp
@@ -524,43 +524,29 @@ ElementImpl *DocumentImpl::getElementById( const DOMString &elementId ) const
 	return 0;
     }
 
-    QPtrStack<NodeImpl> nodeStack;
-    NodeImpl *current = _first;
+    return m_elementsById.find(elementId.string());
+}
 
-    while(1)
-    {
-        if(!current)
-        {
-            if(nodeStack.isEmpty()) break;
-            current = nodeStack.pop();
-            current = current->nextSibling();
-        }
-        else
-        {
-            if(current->isElementNode())
-            {
-                ElementImpl *e = static_cast<ElementImpl *>(current);
-                if(e->getAttribute(ATTR_ID) == elementId)
-                    return e;
-            }
 
-            NodeImpl *child = current->firstChild();
-            if(child)
-            {
-                nodeStack.push(current);
-                current = child;
-            }
-            else
-            {
-                current = current->nextSibling();
-            }
-        }
+void DocumentImpl::addElementById(const DOMString &elementId, ElementImpl *element)
+{
+    QString qId = elementId.string();
+
+    if (m_elementsById.find(qId) == NULL) {
+	m_elementsById.insert(qId, element);
     }
+}
 
-    //kdDebug() << "WARNING: *DocumentImpl::getElementById not found " << elementId.string() << endl;
-    return 0;
+void DocumentImpl::removeElementById(const DOMString &elementId, ElementImpl *element)
+{
+    QString qId = elementId.string();
+
+    if (m_elementsById.find(qId) == element) {
+	m_elementsById.remove(qId);
+    }
 }
 
+
 void DocumentImpl::setTitle(DOMString _title)
 {
     m_title = _title;
diff --git a/WebCore/khtml/xml/dom_docimpl.h b/WebCore/khtml/xml/dom_docimpl.h
index 04f7e80..b4ea5f1 100644
--- a/WebCore/khtml/xml/dom_docimpl.h
+++ b/WebCore/khtml/xml/dom_docimpl.h
@@ -460,6 +460,9 @@ public:
     // and make it sensitive to the type of document.
     static bool isValidName(const DOMString &);
     
+    void addElementById(const DOMString &elementId, ElementImpl *element);
+    void removeElementById(const DOMString &elementId, ElementImpl *element);
+
 signals:
     void finishedParsing();
 
@@ -582,7 +585,9 @@ private:
     int m_secureForms;
     
     khtml::Decoder *m_decoder;
-    
+
+    QDict<ElementImpl> m_elementsById;
+ 
     bool m_createRenderers;
 #endif
 };
diff --git a/WebCore/khtml/xml/dom_elementimpl.cpp b/WebCore/khtml/xml/dom_elementimpl.cpp
index 56304fc..213ab4b 100644
--- a/WebCore/khtml/xml/dom_elementimpl.cpp
+++ b/WebCore/khtml/xml/dom_elementimpl.cpp
@@ -227,6 +227,10 @@ void ElementImpl::setAttribute(NodeImpl::Id id, DOMStringImpl* value, int &excep
         exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
         return;
     }
+
+    if (id == ATTR_ID) {
+	updateId(old ? old->val() : 0, value);
+    }
     
     if (old && !value)
         namedAttrMap->removeAttribute(id);
@@ -240,6 +244,16 @@ void ElementImpl::setAttribute(NodeImpl::Id id, DOMStringImpl* value, int &excep
 
 void ElementImpl::setAttributeMap( NamedAttrMapImpl* list )
 {
+    // If setting the whole map changes the id attribute, we need to
+    // call updateId.
+
+    AttributeImpl *oldId = namedAttrMap ? namedAttrMap->getAttributeItem(ATTR_ID) : 0;
+    AttributeImpl *newId = list ? list->getAttributeItem(ATTR_ID) : 0;
+
+    if (oldId || newId) {
+	updateId(oldId ? oldId->val() : 0, newId ? newId->val() : 0);
+    }
+
     if(namedAttrMap)
         namedAttrMap->deref();
 
@@ -334,6 +348,28 @@ void ElementImpl::attach()
     createRendererIfNeeded();
 #endif
     NodeBaseImpl::attach();
+
+    NamedAttrMapImpl *attrs = attributes(true);
+    
+    if (attrs) {
+	AttributeImpl *idAttr = attrs->getAttributeItem(ATTR_ID);
+	if (idAttr && idAttr->val()) {
+	    updateId(0, idAttr->val());
+	}
+    }
+}
+
+void ElementImpl::detach()
+{
+    NamedAttrMapImpl *attrs = attributes(true);
+    if (attrs) {
+	AttributeImpl *idAttr = attrs->getAttributeItem(ATTR_ID);
+	if (idAttr && idAttr->val()) {
+	    updateId(idAttr->val(), 0);
+	}
+    }
+
+    NodeBaseImpl::detach();
 }
 
 void ElementImpl::recalcStyle( StyleChange change )
@@ -458,6 +494,30 @@ void ElementImpl::dispatchAttrAdditionEvent(AttributeImpl *attr)
 //                                         attr->value(),getDocument()->attrName(attr->id()),MutationEvent::ADDITION),exceptioncode);
 }
 
+
+void ElementImpl::updateId(DOMStringImpl* oldId, DOMStringImpl* newId)
+{
+    if (!attached())
+	return;
+
+    if (oldId == newId)
+	return;
+
+    DOMString oldIdStr(oldId);
+    DOMString newIdStr(newId);
+
+    DocumentImpl* doc = getDocument();
+
+    if (oldIdStr == newIdStr)
+	return;
+
+    if (!oldIdStr.isEmpty())
+	doc->removeElementById(oldIdStr, this);
+
+    if (!newIdStr.isEmpty())
+	doc->addElementById(newIdStr, this);
+}
+
 #ifndef NDEBUG
 void ElementImpl::dump(QTextStream *stream, QString ind) const
 {
@@ -603,6 +663,10 @@ Node NamedAttrMapImpl::setNamedItem ( NodeImpl* arg, int &exceptioncode )
         return 0;
     }
 
+    if (a->id() == ATTR_ID) {
+	element->updateId(old ? old->val() : 0, a->val());
+    }
+
     // ### slightly inefficient - resizes attribute array twice.
     Node r;
     if (old) {
@@ -611,6 +675,7 @@ Node NamedAttrMapImpl::setNamedItem ( NodeImpl* arg, int &exceptioncode )
         r = old->_impl;
         removeAttribute(a->id());
     }
+
     addAttribute(a);
     return r;
 }
@@ -635,6 +700,11 @@ Node NamedAttrMapImpl::removeNamedItem ( NodeImpl::Id id, int &exceptioncode )
 
     if (!a->attrImpl())  a->allocateImpl(element);
     Node r(a->attrImpl());
+
+    if (id == ATTR_ID) {
+	element->updateId(a->val(), 0);
+    }
+
     removeAttribute(id);
     return r;
 }
@@ -701,6 +771,16 @@ NamedAttrMapImpl& NamedAttrMapImpl::operator=(const NamedAttrMapImpl& other)
     // clone all attributes in the other map, but attach to our element
     if (!element) return *this;
 
+    // If assigning the map changes the id attribute, we need to call
+    // updateId.
+
+    AttributeImpl *oldId = getAttributeItem(ATTR_ID);
+    AttributeImpl *newId = other.getAttributeItem(ATTR_ID);
+
+    if (oldId || newId) {
+	element->updateId(oldId ? oldId->val() : 0, newId ? newId->val() : 0);
+    }
+
     clearAttributes();
     len = other.len;
     attrs = new AttributeImpl* [len];
diff --git a/WebCore/khtml/xml/dom_elementimpl.h b/WebCore/khtml/xml/dom_elementimpl.h
index d61f2cb..f9da3f8 100644
--- a/WebCore/khtml/xml/dom_elementimpl.h
+++ b/WebCore/khtml/xml/dom_elementimpl.h
@@ -192,6 +192,7 @@ public:
     virtual QString state() { return QString::null; }
 
     virtual void attach();
+    virtual void detach();
     virtual khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent);
     virtual khtml::RenderObject *createRenderer(RenderArena *, khtml::RenderStyle *);
     virtual void recalcStyle( StyleChange = NoChange );
@@ -227,6 +228,8 @@ private:
     // in the DTD
     virtual NamedAttrMapImpl* defaultMap() const;
 
+    void updateId(DOMStringImpl* oldId, DOMStringImpl* newId);
+
 protected: // member variables
     mutable NamedAttrMapImpl *namedAttrMap;
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list