Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(863)

Side by Side Diff: Source/core/rendering/OrderIterator.cpp

Issue 18162016: OrderIterator should be O(number of children) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/OrderIterator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 20 matching lines...) Expand all
31 #include "config.h" 31 #include "config.h"
32 #include "core/rendering/OrderIterator.h" 32 #include "core/rendering/OrderIterator.h"
33 33
34 #include "core/rendering/RenderBox.h" 34 #include "core/rendering/RenderBox.h"
35 35
36 namespace WebCore { 36 namespace WebCore {
37 37
38 OrderIterator::OrderIterator(const RenderBox* containerBox) 38 OrderIterator::OrderIterator(const RenderBox* containerBox)
39 : m_containerBox(containerBox) 39 : m_containerBox(containerBox)
40 , m_currentChild(0) 40 , m_currentChild(0)
41 , m_orderValuesIterator(0) 41 , m_currentOrderIndex(0)
42 , m_currentChildIndex(0)
42 { 43 {
43 } 44 }
44 45
45 RenderBox* OrderIterator::first() 46 RenderBox* OrderIterator::first()
46 { 47 {
47 reset(); 48 reset();
48 return next(); 49 return next();
49 } 50 }
50 51
51 RenderBox* OrderIterator::next() 52 RenderBox* OrderIterator::next()
52 { 53 {
53 do { 54 for (; m_currentOrderIndex < m_orderValues.size(); ++m_currentOrderIndex) {
54 if (!m_currentChild) { 55 const Vector<RenderBox*>& currentOrderChildren = m_orderedValues.get(m_o rderValues[m_currentOrderIndex]);
55 if (m_orderValuesIterator == m_orderValues.end()) 56 ASSERT(!currentOrderChildren.isEmpty());
56 return 0; 57 for (; m_currentChildIndex < currentOrderChildren.size(); ++m_currentChi ldIndex) {
tony 2013/07/19 17:36:31 Using a for loop here is weird since you always re
57 if (m_orderValuesIterator) { 58 m_currentChild = currentOrderChildren[m_currentChildIndex];
58 ++m_orderValuesIterator; 59 ++m_currentChildIndex;
59 if (m_orderValuesIterator == m_orderValues.end()) 60 return m_currentChild;
60 return 0; 61 }
61 } else {
62 m_orderValuesIterator = m_orderValues.begin();
63 }
64 62
65 m_currentChild = m_containerBox->firstChildBox(); 63 m_currentChildIndex = 0;
66 } else { 64 }
67 m_currentChild = m_currentChild->nextSiblingBox();
68 }
69 } while (!m_currentChild || m_currentChild->style()->order() != *m_orderValu esIterator);
70 65
66 m_currentChild = 0;
71 return m_currentChild; 67 return m_currentChild;
72 } 68 }
73 69
74 void OrderIterator::reset() 70 void OrderIterator::reset()
75 { 71 {
72 m_currentOrderIndex = 0;
73 m_currentChildIndex = 0;
76 m_currentChild = 0; 74 m_currentChild = 0;
77 m_orderValuesIterator = 0;
78 } 75 }
79 76
80 OrderIteratorPopulator::~OrderIteratorPopulator() 77 OrderIteratorPopulator::~OrderIteratorPopulator()
81 { 78 {
82 m_iterator.reset(); 79 m_iterator.reset();
83 80
84 if (m_anyChildHasDefaultOrderValue) 81 std::sort(m_iterator.m_orderValues.begin(), m_iterator.m_orderValues.end());
85 m_iterator.m_orderValues.append(0);
86
87 if (m_iterator.m_orderValues.size() > 1)
88 removeDuplicatedOrderValues();
89 82
90 // Ensure that we release any extra memory we hold onto. 83 // Ensure that we release any extra memory we hold onto.
91 m_iterator.m_orderValues.shrinkToFit(); 84 m_iterator.m_orderValues.shrinkToFit();
92 } 85 }
93 86
94 void OrderIteratorPopulator::removeDuplicatedOrderValues() 87 void OrderIteratorPopulator::collectChild(RenderBox* child)
95 { 88 {
96 OrderIterator::OrderValues& orderValues = m_iterator.m_orderValues; 89 int order = child->style()->order();
97 90
98 std::sort(orderValues.begin(), orderValues.end()); 91 // FIXME: Ideally we would want to avoid inserting into the HashMap for the common case where there are only items
99 92 // with the default 'order' 0. The current API is designed to blend into a s ingle iteration which makes having a
100 int previous = orderValues[0]; 93 // slower fallback difficult without having to store the children (grid item s may not be contiguous in DOM order).
101 size_t uniqueItemIndex = 0; 94 OrderIterator::OrderedValuesMap::AddResult result = m_iterator.m_orderedValu es.add(order, Vector<RenderBox*>());
tony 2013/07/19 17:36:31 Can we use a std::map<int, Vector<RenderBox*> > he
102 for (size_t i = 1; i < orderValues.size(); ++i) { 95 result.iterator->value.append(child);
103 int current = orderValues[i]; 96 if (result.isNewEntry)
104 if (current == previous)
105 continue;
106 ++uniqueItemIndex;
107 std::swap(orderValues[i], orderValues[uniqueItemIndex]);
108 previous = current;
109 }
110 orderValues.shrink(uniqueItemIndex + 1);
111 }
112
113 void OrderIteratorPopulator::collectChild(const RenderBox* child)
114 {
115 // Avoid growing the vector for the common-case default value of 0.
116 if (int order = child->style()->order())
117 m_iterator.m_orderValues.append(order); 97 m_iterator.m_orderValues.append(order);
118 else
119 m_anyChildHasDefaultOrderValue = true;
120 } 98 }
121 99
122 } // namespace WebCore 100 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/OrderIterator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698