[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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
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 );
}