From c074b18f8d4510713f6d66149213510428eae6f1 Mon Sep 17 00:00:00 2001
From: Christian Kamm <christian.d.kamm@nokia.com>
Date: Wed, 7 Sep 2011 08:45:01 +0200
Subject: [PATCH] C++: Improve Literal::hashCode.

This can have a dramatic impact on performance when a file contains lots
of unique literals.

Change-Id: I5309b28f704d7f53e164dc8084ae08354c09354b
Reviewed-on: http://codereview.qt.nokia.com/4312
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
---
 src/libs/3rdparty/cplusplus/Literals.cpp | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/libs/3rdparty/cplusplus/Literals.cpp b/src/libs/3rdparty/cplusplus/Literals.cpp
index 16eab541d7b..d0aa05d3512 100644
--- a/src/libs/3rdparty/cplusplus/Literals.cpp
+++ b/src/libs/3rdparty/cplusplus/Literals.cpp
@@ -75,9 +75,21 @@ unsigned Literal::hashCode() const
 
 unsigned Literal::hashCode(const char *chars, unsigned size)
 {
-    unsigned h = 0;
-    for (unsigned i = 0; i < size; ++i)
-        h = (h >> 5) - h + chars[i];
+    /* Hash taken from QtCore's qHash for strings, which in turn has the note:
+
+    These functions are based on Peter J. Weinberger's hash function
+    (from the Dragon Book). The constant 24 in the original function
+    was replaced with 23 to produce fewer collisions on input such as
+    "a", "aa", "aaa", "aaaa", ...
+    */
+
+    uint h = 0;
+
+    while (size--) {
+        h = (h << 4) + *chars++;
+        h ^= (h & 0xf0000000) >> 23;
+        h &= 0x0fffffff;
+    }
     return h;
 }
 
-- 
GitLab