diff options
Diffstat (limited to 'WebCore/dom/QualifiedName.h')
-rw-r--r-- | WebCore/dom/QualifiedName.h | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/WebCore/dom/QualifiedName.h b/WebCore/dom/QualifiedName.h index 5aa8abf..d09cdea 100644 --- a/WebCore/dom/QualifiedName.h +++ b/WebCore/dom/QualifiedName.h @@ -23,8 +23,15 @@ #define QualifiedName_h #include "AtomicString.h" +#include <wtf/HashFunctions.h> namespace WebCore { + +struct QualifiedNameComponents { + StringImpl* m_prefix; + StringImpl* m_localName; + StringImpl* m_namespace; +}; class QualifiedName { public: @@ -75,7 +82,7 @@ public: // Init routine for globals static void init(); - + private: void ref() { m_impl->ref(); } void deref(); @@ -93,5 +100,70 @@ inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); } inline bool operator!=(const QualifiedName& q, const AtomicString& a) { return a != q.localName(); } + +inline unsigned hashComponents(const QualifiedNameComponents& buf) +{ + ASSERT(sizeof(QualifiedNameComponents) % (sizeof(uint16_t) * 2) == 0); + + unsigned l = sizeof(QualifiedNameComponents) / (sizeof(uint16_t) * 2); + const uint16_t* s = reinterpret_cast<const uint16_t*>(&buf); + uint32_t hash = WTF::stringHashingStartValue; + + // Main loop + for (; l > 0; l--) { + hash += s[0]; + uint32_t tmp = (s[1] << 11) ^ hash; + hash = (hash << 16) ^ tmp; + s += 2; + hash += hash >> 11; + } + + // Force "avalanching" of final 127 bits + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 2; + hash += hash >> 15; + hash ^= hash << 10; + + // this avoids ever returning a hash code of 0, since that is used to + // signal "hash not computed yet", using a value that is likely to be + // effectively the same as 0 when the low bits are masked + if (hash == 0) + hash = 0x80000000; + + return hash; +} + +struct QualifiedNameHash { + static unsigned hash(const QualifiedName& name) { return hash(name.impl()); } + + static unsigned hash(const QualifiedName::QualifiedNameImpl* name) + { + QualifiedNameComponents c = { name->m_prefix.impl(), name->m_localName.impl(), name->m_namespace.impl() }; + return hashComponents(c); + } + + static bool equal(const QualifiedName& a, const QualifiedName& b) { return a == b; } + static bool equal(const QualifiedName::QualifiedNameImpl* a, const QualifiedName::QualifiedNameImpl* b) { return a == b; } + + static const bool safeToCompareToEmptyOrDeleted = false; +}; + +} + +namespace WTF { + + template<typename T> struct DefaultHash; + template<> struct DefaultHash<WebCore::QualifiedName> { + typedef WebCore::QualifiedNameHash Hash; + }; + + template<> struct HashTraits<WebCore::QualifiedName> : GenericHashTraits<WebCore::QualifiedName> { + static const bool emptyValueIsZero = false; + static WebCore::QualifiedName emptyValue() { return WebCore::QualifiedName(WebCore::nullAtom, WebCore::nullAtom, WebCore::nullAtom); } + static void constructDeletedValue(WebCore::QualifiedName& slot) { new (&slot) WebCore::QualifiedName(WebCore::nullAtom, WebCore::AtomicString(HashTableDeletedValue), WebCore::nullAtom); } + static bool isDeletedValue(const WebCore::QualifiedName& slot) { return slot.localName().isHashTableDeletedValue(); } + }; } + #endif |