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

Side by Side Diff: Source/core/dom/ElementData.h

Issue 337753005: Make iterator for Element's attributes more lightweight (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Proper rebase Created 6 years, 6 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/dom/Element.idl ('k') | Source/core/dom/ElementData.cpp » ('j') | 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) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2014 Apple Inc. All rights reserved. 3 * Copyright (C) 2014 Apple Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 25 matching lines...) Expand all
36 #include "core/dom/SpaceSplitString.h" 36 #include "core/dom/SpaceSplitString.h"
37 #include "wtf/text/AtomicString.h" 37 #include "wtf/text/AtomicString.h"
38 38
39 namespace WebCore { 39 namespace WebCore {
40 40
41 class Attr; 41 class Attr;
42 class ShareableElementData; 42 class ShareableElementData;
43 class StylePropertySet; 43 class StylePropertySet;
44 class UniqueElementData; 44 class UniqueElementData;
45 45
46 class AttributeConstIterator { 46 class AttributeCollection {
47 public: 47 public:
48 AttributeConstIterator(const Attribute* array, unsigned index) 48 typedef const Attribute* const_iterator;
49 : m_array(array)
50 , m_index(index)
51 { }
52 49
53 const Attribute* operator*() const { return &m_array[m_index]; } 50 AttributeCollection(const Attribute* array, unsigned size)
54 const Attribute* operator->() const { return &m_array[m_index]; }
55 AttributeConstIterator& operator++() { ++m_index; return *this; }
56
57 bool operator==(const AttributeConstIterator& other) const { return m_index == other.m_index; }
58 bool operator!=(const AttributeConstIterator& other) const { return !(*this == other); }
59
60 unsigned index() const { return m_index; }
61
62 private:
63 const Attribute* m_array;
64 unsigned m_index;
65 };
66
67 class AttributeIteratorAccessor {
68 public:
69 AttributeIteratorAccessor(const Attribute* array, unsigned size)
70 : m_array(array) 51 : m_array(array)
71 , m_size(size) 52 , m_size(size)
72 { } 53 { }
73 54
74 AttributeConstIterator begin() const { return AttributeConstIterator(m_array , 0); } 55 const_iterator begin() const { return m_array; }
75 AttributeConstIterator end() const { return AttributeConstIterator(m_array, m_size); } 56 const_iterator end() const { return m_array + m_size; }
76 57
77 unsigned size() const { return m_size; } 58 unsigned size() const { return m_size; }
78 59
79 private: 60 private:
80 const Attribute* m_array; 61 const Attribute* m_array;
81 unsigned m_size; 62 unsigned m_size;
82 }; 63 };
83 64
84 // ElementData represents very common, but not necessarily unique to an element, 65 // ElementData represents very common, but not necessarily unique to an element,
85 // data such as attributes, inline style, and parsed class names and ids. 66 // data such as attributes, inline style, and parsed class names and ids.
(...skipping 12 matching lines...) Expand all
98 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle Resolution = newId; } 79 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle Resolution = newId; }
99 80
100 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); } 81 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); }
101 82
102 const StylePropertySet* presentationAttributeStyle() const; 83 const StylePropertySet* presentationAttributeStyle() const;
103 84
104 // This is not a trivial getter and its return value should be cached for pe rformance. 85 // This is not a trivial getter and its return value should be cached for pe rformance.
105 size_t attributeCount() const; 86 size_t attributeCount() const;
106 bool hasAttributes() const { return !!attributeCount(); } 87 bool hasAttributes() const { return !!attributeCount(); }
107 88
108 AttributeIteratorAccessor attributesIterator() const; 89 AttributeCollection attributes() const;
109 90
110 const Attribute& attributeAt(unsigned index) const; 91 const Attribute& attributeAt(unsigned index) const;
111 const Attribute* findAttributeByName(const QualifiedName&) const; 92 const Attribute* findAttributeByName(const QualifiedName&) const;
112 size_t findAttributeIndexByName(const QualifiedName&, bool shouldIgnoreCase = false) const; 93 size_t findAttributeIndexByName(const QualifiedName&, bool shouldIgnoreCase = false) const;
113 size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreA ttributeCase) const; 94 size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreA ttributeCase) const;
114 size_t findAttrNodeIndex(Attr*) const; 95 size_t findAttrNodeIndex(Attr*) const;
115 96
116 bool hasID() const { return !m_idForStyleResolution.isNull(); } 97 bool hasID() const { return !m_idForStyleResolution.isNull(); }
117 bool hasClass() const { return !m_classNames.isNull(); } 98 bool hasClass() const { return !m_classNames.isNull(); }
118 99
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 217
237 inline const Attribute* ElementData::attributeBase() const 218 inline const Attribute* ElementData::attributeBase() const
238 { 219 {
239 if (m_isUnique) 220 if (m_isUnique)
240 return static_cast<const UniqueElementData*>(this)->m_attributeVector.be gin(); 221 return static_cast<const UniqueElementData*>(this)->m_attributeVector.be gin();
241 return static_cast<const ShareableElementData*>(this)->m_attributeArray; 222 return static_cast<const ShareableElementData*>(this)->m_attributeArray;
242 } 223 }
243 224
244 inline size_t ElementData::findAttributeIndexByName(const QualifiedName& name, b ool shouldIgnoreCase) const 225 inline size_t ElementData::findAttributeIndexByName(const QualifiedName& name, b ool shouldIgnoreCase) const
245 { 226 {
246 AttributeIteratorAccessor attributes = attributesIterator(); 227 AttributeCollection attributes = this->attributes();
247 AttributeConstIterator end = attributes.end(); 228 AttributeCollection::const_iterator end = attributes.end();
248 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { 229 unsigned index = 0;
230 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
249 if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase)) 231 if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
250 return it.index(); 232 return index;
251 } 233 }
252 return kNotFound; 234 return kNotFound;
253 } 235 }
254 236
255 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th at the caller 237 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th at the caller
256 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not). 238 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
257 inline size_t ElementData::findAttributeIndexByName(const AtomicString& name, bo ol shouldIgnoreAttributeCase) const 239 inline size_t ElementData::findAttributeIndexByName(const AtomicString& name, bo ol shouldIgnoreAttributeCase) const
258 { 240 {
259 bool doSlowCheck = shouldIgnoreAttributeCase; 241 bool doSlowCheck = shouldIgnoreAttributeCase;
260 242
261 // Optimize for the case where the attribute exists and its name exactly mat ches. 243 // Optimize for the case where the attribute exists and its name exactly mat ches.
262 AttributeIteratorAccessor attributes = attributesIterator(); 244 AttributeCollection attributes = this->attributes();
263 AttributeConstIterator end = attributes.end(); 245 AttributeCollection::const_iterator end = attributes.end();
264 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { 246 unsigned index = 0;
247 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
265 // FIXME: Why check the prefix? Namespaces should be all that matter. 248 // FIXME: Why check the prefix? Namespaces should be all that matter.
266 // Most attributes (all of HTML and CSS) have no namespace. 249 // Most attributes (all of HTML and CSS) have no namespace.
267 if (!it->name().hasPrefix()) { 250 if (!it->name().hasPrefix()) {
268 if (name == it->localName()) 251 if (name == it->localName())
269 return it.index(); 252 return index;
270 } else { 253 } else {
271 doSlowCheck = true; 254 doSlowCheck = true;
272 } 255 }
273 } 256 }
274 257
275 if (doSlowCheck) 258 if (doSlowCheck)
276 return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase) ; 259 return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase) ;
277 return kNotFound; 260 return kNotFound;
278 } 261 }
279 262
280 inline AttributeIteratorAccessor ElementData::attributesIterator() const 263 inline AttributeCollection ElementData::attributes() const
281 { 264 {
282 if (isUnique()) { 265 if (isUnique()) {
283 const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueEl ementData*>(this)->m_attributeVector; 266 const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueEl ementData*>(this)->m_attributeVector;
284 return AttributeIteratorAccessor(attributeVector.data(), attributeVector .size()); 267 return AttributeCollection(attributeVector.data(), attributeVector.size( ));
285 } 268 }
286 return AttributeIteratorAccessor(static_cast<const ShareableElementData*>(th is)->m_attributeArray, m_arraySize); 269 return AttributeCollection(static_cast<const ShareableElementData*>(this)->m _attributeArray, m_arraySize);
287 } 270 }
288 271
289 inline const Attribute* ElementData::findAttributeByName(const QualifiedName& na me) const 272 inline const Attribute* ElementData::findAttributeByName(const QualifiedName& na me) const
290 { 273 {
291 AttributeIteratorAccessor attributes = attributesIterator(); 274 AttributeCollection attributes = this->attributes();
292 AttributeConstIterator end = attributes.end(); 275 AttributeCollection::const_iterator end = attributes.end();
293 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { 276 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
294 if (it->name().matches(name)) 277 if (it->name().matches(name))
295 return *it; 278 return it;
296 } 279 }
297 return 0; 280 return 0;
298 } 281 }
299 282
300 inline const Attribute& ElementData::attributeAt(unsigned index) const 283 inline const Attribute& ElementData::attributeAt(unsigned index) const
301 { 284 {
302 RELEASE_ASSERT(index < attributeCount()); 285 RELEASE_ASSERT(index < attributeCount());
303 ASSERT(attributeBase() + index); 286 ASSERT(attributeBase() + index);
304 return *(attributeBase() + index); 287 return *(attributeBase() + index);
305 } 288 }
306 289
307 inline void UniqueElementData::appendAttribute(const QualifiedName& attributeNam e, const AtomicString& value) 290 inline void UniqueElementData::appendAttribute(const QualifiedName& attributeNam e, const AtomicString& value)
308 { 291 {
309 m_attributeVector.append(Attribute(attributeName, value)); 292 m_attributeVector.append(Attribute(attributeName, value));
310 } 293 }
311 294
312 inline void UniqueElementData::removeAttributeAt(size_t index) 295 inline void UniqueElementData::removeAttributeAt(size_t index)
313 { 296 {
314 m_attributeVector.remove(index); 297 m_attributeVector.remove(index);
315 } 298 }
316 299
317 inline Attribute& UniqueElementData::attributeAt(unsigned index) 300 inline Attribute& UniqueElementData::attributeAt(unsigned index)
318 { 301 {
319 return m_attributeVector.at(index); 302 return m_attributeVector.at(index);
320 } 303 }
321 304
322 } // namespace WebCore 305 } // namespace WebCore
323 306
324 #endif // ElementData_h 307 #endif // ElementData_h
OLDNEW
« no previous file with comments | « Source/core/dom/Element.idl ('k') | Source/core/dom/ElementData.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698