[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/khtml/css
From:       Viacheslav Tokarev <tsjoker () gmail ! com>
Date:       2009-03-10 16:42:32
Message-ID: 1236703352.165099.16769.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 937864 by vtokarev:

introduce new selector optimization:
while first simple selector was chosen smartly based on possible match criteria \
(class, id, tag, etc) there was nothing done for following simple selectors and in \
case of descendant matching we could end up going over tree up to the root and not \
find the match instead store precached sets of tags, classes and ids on that path
so we could check for possible match earlier

that significantly improves building style for element time for css heavy sites, like \
youtube where amount of checkSimpleSelector calls reduced by 5x times

 M  +43 -0     cssstyleselector.cpp  
 M  +4 -0      cssstyleselector.h  


--- trunk/KDE/kdelibs/khtml/css/cssstyleselector.cpp #937863:937864
@@ -645,6 +645,36 @@
             selectorsForCheck.append(v[j]);
     }
 
+    // build caches for element so it could be used in heuristic for descendant \
selectors +    // go up the tree and cache possible tags, classes and ids
+    tagCache.clear();
+    idCache.clear();
+    classCache.clear();
+    ElementImpl* current = element;
+    while (true) {
+        NodeImpl* parent = current->parentNode();
+        if (!parent || !parent->isElementNode())
+            break;
+        current = static_cast<ElementImpl*>(parent);
+
+        if (current->hasClass()) {
+            const ClassNames& classNames = current->classNames();
+            for (unsigned i = 0; i < classNames.size(); ++i)
+                classCache.add((unsigned long)classNames[i].impl());
+        }
+
+        DOMStringImpl* idValue = current->getAttributeImplById(ATTR_ID);
+        if (idValue && idValue->length()) {
+            bool caseSensitive = (current->document()->htmlMode() == \
DocumentImpl::XHtml) || strictParsing; +            AtomicString currentId = \
caseSensitive ? idValue : idValue->lower(); +            // though currentId is local \
and could be deleted from AtomicStringImpl cache right away +            // don't \
care about that, cause selector values are stable and only they will be checked later \
+            idCache.add((unsigned long)currentId.impl()); +        }
+
+        tagCache.add(localNamePart(current->id()));
+    }
+
     // sort selectors indexes so we match them in increasing order
     qSort(selectorsForCheck.begin(), selectorsForCheck.end());
 
@@ -1176,6 +1206,19 @@
     switch(relation) {
         case CSSSelector::Descendant:
         {
+            // if ancestor of original element we may want to check prepared caches \
first +            // whether given selector could possibly have a match
+            // if no we return SelectorFails result right away and avoid going up \
the tree +            if (isAncestor) {
+                int id = sel->tagLocalName.id();
+                if (id != anyLocalName && !tagCache.contains(id))
+                    return SelectorFails;
+                if (sel->match == CSSSelector::Class && \
!classCache.contains((unsigned long)sel->value.impl())) +                    return \
SelectorFails; +                if (sel->match == CSSSelector::Id && \
!idCache.contains((unsigned long)sel->value.impl())) +                    return \
SelectorFails; +            }
+
             while(true)
             {
                 DOM::NodeImpl* n = e->parentNode();
--- trunk/KDE/kdelibs/khtml/css/cssstyleselector.h #937863:937864
@@ -31,6 +31,7 @@
 #include <QtCore/QList>
 #include <wtf/HashMap.h>
 #include <wtf/Vector.h>
+#include <wtf/HashSet.h>
 
 class KHTMLSettings;
 class KHTMLView;
@@ -307,6 +308,9 @@
         WTF::HashMap< unsigned, WTF::Vector<int> > tagSelectors;
         WTF::Vector<int> otherSelectors;
 
+        WTF::HashSet<unsigned> tagCache;
+        WTF::HashSet<unsigned long> classCache, idCache;
+
 	RenderStyle::PseudoId dynamicPseudo;
 
 	RenderStyle *style;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic