47#define INITIAL_HT_SIZE 241
51 hash_str_lookup( FT_Hashkey* key )
53 const char* kp = key->str;
59 res = ( res << 5 ) - res + (FT_ULong)*kp++;
66 hash_num_lookup( FT_Hashkey* key )
68 FT_ULong num = (FT_ULong)key->num;
74 res = ( res << 5 ) - res + ( ( num >> 8 ) & 0xFF );
75 res = ( res << 5 ) - res + ( ( num >> 16 ) & 0xFF );
76 res = ( res << 5 ) - res + ( ( num >> 24 ) & 0xFF );
83 hash_str_compare( FT_Hashkey* a,
86 if ( a->str[0] == b->str[0] &&
87 ft_strcmp( a->str, b->str ) == 0 )
95 hash_num_compare( FT_Hashkey* a,
98 if ( a->num == b->num )
106 hash_bucket( FT_Hashkey key,
110 FT_Hashnode* bp = hash->table;
114 res = (hash->lookup)( &key );
116 ndp = bp + ( res % hash->size );
119 if ( (hash->compare)( &(*ndp)->key, &key ) )
124 ndp = bp + ( hash->size - 1 );
132 hash_rehash( FT_Hash hash,
135 FT_Hashnode* obp = hash->table;
139 FT_UInt i, sz = hash->size;
140 FT_Error error = FT_Err_Ok;
144 hash->limit = hash->size / 3;
146 if ( FT_NEW_ARRAY( hash->table, hash->size ) )
149 for ( i = 0, bp = obp; i < sz; i++, bp++ )
153 nbp = hash_bucket( (*bp)->key, hash );
166 hash_init( FT_Hash hash,
170 FT_UInt sz = INITIAL_HT_SIZE;
175 hash->limit = sz / 3;
180 hash->lookup = hash_num_lookup;
181 hash->compare = hash_num_compare;
185 hash->lookup = hash_str_lookup;
186 hash->compare = hash_str_compare;
189 FT_MEM_NEW_ARRAY( hash->table, sz );
196 ft_hash_str_init( FT_Hash hash,
199 return hash_init( hash, 0, memory );
204 ft_hash_num_init( FT_Hash hash,
207 return hash_init( hash, 1, memory );
212 ft_hash_str_free( FT_Hash hash,
217 FT_UInt sz = hash->size;
218 FT_Hashnode* bp = hash->table;
222 for ( i = 0; i < sz; i++, bp++ )
225 FT_FREE( hash->table );
234 hash_insert( FT_Hashkey key,
241 FT_Hashnode* bp = hash_bucket( key, hash );
242 FT_Error error = FT_Err_Ok;
255 if ( hash->used >= hash->limit )
257 error = hash_rehash( hash, memory );
264 else if ( overwrite )
273 ft_hash_str_insert(
const char* key,
283 return hash_insert( hk, data, hash, memory, TRUE );
288 ft_hash_num_insert( FT_Int num,
298 return hash_insert( hk, data, hash, memory, TRUE );
303 ft_hash_str_insert_no_overwrite(
const char* key,
313 return hash_insert( hk, data, hash, memory, FALSE );
318 ft_hash_num_insert_no_overwrite( FT_Int num,
328 return hash_insert( hk, data, hash, memory, FALSE );
333 hash_lookup( FT_Hashkey key,
336 FT_Hashnode* np = hash_bucket( key, hash );
339 return (*np) ? &(*np)->data
345 ft_hash_str_lookup(
const char* key,
353 return hash_lookup( hk, hash );
358 ft_hash_num_lookup( FT_Int num,
366 return hash_lookup( hk, hash );
371 ft_hash_num_iterator( FT_UInt *idx,
376 FT_Hashnode nn = NULL;
381 if ( *idx >= hash->size )
384 nn = hash->table[*idx];
403 ft_hash_str_iterator( FT_UInt *idx,
408 FT_Hashnode nn = NULL;
413 if ( *idx >= hash->size )
416 nn = hash->table[*idx];