| Index: Source/core/dom/NthIndexCache.cpp
|
| diff --git a/Source/core/dom/NthIndexCache.cpp b/Source/core/dom/NthIndexCache.cpp
|
| index 498abafe26eae8179c1a6a9ad3ff00c5080761ad..01de622a91ecf1c7205d2581755de30ab45b6449 100644
|
| --- a/Source/core/dom/NthIndexCache.cpp
|
| +++ b/Source/core/dom/NthIndexCache.cpp
|
| @@ -35,9 +35,23 @@ NthIndexCache::NthIndexData& NthIndexCache::ensureNthIndexDataFor(Node& parent)
|
| return *addResult.storedValue->value;
|
| }
|
|
|
| +NthIndexCache::IndexByType& NthIndexCache::ensureTypeIndexMap(Node& parent)
|
| +{
|
| + if (!m_parentMapForType)
|
| + m_parentMapForType = adoptPtrWillBeNoop(new ParentMapForType());
|
| +
|
| + ParentMapForType::AddResult addResult = m_parentMapForType->add(&parent, nullptr);
|
| + if (addResult.isNewEntry)
|
| + addResult.storedValue->value = adoptPtrWillBeNoop(new IndexByType());
|
| +
|
| + ASSERT(addResult.storedValue->value);
|
| + return *addResult.storedValue->value;
|
| +}
|
| +
|
| unsigned NthIndexCache::NthIndexData::cacheNthIndices(Element& element)
|
| {
|
| ASSERT(!element.isPseudoElement());
|
| + ASSERT(m_elementIndexMap.isEmpty());
|
| unsigned index = 0;
|
| // The frequency at which we cache the nth-index for a set of siblings.
|
| // A spread value of 3 means every third Element will have its nth-index cached.
|
| @@ -57,6 +71,37 @@ unsigned NthIndexCache::NthIndexData::cacheNthIndices(Element& element)
|
| return index;
|
| }
|
|
|
| +unsigned NthIndexCache::NthIndexData::cacheNthIndicesOfType(Element& element, const QualifiedName& type)
|
| +{
|
| + ASSERT(!element.isPseudoElement());
|
| + ASSERT(m_elementIndexMap.isEmpty());
|
| + unsigned index = 0;
|
| + // The frequency at which we cache the nth-index of type for a set of siblings.
|
| + // A spread value of 3 means every third Element of its type will have its nth-index cached.
|
| + // Using a spread value > 1 is done to save memory. Looking up the nth-index of its type will
|
| + // still be done in less time, as most number of elements traversed
|
| + // will be equal to find 'spread' elements in the sibling set.
|
| + const unsigned spread = 3;
|
| + unsigned count = 0;
|
| + for (Element* sibling = ElementTraversal::firstChild(*element.parentNode(), HasTagName(type)); sibling; sibling = ElementTraversal::nextSibling(*sibling, HasTagName(type))) {
|
| + if (!(++count % spread))
|
| + m_elementIndexMap.add(sibling, count);
|
| + if (sibling == &element)
|
| + index = count;
|
| + }
|
| + ASSERT(count && index);
|
| + m_count = count;
|
| + return index;
|
| +}
|
| +
|
| +NthIndexCache::NthIndexData& NthIndexCache::nthIndexDataWithTagName(Element& element)
|
| +{
|
| + IndexByType::AddResult addResult = ensureTypeIndexMap(*element.parentNode()).add(element.tagName(), nullptr);
|
| + if (addResult.isNewEntry)
|
| + addResult.storedValue->value = adoptPtrWillBeNoop(new NthIndexData());
|
| + return *addResult.storedValue->value;
|
| +}
|
| +
|
| DEFINE_TRACE(NthIndexCache::NthIndexData)
|
| {
|
| #if ENABLE(OILPAN)
|
|
|