diff options
Diffstat (limited to 'Source/WebCore/dom/DynamicNodeList.cpp')
-rw-r--r-- | Source/WebCore/dom/DynamicNodeList.cpp | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/Source/WebCore/dom/DynamicNodeList.cpp b/Source/WebCore/dom/DynamicNodeList.cpp index 23664e8..bba1678 100644 --- a/Source/WebCore/dom/DynamicNodeList.cpp +++ b/Source/WebCore/dom/DynamicNodeList.cpp @@ -3,6 +3,7 @@ * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Dirk Mueller (mueller@kde.org) * Copyright (C) 2004, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2012 The Linux Foundation All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -56,8 +57,18 @@ unsigned DynamicNodeList::length() const unsigned length = 0; - for (Node* n = m_rootNode->firstChild(); n; n = n->traverseNextNode(m_rootNode.get())) - length += n->isElementNode() && nodeMatches(static_cast<Element*>(n)); + Node* lastNode = m_rootNode->lastDescendantNode(); + Vector<Node* >& cachedNodes = m_caches->cachedNodes; + for (Node* n = m_rootNode->firstChild(); n; n = n->traverseNextNodeFastPath()) { + if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) { + if (length >= cachedNodes.size()) + cachedNodes.resize(length + 1); + cachedNodes.data()[length] = n; + length ++; + } + if (n == lastNode) + break; + } m_caches->cachedLength = length; m_caches->isLengthCacheValid = true; @@ -68,7 +79,9 @@ unsigned DynamicNodeList::length() const Node* DynamicNodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const { ASSERT(remainingOffset >= 0); - for (Node* n = start; n; n = n->traverseNextNode(m_rootNode.get())) { + if (!m_caches->lastDecendantOfRoot) + m_caches->lastDecendantOfRoot = m_rootNode->lastDescendantNode(); + for (Node* n = start; n; n = n->traverseNextNodeFastPath()) { if (n->isElementNode() && nodeMatches(static_cast<Element*>(n))) { if (!remainingOffset) { m_caches->lastItem = n; @@ -78,6 +91,8 @@ Node* DynamicNodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int } --remainingOffset; } + if (n == m_caches->lastDecendantOfRoot) + break; } return 0; // no matching node in this subtree @@ -103,6 +118,14 @@ Node* DynamicNodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, in Node* DynamicNodeList::item(unsigned offset) const { + Node* result; + Vector<Node* >& cachedNodes = m_caches->cachedNodes; + if (offset < cachedNodes.size()) { + result = cachedNodes[offset]; + if (result) + return result; + } + int remainingOffset = offset; Node* start = m_rootNode->firstChild(); if (m_caches->isItemCacheValid) { @@ -115,8 +138,16 @@ Node* DynamicNodeList::item(unsigned offset) const } if (remainingOffset < 0) - return itemBackwardsFromCurrent(start, offset, remainingOffset); - return itemForwardsFromCurrent(start, offset, remainingOffset); + result = itemBackwardsFromCurrent(start, offset, remainingOffset); + else + result = itemForwardsFromCurrent(start, offset, remainingOffset); + + if (result) { + if (offset >= cachedNodes.size()) + cachedNodes.resize(offset + 1); + cachedNodes.data()[offset] = result; + } + return result; } Node* DynamicNodeList::itemWithName(const AtomicString& elementId) const @@ -159,6 +190,7 @@ void DynamicNodeList::invalidateCache() DynamicNodeList::Caches::Caches() : lastItem(0) + , lastDecendantOfRoot(0) , isLengthCacheValid(false) , isItemCacheValid(false) { @@ -172,8 +204,10 @@ PassRefPtr<DynamicNodeList::Caches> DynamicNodeList::Caches::create() void DynamicNodeList::Caches::reset() { lastItem = 0; + lastDecendantOfRoot = 0; isLengthCacheValid = false; - isItemCacheValid = false; + isItemCacheValid = false; + cachedNodes.clear(); } } // namespace WebCore |