JavaScriptCore/wtf/StringHashFunctions.h
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/JavaScriptCore/wtf/StringHashFunctions.h	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2005, 2006, 2008, 2010 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef WTF_StringHashFunctions_h
+#define WTF_StringHashFunctions_h
+
+#include <wtf/unicode/Unicode.h>
+
+namespace WTF {
+
+// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
+static const unsigned stringHashingStartValue = 0x9e3779b9U;
+
+// stringHash methods based on Paul Hsieh's SuperFastHash.
+// http://www.azillionmonkeys.com/qed/hash.html
+// char* data is interpreted as latin-encoded (zero extended to 16 bits).
+
+inline unsigned stringHash(const UChar* data, unsigned length)
+{
+    unsigned hash = WTF::stringHashingStartValue;
+    unsigned rem = length & 1;
+    length >>= 1;
+
+    // Main loop
+    for (; length > 0; length--) {
+        hash += data[0];
+        unsigned tmp = (data[1] << 11) ^ hash;
+        hash = (hash << 16) ^ tmp;
+        data += 2;
+        hash += hash >> 11;
+    }
+
+    // Handle end case
+    if (rem) {
+        hash += data[0];
+        hash ^= hash << 11;
+        hash += hash >> 17;
+    }
+
+    // Force "avalanching" of final 127 bits
+    hash ^= hash << 3;
+    hash += hash >> 5;
+    hash ^= hash << 2;
+    hash += hash >> 15;
+    hash ^= hash << 10;
+
+    hash &= 0x7fffffff;
+
+    // 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 = 0x40000000;
+
+    return hash;
+}
+
+inline unsigned stringHash(const char* data, unsigned length)
+{
+    unsigned hash = WTF::stringHashingStartValue;
+    unsigned rem = length & 1;
+    length >>= 1;
+
+    // Main loop
+    for (; length > 0; length--) {
+        hash += static_cast<unsigned char>(data[0]);
+        unsigned tmp = (static_cast<unsigned char>(data[1]) << 11) ^ hash;
+        hash = (hash << 16) ^ tmp;
+        data += 2;
+        hash += hash >> 11;
+    }
+
+    // Handle end case
+    if (rem) {
+        hash += static_cast<unsigned char>(data[0]);
+        hash ^= hash << 11;
+        hash += hash >> 17;
+    }
+
+    // Force "avalanching" of final 127 bits
+    hash ^= hash << 3;
+    hash += hash >> 5;
+    hash ^= hash << 2;
+    hash += hash >> 15;
+    hash ^= hash << 10;
+
+    hash &= 0x7fffffff;
+
+    // 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 = 0x40000000;
+
+    return hash;
+}
+
+inline unsigned stringHash(const char* data)
+{
+    unsigned hash = WTF::stringHashingStartValue;
+
+    // Main loop
+    for (;;) {
+        unsigned char b0 = data[0];
+        if (!b0)
+            break;
+        unsigned char b1 = data[1];
+        if (!b1) {
+            hash += b0;
+            hash ^= hash << 11;
+            hash += hash >> 17;
+            break;
+        }
+        hash += b0;
+        unsigned tmp = (b1 << 11) ^ hash;
+        hash = (hash << 16) ^ tmp;
+        data += 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;
+
+    hash &= 0x7fffffff;
+
+    // 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 = 0x40000000;
+
+    return hash;
+}
+
+} // namespace WTF
+
+#endif // WTF_StringHashFunctions_h