Chromium Code Reviews| Index: Source/core/dom/NthIndexCache.cpp |
| diff --git a/Source/core/dom/NthIndexCache.cpp b/Source/core/dom/NthIndexCache.cpp |
| index 01e721902a361ff88abae6757071ce9300d8dd05..8d4e80b7c69bde718831233d98e7a5471828e6c9 100644 |
| --- a/Source/core/dom/NthIndexCache.cpp |
| +++ b/Source/core/dom/NthIndexCache.cpp |
| @@ -35,6 +35,19 @@ NthIndexCache::NthIndexData& NthIndexCache::ensureNthIndexDataFor(Node& parent) |
| return *addResult.storedValue->value; |
| } |
| +NthIndexCache::ElementTagNameAndNthIndexMap& NthIndexCache::ensureElementTagNameAndNthIndexMapForType(Node& parent) |
|
esprehn
2015/04/30 04:55:05
ensureTypeIndexMap(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 ElementTagNameAndNthIndexMap()); |
| + |
| + ASSERT(addResult.storedValue->value); |
| + return *addResult.storedValue->value; |
| +} |
| + |
| unsigned NthIndexCache::NthIndexData::cacheNthIndices(Element& element) |
| { |
| unsigned index = 0; |
| @@ -56,6 +69,40 @@ unsigned NthIndexCache::NthIndexData::cacheNthIndices(Element& element) |
| return index; |
| } |
| +unsigned NthIndexCache::NthIndexData::cacheNthIndicesOfType(Element& element, const QualifiedName& type) |
|
esprehn
2015/04/30 04:55:05
We should make NthIndexData not a nested class.
|
| +{ |
| + unsigned index = 0; |
|
esprehn
2015/04/30 04:55:05
This and the other method should both ASSERT(m_ele
|
| + // 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. |
| + // Using a spread value > 1 is done to save memory. Looking up the nth-index will |
| + // still be done in constant time in terms of sibling count, at most 'spread' |
| + // elements will be traversed. |
| + 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(ElementTagNameAndNthIndexMap& m_elementTagNameAndNthIndexMap, Element& element) |
| +{ |
| + |
| + auto it = m_elementTagNameAndNthIndexMap.find(element.tagName()); |
|
esprehn
2015/04/30 04:55:05
You should not call find() and then add(), always
|
| + if (it != m_elementTagNameAndNthIndexMap.end()) |
| + return *(it->value); |
|
esprehn
2015/04/30 04:55:05
Delete this.
|
| + ElementTagNameAndNthIndexMap::AddResult addResult = m_elementTagNameAndNthIndexMap.add(element.tagName(), nullptr); |
|
esprehn
2015/04/30 04:55:05
m_indexByType, you don't need these verbose names.
|
| + if (addResult.isNewEntry) |
| + addResult.storedValue->value = adoptPtrWillBeNoop(new NthIndexData()); |
| + return *addResult.storedValue->value; |
| + } |
| +} |
| + |
| DEFINE_TRACE(NthIndexCache::NthIndexData) |
| { |
| #if ENABLE(OILPAN) |