From ab32e8f14e18bfbb1bb131537f7515084e3120aa Mon Sep 17 00:00:00 2001 From: Ricardo Rocha Date: Mon, 12 Dec 2011 17:24:58 +0000 Subject: [PATCH] fix expand hash tables with TRIE_LOCK_AT_WRITE_LEVEL schemes --- OPTYap/tab.macros.h | 22 +++--- OPTYap/tab.structs.h | 2 - OPTYap/tab.tries.c | 2 +- OPTYap/tab.tries.i | 167 ++++++++++++++++++++++--------------------- 4 files changed, 99 insertions(+), 94 deletions(-) diff --git a/OPTYap/tab.macros.h b/OPTYap/tab.macros.h index 7960daeb0..d83698e86 100644 --- a/OPTYap/tab.macros.h +++ b/OPTYap/tab.macros.h @@ -179,17 +179,17 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define IS_INVALID_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x2) /* trie hashes */ -#define MAX_NODES_PER_TRIE_LEVEL 8 -#define MAX_NODES_PER_BUCKET (MAX_NODES_PER_TRIE_LEVEL / 2) -#define BASE_HASH_BUCKETS 64 -#define HASH_ENTRY(ENTRY, SEED) ((((unsigned long int) ENTRY) >> NumberOfLowTagBits) & (SEED)) -#define SUBGOAL_TRIE_HASH_MARK ((Term) MakeTableVarTerm(MAX_TABLE_VARS)) -#define IS_SUBGOAL_TRIE_HASH(NODE) (TrNode_entry(NODE) == SUBGOAL_TRIE_HASH_MARK) -#define ANSWER_TRIE_HASH_MARK 0 -#define IS_ANSWER_TRIE_HASH(NODE) (TrNode_instr(NODE) == ANSWER_TRIE_HASH_MARK) -#define GLOBAL_TRIE_HASH_MARK ((Term) MakeTableVarTerm(MAX_TABLE_VARS)) -#define IS_GLOBAL_TRIE_HASH(NODE) (TrNode_entry(NODE) == GLOBAL_TRIE_HASH_MARK) -#define HASH_TRIE_LOCK(NODE) GLOBAL_trie_locks((((unsigned long int) (NODE)) >> 5) & (TRIE_LOCK_BUCKETS - 1)) +#define MAX_NODES_PER_TRIE_LEVEL 8 +#define MAX_NODES_PER_BUCKET (MAX_NODES_PER_TRIE_LEVEL / 2) +#define BASE_HASH_BUCKETS 64 +#define HASH_ENTRY(ENTRY, NUM_BUCKETS) ((((unsigned long int) ENTRY) >> NumberOfLowTagBits) & (NUM_BUCKETS - 1)) +#define SUBGOAL_TRIE_HASH_MARK ((Term) MakeTableVarTerm(MAX_TABLE_VARS)) +#define IS_SUBGOAL_TRIE_HASH(NODE) (TrNode_entry(NODE) == SUBGOAL_TRIE_HASH_MARK) +#define ANSWER_TRIE_HASH_MARK 0 +#define IS_ANSWER_TRIE_HASH(NODE) (TrNode_instr(NODE) == ANSWER_TRIE_HASH_MARK) +#define GLOBAL_TRIE_HASH_MARK ((Term) MakeTableVarTerm(MAX_TABLE_VARS)) +#define IS_GLOBAL_TRIE_HASH(NODE) (TrNode_entry(NODE) == GLOBAL_TRIE_HASH_MARK) +#define HASH_TRIE_LOCK(NODE) GLOBAL_trie_locks((((unsigned long int) (NODE)) >> 5) & (TRIE_LOCK_BUCKETS - 1)) /* auxiliary stack */ #define STACK_PUSH_UP(ITEM, STACK) *--(STACK) = (CELL)(ITEM) diff --git a/OPTYap/tab.structs.h b/OPTYap/tab.structs.h index fa4338e9b..37de4eb78 100644 --- a/OPTYap/tab.structs.h +++ b/OPTYap/tab.structs.h @@ -148,9 +148,7 @@ typedef struct global_trie_hash { #define Hash_mark(X) ((X)->mark) #define Hash_num_buckets(X) ((X)->number_of_buckets) -#define Hash_seed(X) ((X)->number_of_buckets - 1) #define Hash_buckets(X) ((X)->buckets) -#define Hash_bucket(X,N) ((X)->buckets + N) #define Hash_num_nodes(X) ((X)->number_of_nodes) #define Hash_previous(X) ((X)->previous) #define Hash_next(X) ((X)->next) diff --git a/OPTYap/tab.tries.c b/OPTYap/tab.tries.c index bec2c648e..6c51468cd 100644 --- a/OPTYap/tab.tries.c +++ b/OPTYap/tab.tries.c @@ -456,7 +456,7 @@ static void free_global_trie_branch(gt_node_ptr current_node) { child_node = TrNode_child(parent_node); if (IS_GLOBAL_TRIE_HASH(child_node)) { gt_hash_ptr hash = (gt_hash_ptr) child_node; - gt_node_ptr *bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(current_node), Hash_seed(hash))); + gt_node_ptr *bucket = Hash_buckets(hash) + HASH_ENTRY(TrNode_entry(current_node), Hash_num_buckets(hash)); int num_nodes = --Hash_num_nodes(hash); child_node = *bucket; if (child_node != current_node) { diff --git a/OPTYap/tab.tries.i b/OPTYap/tab.tries.i index e36d08ae3..f0e12fc7a 100644 --- a/OPTYap/tab.tries.i +++ b/OPTYap/tab.tries.i @@ -95,7 +95,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s new_subgoal_trie_hash(hash, count_nodes, tab_ent); chain_node = child_node; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); + bucket = Hash_buckets(hash) + HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; @@ -114,7 +114,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s sg_node_ptr *bucket; int count_nodes = 0; hash = (sg_hash_ptr) child_node; - bucket = Hash_bucket(hash, HASH_ENTRY(t, Hash_seed(hash))); + bucket = Hash_buckets(hash) + HASH_ENTRY(t, Hash_num_buckets(hash)); child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) { @@ -130,26 +130,27 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s count_nodes++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ - sg_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; - int seed; - first_old_bucket = Hash_buckets(hash); - old_bucket = first_old_bucket + Hash_num_buckets(hash); - Hash_num_buckets(hash) *= 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); - seed = Hash_seed(hash); + sg_node_ptr chain_node, next_node, *old_bucket, *hash_old_buckets, *hash_new_buckets; + int num_buckets; + num_buckets = Hash_num_buckets(hash) * 2; + ALLOC_HASH_BUCKETS(hash_new_buckets, num_buckets); + hash_old_buckets = Hash_buckets(hash); + old_bucket = hash_old_buckets + Hash_num_buckets(hash); do { if (*--old_bucket) { chain_node = *old_bucket; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), seed)); + bucket = hash_new_buckets + HASH_ENTRY(TrNode_entry(chain_node), num_buckets); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; chain_node = next_node; } while (chain_node); } - } while (old_bucket != first_old_bucket); - FREE_HASH_BUCKETS(first_old_bucket); + } while (old_bucket != hash_old_buckets); + FREE_HASH_BUCKETS(hash_old_buckets); + Hash_buckets(hash) = hash_new_buckets; + Hash_num_buckets(hash) = num_buckets; } UNLOCK_SUBGOAL_NODE(parent_node); return child_node; @@ -252,7 +253,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s new_subgoal_trie_hash(hash, count_nodes, tab_ent); chain_node = child_node; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); + bucket = Hash_buckets(hash) + HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; @@ -270,10 +271,10 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s subgoal_trie_hash: { /* trie nodes with hashing */ sg_node_ptr *bucket, first_node; - int seed, count_nodes = 0; + int num_buckets, count_nodes = 0; - seed = Hash_seed(hash); - bucket = Hash_bucket(hash, HASH_ENTRY(t, seed)); + num_buckets = Hash_num_buckets(hash); + bucket = Hash_buckets(hash) + HASH_ENTRY(t, num_buckets); first_node = child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) @@ -285,7 +286,7 @@ subgoal_trie_hash: NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); #endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ LOCK_SUBGOAL_NODE(parent_node); - if (seed != Hash_seed(hash)) { + if (num_buckets != Hash_num_buckets(hash)) { /* the hash has been expanded */ #ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK FREE_SUBGOAL_TRIE_NODE(child_node); @@ -319,25 +320,26 @@ subgoal_trie_hash: count_nodes++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ - sg_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; - first_old_bucket = Hash_buckets(hash); - old_bucket = first_old_bucket + Hash_num_buckets(hash); - Hash_num_buckets(hash) *= 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); - seed = Hash_seed(hash); + sg_node_ptr chain_node, next_node, *old_bucket, *hash_old_buckets, *hash_new_buckets; + num_buckets = Hash_num_buckets(hash) * 2; + ALLOC_HASH_BUCKETS(hash_new_buckets, num_buckets); + hash_old_buckets = Hash_buckets(hash); + old_bucket = hash_old_buckets + Hash_num_buckets(hash); do { if (*--old_bucket) { chain_node = *old_bucket; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), seed)); + bucket = hash_new_buckets + HASH_ENTRY(TrNode_entry(chain_node), num_buckets); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; chain_node = next_node; } while (chain_node); } - } while (old_bucket != first_old_bucket); - FREE_HASH_BUCKETS(first_old_bucket); + } while (old_bucket != hash_old_buckets); + FREE_HASH_BUCKETS(hash_old_buckets); + Hash_buckets(hash) = hash_new_buckets; + Hash_num_buckets(hash) = num_buckets; } UNLOCK_SUBGOAL_NODE(parent_node); return child_node; @@ -391,7 +393,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n new_answer_trie_hash(hash, count_nodes, sg_fr); chain_node = child_node; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); + bucket = Hash_buckets(hash) + HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; @@ -410,7 +412,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n ans_node_ptr *bucket; int count_nodes = 0; hash = (ans_hash_ptr) child_node; - bucket = Hash_bucket(hash, HASH_ENTRY(t, Hash_seed(hash))); + bucket = Hash_buckets(hash) + HASH_ENTRY(t, Hash_num_buckets(hash)); child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) { @@ -426,26 +428,27 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n count_nodes++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ - ans_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; - int seed; - first_old_bucket = Hash_buckets(hash); - old_bucket = first_old_bucket + Hash_num_buckets(hash); - Hash_num_buckets(hash) *= 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); - seed = Hash_seed(hash); + ans_node_ptr chain_node, next_node, *old_bucket, *hash_old_buckets, *hash_new_buckets; + int num_buckets; + num_buckets = Hash_num_buckets(hash) * 2; + ALLOC_HASH_BUCKETS(hash_new_buckets, num_buckets); + hash_old_buckets = Hash_buckets(hash); + old_bucket = hash_old_buckets + Hash_num_buckets(hash); do { if (*--old_bucket) { chain_node = *old_bucket; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), seed)); + bucket = hash_new_buckets + HASH_ENTRY(TrNode_entry(chain_node), num_buckets); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; chain_node = next_node; } while (chain_node); } - } while (old_bucket != first_old_bucket); - FREE_HASH_BUCKETS(first_old_bucket); + } while (old_bucket != hash_old_buckets); + FREE_HASH_BUCKETS(hash_old_buckets); + Hash_buckets(hash) = hash_new_buckets; + Hash_num_buckets(hash) = num_buckets; } UNLOCK_ANSWER_NODE(parent_node); return child_node; @@ -549,7 +552,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n new_answer_trie_hash(hash, count_nodes, sg_fr); chain_node = child_node; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); + bucket = Hash_buckets(hash) + HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; @@ -567,10 +570,10 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n answer_trie_hash: { /* trie nodes with hashing */ ans_node_ptr *bucket, first_node; - int seed, count_nodes = 0; + int num_buckets, count_nodes = 0; - seed = Hash_seed(hash); - bucket = Hash_bucket(hash, HASH_ENTRY(t, seed)); + num_buckets = Hash_num_buckets(hash); + bucket = Hash_buckets(hash) + HASH_ENTRY(t, num_buckets); first_node = child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) @@ -582,7 +585,7 @@ answer_trie_hash: NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); #endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ LOCK_ANSWER_NODE(parent_node); - if (seed != Hash_seed(hash)) { + if (num_buckets != Hash_num_buckets(hash)) { /* the hash has been expanded */ #ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK FREE_ANSWER_TRIE_NODE(child_node); @@ -615,26 +618,27 @@ answer_trie_hash: Hash_num_nodes(hash)++; count_nodes++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { - /* expand current hash */ - ans_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; - first_old_bucket = Hash_buckets(hash); - old_bucket = first_old_bucket + Hash_num_buckets(hash); - Hash_num_buckets(hash) *= 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); - seed = Hash_seed(hash); + /* expand current hash */ + ans_node_ptr chain_node, next_node, *old_bucket, *hash_old_buckets, *hash_new_buckets; + num_buckets = Hash_num_buckets(hash) * 2; + ALLOC_HASH_BUCKETS(hash_new_buckets, num_buckets); + hash_old_buckets = Hash_buckets(hash); + old_bucket = hash_old_buckets + Hash_num_buckets(hash); do { if (*--old_bucket) { chain_node = *old_bucket; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), seed)); + bucket = hash_new_buckets + HASH_ENTRY(TrNode_entry(chain_node), num_buckets); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; chain_node = next_node; } while (chain_node); } - } while (old_bucket != first_old_bucket); - FREE_HASH_BUCKETS(first_old_bucket); + } while (old_bucket != hash_old_buckets); + FREE_HASH_BUCKETS(hash_old_buckets); + Hash_buckets(hash) = hash_new_buckets; + Hash_num_buckets(hash) = num_buckets; } UNLOCK_ANSWER_NODE(parent_node); return child_node; @@ -686,7 +690,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node new_global_trie_hash(hash, count_nodes); chain_node = child_node; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); + bucket = Hash_buckets(hash) + HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; @@ -705,7 +709,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node gt_node_ptr *bucket; int count_nodes = 0; hash = (gt_hash_ptr) child_node; - bucket = Hash_bucket(hash, HASH_ENTRY(t, Hash_seed(hash))); + bucket = Hash_buckets(hash) + HASH_ENTRY(t, Hash_num_buckets(hash)); child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) { @@ -721,26 +725,27 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node count_nodes++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ - gt_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; - int seed; - first_old_bucket = Hash_buckets(hash); - old_bucket = first_old_bucket + Hash_num_buckets(hash); - Hash_num_buckets(hash) *= 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); - seed = Hash_seed(hash); + gt_node_ptr chain_node, next_node, *old_bucket, *hash_old_buckets, *hash_new_buckets; + int num_buckets; + num_buckets = Hash_num_buckets(hash) * 2; + ALLOC_HASH_BUCKETS(hash_new_buckets, num_buckets); + hash_old_buckets = Hash_buckets(hash); + old_bucket = hash_old_buckets + Hash_num_buckets(hash); do { if (*--old_bucket) { chain_node = *old_bucket; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), seed)); + bucket = hash_new_buckets + HASH_ENTRY(TrNode_entry(chain_node), num_buckets); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; chain_node = next_node; } while (chain_node); } - } while (old_bucket != first_old_bucket); - FREE_HASH_BUCKETS(first_old_bucket); + } while (old_bucket != hash_old_buckets); + FREE_HASH_BUCKETS(hash_old_buckets); + Hash_buckets(hash) = hash_new_buckets; + Hash_num_buckets(hash) = num_buckets; } UNLOCK_GLOBAL_NODE(parent_node); return child_node; @@ -752,6 +757,7 @@ static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr parent_n #else static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node, Term t) { #endif /* MODE_GLOBAL_TRIE_ENTRY */ + CACHE_REGS gt_node_ptr child_node; gt_hash_ptr hash; @@ -840,10 +846,10 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) { /* alloc a new hash */ gt_node_ptr chain_node, next_node, *bucket; - new_answer_trie_hash(hash, count_nodes, sg_fr); + new_global_trie_hash(hash, count_nodes); chain_node = child_node; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); + bucket = Hash_buckets(hash) + HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; @@ -861,10 +867,10 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node global_trie_hash: { /* trie nodes with hashing */ gt_node_ptr *bucket, first_node; - int seed, count_nodes = 0; + int num_buckets, count_nodes = 0; - seed = Hash_seed(hash); - bucket = Hash_bucket(hash, HASH_ENTRY(t, seed)); + num_buckets = Hash_num_buckets(hash); + bucket = Hash_buckets(hash) + HASH_ENTRY(t, num_buckets); first_node = child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) @@ -876,7 +882,7 @@ global_trie_hash: NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); #endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ LOCK_GLOBAL_NODE(parent_node); - if (seed != Hash_seed(hash)) { + if (num_buckets != Hash_num_buckets(hash)) { /* the hash has been expanded */ #ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK FREE_GLOBAL_TRIE_NODE(child_node); @@ -910,25 +916,26 @@ global_trie_hash: count_nodes++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ - gt_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; - first_old_bucket = Hash_buckets(hash); - old_bucket = first_old_bucket + Hash_num_buckets(hash); - Hash_num_buckets(hash) *= 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); - seed = Hash_seed(hash); + gt_node_ptr chain_node, next_node, *old_bucket, *hash_old_buckets, *hash_new_buckets; + num_buckets = Hash_num_buckets(hash) * 2; + ALLOC_HASH_BUCKETS(hash_new_buckets, num_buckets); + hash_old_buckets = Hash_buckets(hash); + old_bucket = hash_old_buckets + Hash_num_buckets(hash); do { if (*--old_bucket) { chain_node = *old_bucket; do { - bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), seed)); + bucket = hash_new_buckets + HASH_ENTRY(TrNode_entry(chain_node), num_buckets); next_node = TrNode_next(chain_node); TrNode_next(chain_node) = *bucket; *bucket = chain_node; chain_node = next_node; } while (chain_node); } - } while (old_bucket != first_old_bucket); - FREE_HASH_BUCKETS(first_old_bucket); + } while (old_bucket != hash_old_buckets); + FREE_HASH_BUCKETS(hash_old_buckets); + Hash_buckets(hash) = hash_new_buckets; + Hash_num_buckets(hash) = num_buckets; } UNLOCK_GLOBAL_NODE(parent_node); return child_node;