[svn:parrot] r48614 - trunk/src
nwellnhof at svn.parrot.org
nwellnhof at svn.parrot.org
Mon Aug 23 18:14:58 UTC 2010
Author: nwellnhof
Date: Mon Aug 23 18:14:57 2010
New Revision: 48614
URL: https://trac.parrot.org/parrot/changeset/48614
Log:
Optimize expand_hash
Merge pointer relocation and rehashing into a single loop. Optimize
update of free list. Also don't assume that new_size = 2 * old_size.
Modified:
trunk/src/hash.c
Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c Mon Aug 23 14:54:49 2010 (r48613)
+++ trunk/src/hash.c Mon Aug 23 18:14:57 2010 (r48614)
@@ -739,6 +739,7 @@
const UINTVAL old_size = hash->mask + 1;
const UINTVAL new_size = old_size << 1; /* Double. Right-shift is 2x */
const UINTVAL old_nb = N_BUCKETS(old_size);
+ const UINTVAL new_nb = N_BUCKETS(new_size);
size_t offset, i;
/*
@@ -775,7 +776,7 @@
bs = new_mem;
old_bi = (HashBucket **)(bs + old_nb);
- new_bi = (HashBucket **)(bs + N_BUCKETS(new_size));
+ new_bi = (HashBucket **)(bs + new_nb);
/* things can have moved by this offset */
offset = (char *)new_mem - (char *)old_mem;
@@ -789,52 +790,40 @@
hash->mask = new_size - 1;
/* clear freshly allocated bucket index */
- memset(new_bi + old_size, 0, sizeof (HashBucket *) * old_size);
+ memset(new_bi + old_size, 0, sizeof (HashBucket *) * (new_size - old_size));
- /*
- * reloc pointers - this part would be also needed, if we
- * allocate hash memory from GC movable memory, and then
- * also the free_list needs updating (this is empty now,
- * as expand_hash is only called for that case).
- */
- if (offset) {
- size_t j;
- for (j = 0; j < old_size; ++j) {
- HashBucket **next_p = new_bi + j;
- while (*next_p) {
- *next_p = (HashBucket *)((char *)*next_p + offset);
- b = *next_p;
- next_p = &b->next;
- }
- }
- }
-
- /* recalc bucket index */
+ /* reloc pointers and recalc bucket indices */
for (i = 0; i < old_size; ++i) {
HashBucket **next_p = new_bi + i;
- while ((b = *next_p) != NULL) {
+ while (*next_p != NULL) {
+ size_t new_loc;
+
+ b = (HashBucket *)((char *)*next_p + offset);
/* rehash the bucket */
- const size_t new_loc =
- (hash->hash_val)(interp, b->key, hash->seed) & (new_size - 1);
+ new_loc = (hash->hash_val)(interp, b->key, hash->seed) & (new_size - 1);
if (i != new_loc) {
*next_p = b->next;
b->next = new_bi[new_loc];
new_bi[new_loc] = b;
}
- else
- next_p = &b->next;
+ else {
+ *next_p = b;
+ next_p = &b->next;
+ }
}
}
- /* add new buckets to free_list in reverse order
+ /* add new buckets to free_list
* lowest bucket is top on free list and will be used first */
- for (i = 0, b = (HashBucket *)new_bi - 1; i < old_nb; ++i, --b) {
- b->next = hash->free_list;
- b->key = b->value = NULL;
- hash->free_list = b;
+ for (b = bs + old_nb; b < bs + new_nb - 1; ++b) {
+ b->next = b + 1;
+ b->key = b->value = NULL;
}
+
+ b->next = hash->free_list;
+ hash->free_list = bs + old_nb;
}
More information about the parrot-commits
mailing list