Skip to content

Commit

Permalink
optimize rehash
Browse files Browse the repository at this point in the history
Now that hash bins are power-of-two sized, rehashing a hash literally
doubles its bins.  If a hash has 2^n bins and an entry has hash value
of k, k % (2^n) and k % 2^(n+1) can differ at most one bits i.e. MSB.
If they are the identical, the entry do not move.  Even if they
differ,  the destination address is obvious: 2^n+k.
  • Loading branch information
shyouhei committed Jan 20, 2014
1 parent 7c7e414 commit f7ca891
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions st.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,18 +589,27 @@ rehash(register st_table *table)
{
register st_table_entry *ptr, **new_bins;
st_index_t new_num_bins, hash_val;
st_index_t i = table->num_bins, j;

new_num_bins = new_size(table->num_bins+1);
new_bins = st_realloc_bins(table->bins, new_num_bins, table->num_bins);
new_bins = realloc(table->bins, new_num_bins * sizeof(new_bins[0]));
table->num_bins = new_num_bins;
table->bins = new_bins;

if ((ptr = table->head) != 0) {
do {
hash_val = hash_pos(ptr->hash, new_num_bins);
ptr->next = new_bins[hash_val];
new_bins[hash_val] = ptr;
} while ((ptr = ptr->fore) != 0);
for (j=0; j<i; j++) {
st_table_entry **prev = &new_bins[j];

new_bins[i + j] = 0;
while (ptr = *prev) {
if (hash_pos(ptr->hash, new_num_bins) == j) {
prev = &ptr->next; /* OK, no move */
}
else {
*prev = ptr->next;
ptr->next = new_bins[i + j];
new_bins[i + j] = ptr;
}
}
}
}

Expand Down

0 comments on commit f7ca891

Please sign in to comment.