ref: 1b7549ccc71c121439974359513d5aa53f9cc910
parent: 609546c4b8d5bb27e579a6bfb8cababad068c0f0
author: Werner Lemberg <[email protected]>
date: Sun Dec 20 03:00:33 EST 2015
[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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2015-12-20 Werner Lemberg <[email protected]>
+ [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 <[email protected]>
+
[base, bdf] Use a union as a hash key.
We want to support both an integer and a string key later on.
--- a/include/freetype/internal/fthash.h
+++ b/include/freetype/internal/fthash.h
@@ -68,11 +68,27 @@
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;
--- 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 );
}