apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ian Holsman <i...@cnet.com>
Subject [Patch] Add apr_hash_overlay
Date Mon, 16 Jul 2001 02:34:36 GMT
This is the first part of allow notes 'tables' to become hash tables.
the patch adds a function to 'merge' two hash tables together, a test 
program for hash tables,
and a small fix to apr_hash_first (make the arg a const)

(I've attached the testhash.c, but am currently on Windows, so I didnt 
change the makefile.in file for this. )
..Ian

Index: apr_hash.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_hash.h,v
retrieving revision 1.25
diff -u -r1.25 apr_hash.h
--- apr_hash.h  2001/05/16 05:30:51     1.25
+++ apr_hash.h  2001/07/16 02:28:43
@@ -150,7 +150,7 @@
  * </PRE>
  * @deffunc apr_hash_index_t *apr_hash_first(apr_hash_t *ht)
  */
-APR_DECLARE(apr_hash_index_t *) apr_hash_first(apr_hash_t *ht);
+APR_DECLARE(apr_hash_index_t *) apr_hash_first(const apr_hash_t *ht);

 /**
  * Continue iterating over the entries in a hash table.
@@ -179,8 +179,20 @@
  * @return The number of key/value pairs in the hash table.
  * @deffunc int apr_hash_count(apr_hash_t *ht);
  */
-APR_DECLARE(int) apr_hash_count(apr_hash_t *ht);
+APR_DECLARE(int) apr_hash_count(const apr_hash_t *ht);

+/**
+ * Merge two hash tables into one new hash table. The values of the 
'base' tabl
e
+ * override the values of the overlay if both have the same key.
+ * @param p The pool to use for the new hash table
+ * @param overlay The first table to put in the new hash table
+ * @param base The table to add at the end of the new hash table
+ * @return A new hash table containing all of the data from the two 
passed in
+ * @deffunc apr_hash_t *apr_hash_overlay(apr_pool_t *p, const 
apr_table_t *over
lay, const apr_table_t *base);
+ */
+APR_DECLARE(apr_hash_t *) apr_hash_overlay(apr_pool_t *p,
+                                             const apr_hash_t *overlay,
+                                             const apr_hash_t *base);

 #ifdef __cplusplus
 }


Index: apr_hash.c
===================================================================
RCS file: /home/cvspublic/apr/tables/apr_hash.c,v
retrieving revision 1.19
diff -u -r1.19 apr_hash.c
--- apr_hash.c    2001/05/16 05:30:52    1.19
+++ apr_hash.c    2001/07/16 02:19:26
@@ -112,7 +112,7 @@
  * apr_hash_next().
  */
 struct apr_hash_index_t {
-    apr_hash_t           *ht;
+    const apr_hash_t           *ht;
     apr_hash_entry_t   *this, *next;
     int                 index;
 };
@@ -155,7 +155,7 @@
     return hi;
 }
 
-APR_DECLARE(apr_hash_index_t *) apr_hash_first(apr_hash_t *ht)
+APR_DECLARE(apr_hash_index_t *) apr_hash_first(const apr_hash_t *ht)
 {
     apr_hash_index_t *hi;
     hi = apr_palloc(ht->pool, sizeof(*hi));
@@ -321,7 +321,67 @@
     /* else key not present and val==NULL */
 }
 
-APR_DECLARE(int) apr_hash_count(apr_hash_t *ht)
+APR_DECLARE(int) apr_hash_count(const apr_hash_t *ht)
 {
     return ht->count;
+}
+
+APR_DECLARE(apr_hash_t*) apr_hash_overlay(apr_pool_t*p, const 
apr_hash_t *overlay, const apr_hash_t*base)
+{
+    apr_hash_t *res;
+    apr_hash_index_t *hi;
+    apr_hash_entry_t *new_vals;
+    int i,j;
+
+#ifdef POOL_DEBUG
+    /* we don't copy keys and values, so it's necessary that
+     * overlay->a.pool and base->a.pool have a life span at least
+     * as long as p
+     */
+    if (!apr_pool_is_ancestor(overlay->a.pool, p)) {
+    fprintf(stderr,    "apr_hash_overlay: overlay's pool is not an 
ancestor of p\n");
+    abort();
+    }
+    if (!apr_pool_is_ancestor(base->a.pool, p)) {
+    fprintf(stderr,    "apr_hash_overlay: base's pool is not an 
ancestor of p\n");
+    abort();
+    }
+#endif
+
+    res = apr_palloc(p, sizeof(apr_hash_t));
+    res->pool = p;
+    res->count=overlay->count;
+    res->max=  (overlay->max > base->max)? overlay->max: base->max;
+    res->array = alloc_array(res, res->max);
+    new_vals = apr_palloc(p, sizeof( apr_hash_entry_t)*res->count);
+    j=0;
+    for (hi = apr_hash_first(overlay); hi; hi = apr_hash_next(hi)) {
+        i = hi->this->hash & res->max;
+
+        new_vals[j].klen = hi->this->klen;
+        new_vals[j].key = hi->this->key;
+        new_vals[j].val = hi->this->val;
+        new_vals[j].hash = hi->this->hash;
+        new_vals[j].next = res->array[i];
+        res->array[i] = &new_vals[j];
+        j++;
+    }
+    /* can't simply copy the stuff over, need to set each one so as to
+       increment the counts/array properly
+    */
+    for (hi = apr_hash_first(base); hi; hi = apr_hash_next(hi)) {
+        apr_hash_set(res,hi->this->key,hi->this->klen, hi->this->val);
+    }
+    return res;  
 }



Mime
View raw message