On Fri, 2010-01-08 at 11:15 +1100, Bojan Smojver wrote:
> Why can't we just use malloc() for this and hang a cleanup off the
> pool? It would use less memory anyway than having another pool for
> this.
Quick and dirty example of what I mean here.
--
Bojan
Index: tables/apr_hash.c
===================================================================
--- tables/apr_hash.c (revision 897059)
+++ tables/apr_hash.c (working copy)
@@ -69,13 +69,9 @@
* index rather than the size so that we can use bitwise-AND for
* modular arithmetic. The count of hash entries may be greater
* depending on the chosen collision rate.
- *
- * We allocate the bucket array in a sub-pool, "array_pool". This allows us
- * to reclaim the old bucket array after an expansion.
*/
struct apr_hash_t {
apr_pool_t *pool;
- apr_pool_t *array_pool;
apr_hash_entry_t **array;
apr_hash_index_t iterator; /* For apr_hash_first(NULL, ...) */
unsigned int count, max;
@@ -90,22 +86,29 @@
* Hash creation functions.
*/
+static apr_status_t array_cleanup(void *data)
+{
+ free(data);
+ return APR_SUCCESS;
+}
+
static apr_hash_entry_t **alloc_array(apr_hash_t *ht, unsigned int max)
{
- return apr_pcalloc(ht->array_pool, sizeof(*ht->array) * (max + 1));
+ void *mem;
+
+ mem = calloc(max + 1, sizeof(*ht->array));
+ apr_pool_cleanup_register(ht->pool, mem,
+ array_cleanup,apr_pool_cleanup_null);
+
+ return mem;
}
APR_DECLARE(apr_hash_t *) apr_hash_make(apr_pool_t *pool)
{
- apr_pool_t *array_pool;
apr_hash_t *ht;
- if (apr_pool_create(&array_pool, pool) != APR_SUCCESS)
- return NULL;
-
ht = apr_palloc(pool, sizeof(apr_hash_t));
ht->pool = pool;
- ht->array_pool = array_pool;
ht->free = NULL;
ht->count = 0;
ht->max = INITIAL_MAX;
@@ -172,17 +175,10 @@
static void expand_array(apr_hash_t *ht)
{
- apr_pool_t *new_array_pool;
- apr_pool_t *old_array_pool;
apr_hash_index_t *hi;
apr_hash_entry_t **new_array;
unsigned int new_max;
- if (apr_pool_create(&new_array_pool, ht->pool) != APR_SUCCESS)
- return; /* Give up and don't try to expand the array */
- old_array_pool = ht->array_pool;
- ht->array_pool = new_array_pool;
-
new_max = ht->max * 2 + 1;
new_array = alloc_array(ht, new_max);
for (hi = apr_hash_first(NULL, ht); hi; hi = apr_hash_next(hi)) {
@@ -190,10 +186,9 @@
hi->this->next = new_array[i];
new_array[i] = hi->this;
}
+ apr_pool_cleanup_run(ht->pool, ht->array, array_cleanup);
ht->array = new_array;
ht->max = new_max;
-
- apr_pool_destroy(old_array_pool);
}
APR_DECLARE_NONSTD(unsigned int) apr_hashfunc_default(const char *char_key,
@@ -306,18 +301,13 @@
APR_DECLARE(apr_hash_t *) apr_hash_copy(apr_pool_t *pool,
const apr_hash_t *orig)
{
- apr_pool_t *array_pool;
apr_hash_t *ht;
apr_hash_entry_t *new_vals;
unsigned int i, j;
- if (apr_pool_create(&array_pool, pool) != APR_SUCCESS)
- return NULL;
-
ht = apr_palloc(pool, sizeof(apr_hash_t) +
sizeof(apr_hash_entry_t) * orig->count);
ht->pool = pool;
- ht->array_pool = array_pool;
ht->free = NULL;
ht->count = orig->count;
ht->max = orig->max;
@@ -413,7 +403,6 @@
const void *data),
const void *data)
{
- apr_pool_t *array_pool;
apr_hash_t *res;
apr_hash_entry_t *new_vals = NULL;
apr_hash_entry_t *iter;
@@ -437,12 +426,8 @@
}
#endif
- if (apr_pool_create(&array_pool, p) != APR_SUCCESS)
- return NULL;
-
res = apr_palloc(p, sizeof(apr_hash_t));
res->pool = p;
- res->array_pool = array_pool;
res->free = NULL;
res->hash_func = base->hash_func;
res->count = base->count;