Author: pepeto Date: Mon Jun 2 09:26:58 2014 New Revision: 25011 URL: http://svn.gna.org/viewcvs/freeciv?rev=25011&view=rev Log: Cache the hash values for every entry of the hash tables.
See gna patch #4730 Modified: trunk/utility/genhash.c Modified: trunk/utility/genhash.c URL: http://svn.gna.org/viewcvs/freeciv/trunk/utility/genhash.c?rev=25011&r1=25010&r2=25011&view=diff ============================================================================== --- trunk/utility/genhash.c (original) +++ trunk/utility/genhash.c Mon Jun 2 09:26:58 2014 @@ -75,6 +75,7 @@ struct genhash_entry { void *key; void *data; + genhash_val_t hash_val; struct genhash_entry *next; }; @@ -351,7 +352,6 @@ { struct genhash_entry **new_buckets, **bucket, **end, **slot; struct genhash_entry *iter, *next; - genhash_val_fn_t key_val_func = pgenhash->key_val_func; fc_assert(new_nbuckets >= pgenhash->num_entries); @@ -361,7 +361,7 @@ end = bucket + pgenhash->num_buckets; for (; bucket < end; bucket++) { for (iter = *bucket; NULL != iter; iter = next) { - slot = new_buckets + (key_val_func(iter->key) % new_nbuckets); + slot = new_buckets + (iter->hash_val % new_nbuckets); next = iter->next; iter->next = *slot; *slot = iter; @@ -424,14 +424,16 @@ it should go if it is to be a new key. ****************************************************************************/ static inline struct genhash_entry ** -genhash_slot_lookup(const struct genhash *pgenhash, const void *key) +genhash_slot_lookup(const struct genhash *pgenhash, + const void *key, + genhash_val_t hash_val) { struct genhash_entry **slot; - for (slot = (pgenhash->buckets - + (pgenhash->key_val_func(key) % pgenhash->num_buckets)); + for (slot = (pgenhash->buckets + (hash_val % pgenhash->num_buckets)); NULL != *slot; slot = &(*slot)->next) { - if (pgenhash->key_comp_func((*slot)->key, key)) { + if (hash_val == (*slot)->hash_val + && pgenhash->key_comp_func((*slot)->key, key)) { return slot; } } @@ -472,12 +474,14 @@ ****************************************************************************/ static inline void genhash_slot_create(struct genhash *pgenhash, struct genhash_entry **slot, - const void *key, const void *data) + const void *key, const void *data, + genhash_val_t hash_val) { struct genhash_entry *entry = fc_malloc(sizeof(*entry)); entry->key = pgenhash->key_copy_func(key); entry->data = pgenhash->data_copy_func(data); + entry->hash_val = hash_val; entry->next = *slot; *slot = entry; } @@ -572,8 +576,10 @@ for (; src_bucket < end; src_bucket++, dest_bucket++) { dest_slot = dest_bucket; - for (src_iter = *src_bucket; NULL != src_iter; src_iter = src_iter->next) { - genhash_slot_create(new_genhash, dest_slot, src_iter->key, src_iter->data); + for (src_iter = *src_bucket; NULL != src_iter; + src_iter = src_iter->next) { + genhash_slot_create(new_genhash, dest_slot, src_iter->key, + src_iter->data, src_iter->hash_val); dest_slot = &(*dest_slot)->next; } } @@ -610,15 +616,17 @@ const void *data) { struct genhash_entry **slot; + genhash_val_t hash_val; fc_assert_ret_val(NULL != pgenhash, FALSE); genhash_maybe_expand(pgenhash); - slot = genhash_slot_lookup(pgenhash, key); + hash_val = pgenhash->key_val_func(key); + slot = genhash_slot_lookup(pgenhash, key, hash_val); if (NULL != *slot) { return FALSE; } else { - genhash_slot_create(pgenhash, slot, key, data); + genhash_slot_create(pgenhash, slot, key, data, hash_val); pgenhash->num_entries++; return TRUE; } @@ -649,12 +657,14 @@ void **old_pdata) { struct genhash_entry **slot; + genhash_val_t hash_val; fc_assert_action(NULL != pgenhash, genhash_default_get(old_pkey, old_pdata); return FALSE); genhash_maybe_expand(pgenhash); - slot = genhash_slot_lookup(pgenhash, key); + hash_val = pgenhash->key_val_func(key); + slot = genhash_slot_lookup(pgenhash, key, hash_val); if (NULL != *slot) { /* Replace. */ genhash_slot_get(slot, old_pkey, old_pdata); @@ -663,7 +673,7 @@ } else { /* Insert. */ genhash_default_get(old_pkey, old_pdata); - genhash_slot_create(pgenhash, slot, key, data); + genhash_slot_create(pgenhash, slot, key, data, hash_val); pgenhash->num_entries++; return FALSE; } @@ -681,7 +691,7 @@ fc_assert_action(NULL != pgenhash, genhash_default_get(NULL, pdata); return FALSE); - slot = genhash_slot_lookup(pgenhash, key); + slot = genhash_slot_lookup(pgenhash, key, pgenhash->key_val_func(key)); if (NULL != *slot) { genhash_slot_get(slot, NULL, pdata); return TRUE; @@ -716,7 +726,7 @@ return FALSE); genhash_maybe_shrink(pgenhash); - slot = genhash_slot_lookup(pgenhash, key); + slot = genhash_slot_lookup(pgenhash, key, pgenhash->key_val_func(key)); if (NULL != *slot) { genhash_slot_get(slot, deleted_pkey, deleted_pdata); genhash_slot_free(pgenhash, slot); @@ -775,7 +785,7 @@ max1 = bucket1 + pgenhash1->num_buckets; for (; bucket1 < max1; bucket1++) { for (iter1 = *bucket1; NULL != iter1; iter1 = iter1->next) { - slot2 = genhash_slot_lookup(pgenhash2, iter1->key); + slot2 = genhash_slot_lookup(pgenhash2, iter1->key, iter1->hash_val); if (NULL == *slot2 || !data_comp_func(iter1->data, (*slot2)->data)) { return FALSE; _______________________________________________ Freeciv-commits mailing list Freeciv-commits@gna.org https://mail.gna.org/listinfo/freeciv-commits