summaryrefslogtreecommitdiff
path: root/tables
diff options
context:
space:
mode:
authorfanf <fanf@13f79535-47bb-0310-9956-ffa450edef68>2000-10-30 19:56:37 +0000
committerfanf <fanf@13f79535-47bb-0310-9956-ffa450edef68>2000-10-30 19:56:37 +0000
commitba289569af19fac5b66a08b632ca0522474cad71 (patch)
tree7c8e11c496f9d5a6be32045fb53d8866348777fe /tables
parent190466f52e5aa4fa6c1efe97de01f860df024d9a (diff)
downloadlibapr-ba289569af19fac5b66a08b632ca0522474cad71.tar.gz
Fix hash resizing: the hash table size was updated before the array was,
so when iterating through the old array in order to move the elements to the new array we'd go strolling off the end and into outer space. Submitted by: Karl Fogel <kfogel@galois.collab.net> Message-ID: <200010272139.e9RLdoi28113@galois.collab.net> git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@60618 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'tables')
-rw-r--r--tables/apr_hash.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/tables/apr_hash.c b/tables/apr_hash.c
index b0385fb18..d0c9f01de 100644
--- a/tables/apr_hash.c
+++ b/tables/apr_hash.c
@@ -122,9 +122,9 @@ struct apr_hash_index_t {
* Hash creation functions.
*/
-static apr_hash_entry_t **alloc_array(apr_hash_t *ht)
+static apr_hash_entry_t **alloc_array(apr_hash_t *ht, apr_size_t max)
{
- return apr_pcalloc(ht->pool, sizeof(*ht->array) * (ht->max + 1));
+ return apr_pcalloc(ht->pool, sizeof(*ht->array) * (max + 1));
}
APR_DECLARE(apr_hash_t *) apr_make_hash(apr_pool_t *pool)
@@ -134,7 +134,7 @@ APR_DECLARE(apr_hash_t *) apr_make_hash(apr_pool_t *pool)
ht->pool = pool;
ht->count = 0;
ht->max = INITIAL_MAX;
- ht->array = alloc_array(ht);
+ ht->array = alloc_array(ht, ht->max);
return ht;
}
@@ -178,22 +178,25 @@ APR_DECLARE(void) apr_hash_this(apr_hash_index_t *hi,
/*
- * Resizing a hash table
+ * Expanding a hash table
*/
-static void resize_array(apr_hash_t *ht)
+static void expand_array(apr_hash_t *ht)
{
apr_hash_index_t *hi;
apr_hash_entry_t **new_array;
+ apr_size_t new_max;
int i;
- new_array = alloc_array(ht);
+ new_max = ht->max * 2 + 1;
+ new_array = alloc_array(ht, new_max);
for (hi = apr_hash_first(ht); hi; hi = apr_hash_next(hi)) {
i = hi->this->hash & ht->max;
hi->this->next = new_array[i];
new_array[i] = hi->this;
}
ht->array = new_array;
+ ht->max = new_max;
}
/*
@@ -274,8 +277,7 @@ static apr_hash_entry_t **find_entry(apr_hash_t *ht,
*hep = he;
/* check that the collision rate isn't too high */
if (++ht->count > ht->max) {
- ht->max = ht->max * 2 + 1;
- resize_array(ht);
+ expand_array(ht);
}
return hep;
}