Browse Source

r14682@Kushana: nickm | 2007-09-28 15:23:38 -0400
From little acorns: redo our string and digest hashing code to be faster, since this stuff may be critical-path.


svn:r11700

Nick Mathewson 16 years ago
parent
commit
38ac9f6005
3 changed files with 30 additions and 2 deletions
  1. 7 0
      ChangeLog
  2. 7 2
      src/common/container.c
  3. 16 0
      src/common/ht.h

+ 7 - 0
ChangeLog

@@ -21,6 +21,13 @@ Changes in version 0.2.0.8-alpha - 2007-??-??
     - Fix logic to look up a cert by its signing key digest.  Bugfix on
       0.2.0.7-alpha.
 
+  o Minor bugfixes (performance):
+    - Use a slightly simpler string hashing algorithm (copying Python's
+      instead of Java's) and optimize our digest hashing algorithm to take
+      advantage of 64-bit platforms and to remove some possibly-costly
+      voodoo.
+
+
 Changes in version 0.2.0.7-alpha - 2007-09-21
   o New directory authorities:
     - Set up moria1 and tor26 as the first v3 directory authorities. See

+ 7 - 2
src/common/container.c

@@ -694,8 +694,13 @@ digestmap_entries_eq(const digestmap_entry_t *a, const digestmap_entry_t *b)
 static INLINE unsigned int
 digestmap_entry_hash(const digestmap_entry_t *a)
 {
-  uint32_t *p = (uint32_t*)a->key;
-  return ht_improve_hash(p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4]);
+#if SIZEOF_INT != 8
+  const uint32_t *p = (const uint32_t*)a->key;
+  return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4];
+#else
+  const uint64_t *p = (const uint64_t*)a->key;
+  return p[0] ^ p[1];
+#endif
 }
 
 HT_PROTOTYPE(strmap_impl, strmap_entry_t, node, strmap_entry_hash,

+ 16 - 0
src/common/ht.h

@@ -65,6 +65,7 @@ ht_improve_hash(unsigned h)
   return h;
 }
 
+#if 0
 /** Basic string hash function, from Java standard String.hashCode(). */
 static INLINE unsigned
 ht_string_hash(const char *s)
@@ -77,6 +78,21 @@ ht_string_hash(const char *s)
   }
   return h;
 }
+#endif
+
+/** Basic string hash function, from Python's str.__hash__() */
+static INLINE unsigned
+ht_string_hash(const char *s)
+{
+  unsigned h;
+  const unsigned char *cp = (const unsigned char *)s;
+  h = *cp << 7;
+  while (*cp) {
+    h = (1000003*h) ^ *cp++;
+  }
+  h ^= (cp-(const unsigned char*)s);
+  return h;
+}
 
 #define _HT_SET_HASH(elm, field, hashfn)        \
     (elm)->field.hte_hash = hashfn(elm)