Commit 1b7549ccc71c121439974359513d5aa53f9cc910

Werner Lemberg 2015-12-20T08:00:33

[base] Introduce hash lookup, compare, and free function pointers. * include/freetype/internal/fthash.c (FT_Hash_LookupFunc, FT_Hash_CompareFunc, FT_Hash_FreeFunc): New typedefs. (FT_HashRec): Add `lookup', `compare', and `free' fields. * src/base/fthash.c (hash_str_lookup, hash_str_compare, hash_str_free): New functions. (ft_hash_init): Set function pointers. (hash_bucket, ft_hash_free): Use them.

diff --git a/ChangeLog b/ChangeLog
index 54ebb86..154a2ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2015-12-20  Werner Lemberg  <wl@gnu.org>
 
+	[base] Introduce hash lookup, compare, and free function pointers.
+
+	* include/freetype/internal/fthash.c (FT_Hash_LookupFunc,
+	FT_Hash_CompareFunc, FT_Hash_FreeFunc): New typedefs.
+	(FT_HashRec): Add `lookup', `compare', and `free' fields.
+
+	* src/base/fthash.c (hash_str_lookup, hash_str_compare,
+	hash_str_free): New functions.
+	(ft_hash_init): Set function pointers.
+	(hash_bucket, ft_hash_free): Use them.
+
+2015-12-20  Werner Lemberg  <wl@gnu.org>
+
 	[base, bdf] Use a union as a hash key.
 
 	We want to support both an integer and a string key later on.
diff --git a/include/freetype/internal/fthash.h b/include/freetype/internal/fthash.h
index 3449b75..80c4b9b 100644
--- a/include/freetype/internal/fthash.h
+++ b/include/freetype/internal/fthash.h
@@ -68,12 +68,28 @@ FT_BEGIN_HEADER
   typedef struct FT_HashnodeRec_  *FT_Hashnode;
 
 
+  typedef FT_ULong
+  (*FT_Hash_LookupFunc)( FT_Hashkey*  key );
+
+  typedef FT_Bool
+  (*FT_Hash_CompareFunc)( FT_Hashkey*  a,
+                          FT_Hashkey*  b );
+
+  typedef void
+  (*FT_Hash_FreeFunc)( FT_Hashnode  hn,
+                       FT_Memory    memory );
+
+
   typedef struct  FT_HashRec_
   {
     FT_UInt  limit;
     FT_UInt  size;
     FT_UInt  used;
 
+    FT_Hash_LookupFunc   lookup;
+    FT_Hash_CompareFunc  compare;
+    FT_Hash_FreeFunc     free;
+
     FT_Hashnode*  table;
 
   } FT_HashRec;
diff --git a/src/base/fthash.c b/src/base/fthash.c
index 091646a..d73c5df 100644
--- a/src/base/fthash.c
+++ b/src/base/fthash.c
@@ -46,27 +46,56 @@
 #define INITIAL_HT_SIZE  241
 
 
+  static FT_ULong
+  hash_str_lookup( FT_Hashkey*  key )
+  {
+    const char*  kp  = key->str;
+    FT_ULong     res = 0;
+
+
+    /* Mocklisp hash function. */
+    while ( *kp )
+      res = ( res << 5 ) - res + (FT_ULong)*kp++;
+
+    return res;
+  }
+
+
+  static FT_Bool
+  hash_str_compare( FT_Hashkey*  a,
+                    FT_Hashkey*  b )
+  {
+    if ( a->str[0] == b->str[0]           &&
+         ft_strcmp( a->str, b->str ) == 0 )
+      return 1;
+
+   return 0;
+  }
+
+
+  static void
+  hash_str_free( FT_Hashnode  hn,
+                 FT_Memory    memory )
+  {
+    FT_FREE( hn );
+  }
+
+
   static FT_Hashnode*
   hash_bucket( FT_Hashkey  key,
                FT_Hash     hash )
   {
-    const char*   kp  = key.str;
     FT_ULong      res = 0;
     FT_Hashnode*  bp  = hash->table;
     FT_Hashnode*  ndp;
 
 
-    /* Mocklisp hash function. */
-    while ( *kp )
-      res = ( res << 5 ) - res + (FT_ULong)*kp++;
+    res = (hash->lookup)( &key );
 
     ndp = bp + ( res % hash->size );
     while ( *ndp )
     {
-      kp = (*ndp)->key.str;
-
-      if ( kp[0] == key.str[0]           &&
-           ft_strcmp( kp, key.str ) == 0 )
+      if ( (hash->compare)( &(*ndp)->key, &key ) )
         break;
 
       ndp--;
@@ -124,6 +153,10 @@
     hash->limit = sz / 3;
     hash->used  = 0;
 
+    hash->lookup  = hash_str_lookup;
+    hash->compare = hash_str_compare;
+    hash->free    = hash_str_free;
+
     FT_MEM_NEW_ARRAY( hash->table, sz );
 
     return error;
@@ -141,8 +174,11 @@
       FT_UInt       i;
 
 
-      for ( i = 0; i < sz; i++, bp++ )
-        FT_FREE( *bp );
+      if ( hash->free )
+      {
+        for ( i = 0; i < sz; i++, bp++ )
+          (hash->free)( *bp, memory );
+      }
 
       FT_FREE( hash->table );
     }