summaryrefslogtreecommitdiffstats
path: root/WebCore/dom/QualifiedName.h
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom/QualifiedName.h')
-rw-r--r--WebCore/dom/QualifiedName.h74
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