[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.
This commit is contained in:
parent
609546c4b8
commit
1b7549ccc7
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -46,27 +46,56 @@
|
|||
#define INITIAL_HT_SIZE 241
|
||||
|
||||
|
||||
static FT_Hashnode*
|
||||
hash_bucket( FT_Hashkey key,
|
||||
FT_Hash hash )
|
||||
static FT_ULong
|
||||
hash_str_lookup( FT_Hashkey* key )
|
||||
{
|
||||
const char* kp = key.str;
|
||||
FT_ULong res = 0;
|
||||
FT_Hashnode* bp = hash->table;
|
||||
FT_Hashnode* ndp;
|
||||
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 )
|
||||
{
|
||||
FT_ULong res = 0;
|
||||
FT_Hashnode* bp = hash->table;
|
||||
FT_Hashnode* ndp;
|
||||
|
||||
|
||||
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 );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue