Browse Source

libdpkg: Switch to the recommended FNV-1a variant

This should give better dispersion. And the function is way way less
complex than the possible future MurmurHash3 or xxHash candidates.
Guillem Jover 11 years ago
parent
commit
c8cd4cc0c1
3 changed files with 21 additions and 19 deletions
  1. 2 0
      debian/changelog
  2. 2 2
      lib/dpkg/strhash.c
  3. 17 17
      lib/dpkg/test/t-string.c

+ 2 - 0
debian/changelog

@@ -109,6 +109,8 @@ dpkg (1.17.14) UNRELEASED; urgency=low
     to make it more meaningful and reproducible.
   * Fix off-by-one error in libdpkg command argv size calculation.
     Based on a patch by Bálint Réczey <balint@balintreczey.hu>. Closes: #760690
+  * Switch the libdpkg string hashing function from FNV-1 to the recommended
+    FNV-1a variant.
 
   [ Raphaël Hertzog ]
   * Explain better in deb-triggers(5) why interest/activate-noawait should be

+ 2 - 2
lib/dpkg/strhash.c

@@ -27,7 +27,7 @@
 #define FNV_MIXING_PRIME 16777619UL
 
 /**
- * Fowler/Noll/Vo -- FNV-1 simple string hash.
+ * Fowler/Noll/Vo -- FNV-1a simple string hash.
  *
  * For more info, @see <http://www.isthe.com/chongo/tech/comp/fnv/index.html>.
  *
@@ -42,8 +42,8 @@ str_fnv_hash(const char *str)
 	register unsigned int p = FNV_MIXING_PRIME;
 
 	while (*str) {
-		h *= p;
 		h ^= *str++;
+		h *= p;
 	}
 
 	return h;

+ 17 - 17
lib/dpkg/test/t-string.c

@@ -57,23 +57,23 @@ test_str_match_end(void)
 static void
 test_str_fnv_hash(void)
 {
-	test_pass(str_fnv_hash("") == 0x811c9dc5UL);
-	test_pass(str_fnv_hash("a") == 0x050c5d7eUL);
-	test_pass(str_fnv_hash("b") == 0x050c5d7dUL);
-	test_pass(str_fnv_hash("c") == 0x050c5d7cUL);
-	test_pass(str_fnv_hash("d") == 0x050c5d7bUL);
-	test_pass(str_fnv_hash("e") == 0x050c5d7aUL);
-	test_pass(str_fnv_hash("f") == 0x050c5d79UL);
-	test_pass(str_fnv_hash("fo") == 0x6b772514UL);
-	test_pass(str_fnv_hash("foo") == 0x408f5e13UL);
-	test_pass(str_fnv_hash("foob") == 0xb4b1178bUL);
-	test_pass(str_fnv_hash("fooba") == 0xfdc80fb0UL);
-	test_pass(str_fnv_hash("foobar") == 0x31f0b262UL);
-
-	test_pass(str_fnv_hash("test-string") == 0x4a5b5149UL);
-	test_pass(str_fnv_hash("Test-string") == 0xdef8cb29UL);
-	test_pass(str_fnv_hash("rest-string") == 0x7808f697UL);
-	test_pass(str_fnv_hash("Rest-string") == 0xf15be3f7UL);
+	test_pass(str_fnv_hash("") == 0x811c9dc5U);
+	test_pass(str_fnv_hash("a") == 0xe40c292cUL);
+	test_pass(str_fnv_hash("b") == 0xe70c2de5UL);
+	test_pass(str_fnv_hash("c") == 0xe60c2c52UL);
+	test_pass(str_fnv_hash("d") == 0xe10c2473UL);
+	test_pass(str_fnv_hash("e") == 0xe00c22e0UL);
+	test_pass(str_fnv_hash("f") == 0xe30c2799UL);
+	test_pass(str_fnv_hash("fo") == 0x6222e842UL);
+	test_pass(str_fnv_hash("foo") == 0xa9f37ed7UL);
+	test_pass(str_fnv_hash("foob") == 0x3f5076efUL);
+	test_pass(str_fnv_hash("fooba") == 0x39aaa18aUL);
+	test_pass(str_fnv_hash("foobar") == 0xbf9cf968UL);
+
+	test_pass(str_fnv_hash("test-string") == 0xd28f6e61UL);
+	test_pass(str_fnv_hash("Test-string") == 0x00a54b81UL);
+	test_pass(str_fnv_hash("rest-string") == 0x1cdeebffUL);
+	test_pass(str_fnv_hash("Rest-string") == 0x20464b9fUL);
 }
 
 static void