Karl Fogel wrote:
Your mailer has wrapped this patch, making it un-applyable.
Also, you don't include a ChangeLog message or state the purpose of the patch anywhere (at least not in this email). Why does apr_hash_first() need a new implementation?
-Karl
Sorry for inconvienience I might have created.
Ok, lets try again: Purpose of this patch: apr_hash_first allocates memory for the iterator struct on every call (if p!=NULL), before jumping to the first entry of the table. In applications, where a thread iterates through the table permanently (using apr_hash_first() + apr_hash_next()) this will create memory shortage in the longer run and also slows down the iteration due to repeating allocations. This patch is a proposal of separating the allocation of an iterator and jumping to the first record into two different functions.
Gunter
Index: apr/include/apr_hash.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_hash.h,v
retrieving revision 1.40
diff -u -r1.40 apr_hash.h
--- apr/include/apr_hash.h 5 Mar 2003 21:22:26 -0000 1.40
+++ apr/include/apr_hash.h 29 Apr 2003 09:40:38 -0000
@@ -145,7 +145,9 @@
* an iteration (although the results may be unpredictable unless all you do
* is delete the current entry) and multiple iterations can be in
* progress at the same time.
-
+ @remark On every call to this function, an iterator will be allocated
(except p=NULL),
+ * so be careful in using this function permanently. An alternative is to use
the functions
+ * apr_hash_alloc_iterator and apr_hash_first_iterator instead.
* @example
*/
/**
@@ -165,6 +167,45 @@
* </PRE>
*/
APR_DECLARE(apr_hash_index_t *) apr_hash_first(apr_pool_t *p, apr_hash_t *ht);
+
+/**
+ * Allocates an memory for iterating over the entries in a hash table.
+ * @param p The pool to allocate the apr_hash_index_t iterator. If this
+ * pool is NULL, then an internal, non-thread-safe iterator is used.
+ * @param ht The hash table
+ */
+APR_DECLARE(apr_hash_index_t *) apr_hash_alloc_iterator (apr_pool_t *p,
apr_hash_t *ht) ;
+
+/**
+ * Start iterating over the entries in a hash table.
+ * @param hi The iterator, which has been previously allocated, using
apr_hash_alloc_iterator
+ * @param ht The hash table
+
+ * @remark There is no restriction on adding or deleting hash entries during
+ * an iteration (although the results may be unpredictable unless all you do
+ * is delete the current entry) and multiple iterations can be in
+ * progress at the same time.
+ * @example
+ */
+/**
+ * <PRE>
+ *
+ * int sum_values(apr_pool_t *p, apr_hash_t *ht)
+ * {
+ * apr_hash_index_t *hi;
+* apr_hash_index_t *hi1;
+ * void *val;
+ * int sum = 0;
+ * hi1 = apr_hash_alloc_iterator (p, ht) ;
+ * for (hi = apr_hash_first_iterator(hi1, ht); hi; hi = apr_hash_next(hi))
{
+ * apr_hash_this(hi, NULL, NULL, &val);
+ * sum += *(int *)val;
+ * }
+ * return sum;
+ * }
+ * </PRE>
+ */
+APR_DECLARE(apr_hash_index_t *) apr_hash_first_iterator (apr_hash_index_t *hi,
apr_hash_t *ht) ;
/**
* Continue iterating over the entries in a hash table.
Index: apr/tables/apr_hash.c
===================================================================
RCS file: /home/cvspublic/apr/tables/apr_hash.c,v
retrieving revision 1.35
diff -u -r1.35 apr_hash.c
--- apr/tables/apr_hash.c 13 Jan 2003 18:52:07 -0000 1.35
+++ apr/tables/apr_hash.c 29 Apr 2003 09:40:38 -0000
@@ -158,6 +158,23 @@
return hi;
}
+APR_DECLARE(apr_hash_index_t *) apr_hash_alloc_iterator (apr_pool_t *p,
apr_hash_t *ht)
+{
+ if (p)
+ return (apr_palloc(p, sizeof(apr_hash_index_t)));
+ else
+ return (&ht->iterator);
+}
+
+APR_DECLARE(apr_hash_index_t *) apr_hash_first_iterator (apr_hash_index_t *hi,
apr_hash_t *ht)
+{
+ hi->ht = ht;
+ hi->index = 0;
+ hi->this = NULL;
+ hi->next = NULL;
+ return apr_hash_next(hi);
+}
+
APR_DECLARE(apr_hash_index_t *) apr_hash_first(apr_pool_t *p, apr_hash_t *ht)
{
apr_hash_index_t *hi;
Index: apr/test/testhash.c
===================================================================
RCS file: /home/cvspublic/apr/test/testhash.c,v
retrieving revision 1.6
diff -u -r1.6 testhash.c
--- apr/test/testhash.c 1 Jan 2003 00:01:56 -0000 1.6
+++ apr/test/testhash.c 29 Apr 2003 09:40:39 -0000
@@ -68,7 +68,8 @@
str[0] = '\0';
- for (hi = apr_hash_first(p, h); hi; hi = apr_hash_next(hi)) {
+ hi = apr_hash_alloc_iterator (p, h);
+ for (hi = apr_hash_first_iterator(hi, h); hi; hi = apr_hash_next(hi)) {
apr_hash_this(hi,(void*) &key, &len, (void*) &val);
apr_snprintf(str, 8196, "%sKey %s (%" APR_SSIZE_T_FMT ") Value %s\n",
str, key, len, val);
@@ -86,7 +87,8 @@
*keySum = 0;
*valSum = 0;
*pcount = 0;
- for (hi = apr_hash_first(p, h); hi; hi = apr_hash_next(hi)) {
+ hi = apr_hash_alloc_iterator (p, h);
+ for (hi = apr_hash_first_iterator(hi, h); hi; hi = apr_hash_next(hi)) {
apr_hash_this(hi, (void*)&key, NULL, &val);
*valSum += *(int *)val;
*keySum += *(int *)key;