Title: [135689] trunk/Source/WebCore
- Revision
- 135689
- Author
- shin...@chromium.org
- Date
- 2012-11-26 01:07:19 -0800 (Mon, 26 Nov 2012)
Log Message
[Shadow] Attaching children of a shadow host takes O(N^2) where N is the number of host children
https://bugs.webkit.org/show_bug.cgi?id=103017
Reviewed by Hajime Morita.
Since ContentDistribution was just a Vector, ContentDistribution::find() took O(N). Each child of shadow host calls it.
As a result, attaching children of shadow host takes O(N^2) at all.
In this patch, we make ContentDistribution::find() O(1) amortizedly. We introduce HashMap from a Node to Vector index,
and use it for ContentDistribution::find().
No new tests, covered by existing tests.
* html/shadow/ContentDistributor.cpp:
(WebCore::ContentDistribution::swap):
(WebCore):
(WebCore::ContentDistribution::append):
(WebCore::ContentDistribution::find):
(WebCore::ContentDistributor::distributeSelectionsTo):
* html/shadow/ContentDistributor.h:
(ContentDistribution): ContentDistribution now contains Vector and a reverse map.
(WebCore::ContentDistribution::first):
(WebCore::ContentDistribution::last):
(WebCore::ContentDistribution::at):
(WebCore::ContentDistribution::size):
(WebCore::ContentDistribution::isEmpty):
(WebCore::ContentDistribution::clear):
(WebCore::ContentDistribution::contains):
(WebCore::ContentDistribution::nodes):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (135688 => 135689)
--- trunk/Source/WebCore/ChangeLog 2012-11-26 08:31:18 UTC (rev 135688)
+++ trunk/Source/WebCore/ChangeLog 2012-11-26 09:07:19 UTC (rev 135689)
@@ -1,3 +1,35 @@
+2012-11-26 Shinya Kawanaka <shin...@chromium.org>
+
+ [Shadow] Attaching children of a shadow host takes O(N^2) where N is the number of host children
+ https://bugs.webkit.org/show_bug.cgi?id=103017
+
+ Reviewed by Hajime Morita.
+
+ Since ContentDistribution was just a Vector, ContentDistribution::find() took O(N). Each child of shadow host calls it.
+ As a result, attaching children of shadow host takes O(N^2) at all.
+
+ In this patch, we make ContentDistribution::find() O(1) amortizedly. We introduce HashMap from a Node to Vector index,
+ and use it for ContentDistribution::find().
+
+ No new tests, covered by existing tests.
+
+ * html/shadow/ContentDistributor.cpp:
+ (WebCore::ContentDistribution::swap):
+ (WebCore):
+ (WebCore::ContentDistribution::append):
+ (WebCore::ContentDistribution::find):
+ (WebCore::ContentDistributor::distributeSelectionsTo):
+ * html/shadow/ContentDistributor.h:
+ (ContentDistribution): ContentDistribution now contains Vector and a reverse map.
+ (WebCore::ContentDistribution::first):
+ (WebCore::ContentDistribution::last):
+ (WebCore::ContentDistribution::at):
+ (WebCore::ContentDistribution::size):
+ (WebCore::ContentDistribution::isEmpty):
+ (WebCore::ContentDistribution::clear):
+ (WebCore::ContentDistribution::contains):
+ (WebCore::ContentDistribution::nodes):
+
2012-11-26 Dan Carney <dcar...@google.com>
[V8] Give isolated shells a lifecycle like that of main shells
Modified: trunk/Source/WebCore/html/shadow/ContentDistributor.cpp (135688 => 135689)
--- trunk/Source/WebCore/html/shadow/ContentDistributor.cpp 2012-11-26 08:31:18 UTC (rev 135688)
+++ trunk/Source/WebCore/html/shadow/ContentDistributor.cpp 2012-11-26 09:07:19 UTC (rev 135689)
@@ -36,6 +36,28 @@
namespace WebCore {
+void ContentDistribution::swap(ContentDistribution& other)
+{
+ m_nodes.swap(other.m_nodes);
+ m_indices.swap(other.m_indices);
+}
+
+void ContentDistribution::append(PassRefPtr<Node> node)
+{
+ size_t size = m_nodes.size();
+ m_indices.set(node.get(), size);
+ m_nodes.append(node);
+}
+
+size_t ContentDistribution::find(const Node* node) const
+{
+ HashMap<const Node*, size_t>::const_iterator it = m_indices.find(node);
+ if (it == m_indices.end())
+ return notFound;
+
+ return it.get()->value;
+}
+
ContentDistributor::ContentDistributor()
: m_validity(Undetermined)
{
@@ -156,10 +178,10 @@
if (distributed[i])
continue;
- if (!query.matches(pool, i))
+ if (!query.matches(pool.nodes(), i))
continue;
- Node* child = pool[i].get();
+ Node* child = pool.at(i).get();
distribution.append(child);
m_nodeToInsertionPoint.add(child, insertionPoint);
distributed[i] = true;
Modified: trunk/Source/WebCore/html/shadow/ContentDistributor.h (135688 => 135689)
--- trunk/Source/WebCore/html/shadow/ContentDistributor.h 2012-11-26 08:31:18 UTC (rev 135688)
+++ trunk/Source/WebCore/html/shadow/ContentDistributor.h 2012-11-26 09:07:19 UTC (rev 135689)
@@ -44,8 +44,30 @@
class Node;
class ShadowRoot;
-typedef Vector<RefPtr<Node> > ContentDistribution;
+class ContentDistribution {
+public:
+ PassRefPtr<Node> first() const { return m_nodes.first(); }
+ PassRefPtr<Node> last() const { return m_nodes.last(); }
+ PassRefPtr<Node> at(size_t index) const { return m_nodes.at(index); }
+ size_t size() const { return m_nodes.size(); }
+ bool isEmpty() const { return m_nodes.isEmpty(); }
+
+ void append(PassRefPtr<Node>);
+ void clear() { m_nodes.clear(); m_indices.clear(); }
+
+ bool contains(const Node* node) const { return m_indices.contains(node); }
+ size_t find(const Node*) const;
+
+ void swap(ContentDistribution& other);
+
+ const Vector<RefPtr<Node> >& nodes() const { return m_nodes; }
+
+private:
+ Vector<RefPtr<Node> > m_nodes;
+ HashMap<const Node*, size_t> m_indices;
+};
+
class ContentDistributor {
WTF_MAKE_NONCOPYABLE(ContentDistributor);
public:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes