Ok..
the revised patch.(and test prog)

Index: include/apr_hash.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_hash.h,v
retrieving revision 1.25
diff -u -b -r1.25 apr_hash.h
--- include/apr_hash.h  2001/05/16 05:30:51 1.25
+++ include/apr_hash.h  2001/07/17 22:39:15
@@ -181,6 +181,18 @@
  */
 APR_DECLARE(int) apr_hash_count(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: tables/apr_hash.c
===================================================================
RCS file: /home/cvspublic/apr/tables/apr_hash.c,v
retrieving revision 1.19
diff -u -b -r1.19 apr_hash.c
--- tables/apr_hash.c 2001/05/16 05:30:52 1.19
+++ tables/apr_hash.c 2001/07/17 22:39:18
@@ -325,3 +325,54 @@
{
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=base->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(base); 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(overlay); hi; hi = apr_hash_next(hi)) {
+ apr_hash_set(res,hi->this->key,hi->this->klen, hi->this->val);
+ }
+ return res;
+}


Index: test/Makefile.in
===================================================================
RCS file: /home/cvspublic/apr/test/Makefile.in,v
retrieving revision 1.59
diff -u -b -r1.59 Makefile.in
--- test/Makefile.in  2001/07/07 13:03:46 1.59
+++ test/Makefile.in  2001/07/17 22:39:18
@@ -24,6 +24,7 @@
         [EMAIL PROTECTED]@ \
         [EMAIL PROTECTED]@ \
         [EMAIL PROTECTED]@ \
+        [EMAIL PROTECTED]@ \
  [EMAIL PROTECTED]@ \
         [EMAIL PROTECTED]@

@@ -122,6 +123,9 @@

 [EMAIL PROTECTED]@: testmem.lo $(LOCAL_LIBS)
  $(LINK) testmem.lo $(LOCAL_LIBS) $(ALL_LIBS)
+
[EMAIL PROTECTED]@: testhash.lo $(LOCAL_LIBS)
+ $(LINK) testhash.lo $(LOCAL_LIBS) $(ALL_LIBS)

 [EMAIL PROTECTED]@: teststr.lo $(LOCAL_LIBS)
  $(LINK) teststr.lo $(LOCAL_LIBS) $(ALL_LIBS)

+
+
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#include "apr.h"
#include "apr_strings.h"
#include "apr_general.h"
#include "apr_pools.h"
#include "apr_hash.h"
#if APR_HAVE_STDIO_H
#include <stdio.h>
#endif
#if APR_HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if APR_HAVE_STRING_H
#include <string.h>
#endif

static void dump_hash( apr_hash_t *h) 
{
        apr_hash_index_t *hi;
        char* val;
        char* key;
        int len;
        int i=0;

        for (hi = apr_hash_first(h); hi; hi = apr_hash_next(hi)) {
                apr_hash_this(hi,(void*) &key, &len,(void*) &val);
                fprintf(stdout, "Key %s (%d) Value %s\n",key,len,val);
                i++;
        }
        if ( i != apr_hash_count(h)) 
        {
                fprintf(stderr, "ERROR: #entries (%d) does not match count 
(%d)\n",i,apr_hash_count(h));
        }
        else 
        {
                fprintf( stdout, "#entries %d \n",i);
        }

}

static void sum_hash( apr_hash_t *h, int*pcount,int*keySum, int*valSum) 
{
        apr_hash_index_t *hi;
        void*val;
        void*key;
        int count=0;

        *keySum=0;
        *valSum=0;
        *pcount=0;
        for (hi = apr_hash_first(h); hi; hi = apr_hash_next(hi)) {
                apr_hash_this(hi, &key, NULL, &val);
                *valSum += *(int *)val;
                *keySum += *(int *)key;
                count++;
        }
        *pcount=count;
}
int main(int argc, const char *const argv[])
{
        apr_pool_t*cntxt;
        apr_hash_t *h;
        apr_hash_t *h2;
        apr_hash_t *h3;
        apr_hash_t *h4;

        int i;
        int j;
        int *val;
        int *key;
        char*result;

        int sumKeys,sumVal;
        int trySumKey,trySumVal;


    /* table defaults  */

    apr_initialize();
    atexit(apr_terminate);
    apr_pool_create(&cntxt, NULL);

        h =apr_hash_make(cntxt);
    if ( h == NULL )  {
        fprintf(stderr, "ERROR: can not allocate HASH!\n");
        exit(-1);
    }

        apr_hash_set(h,"OVERWRITE",APR_HASH_KEY_STRING, "should not see this");
        apr_hash_set(h,"FOO3",APR_HASH_KEY_STRING, "bar3");
        apr_hash_set(h,"FOO3",APR_HASH_KEY_STRING, "bar3");
        apr_hash_set(h,"FOO1",APR_HASH_KEY_STRING, "bar1");
        apr_hash_set(h,"FOO2",APR_HASH_KEY_STRING, "bar2");
        apr_hash_set(h,"FOO4",APR_HASH_KEY_STRING, "bar4");
        apr_hash_set(h,"SAME1",APR_HASH_KEY_STRING, "same");
        apr_hash_set(h,"SAME2",APR_HASH_KEY_STRING, "same");
        apr_hash_set(h,"OVERWRITE",APR_HASH_KEY_STRING, "Overwrite key");

        
        
        result=apr_hash_get(h,"FOO2", APR_HASH_KEY_STRING);
        if (strcmp(result,"bar2"))
                fprintf(stderr,"ERROR:apr_hash_get FOO2 = %s (should be 
bar2)\n",result);

        result= apr_hash_get(h,"SAME2", APR_HASH_KEY_STRING);
        if (strcmp(result,"same"))
                fprintf(stderr,"ERROR:apr_hash_get SAME2 = %s (should be 
same)\n",result);

        
        result=apr_hash_get(h,"OVERWRITE", APR_HASH_KEY_STRING);
        if ( strcmp(result,"Overwrite key"))
                fprintf(stderr,"ERROR:apr_hash_get OVERWRITE = %s (should be 
'Overwrite key')\n",result);

        result=apr_hash_get(h,"NOTTHERE", APR_HASH_KEY_STRING);
        if (result)
                fprintf(stderr,"ERROR:apr_hash_get NOTTHERE = %s (should be 
NULL)\n",result);
        
        result=apr_hash_get(h,"FOO3", APR_HASH_KEY_STRING);
        if ( strcmp(result,"bar3"))
                fprintf(stderr,"ERROR:apr_hash_get FOO3 = %s (should be 
bar3)\n",result);
        

        dump_hash(h);

        h2 =apr_hash_make(cntxt);
        if ( h2 == NULL )  {
                fprintf(stderr, "ERROR: can not allocate HASH!\n");
                exit(-1);
        }
        sumKeys=0;
        sumVal=0;
        trySumKey=0;
        trySumVal=0;

        for (i=0;i<100;i++) {
                j=i*10+1;
                sumKeys+=j;
                sumVal+=i;
                key=apr_palloc(cntxt,sizeof(int));
                *key=j;
                val = apr_palloc(cntxt,sizeof(int));
                *val=i;
                apr_hash_set(h2,key,sizeof(int), val);
        }

        sum_hash( h2, &i, &trySumKey,&trySumVal );
        if (i==100) {
           fprintf(stdout,"All keys accounted for\n");
        } else {
           fprintf(stderr,"ERROR: Only got %d (out of 100)\n",i);
        }
        if ( trySumVal != sumVal ) {
           fprintf(stderr,"ERROR:Values don't add up Got %d expected 
%d\n",trySumVal ,sumVal);
        }
        if ( trySumKey != sumKeys ) {
           fprintf(stderr,"ERROR:Keys don't add up Got %d expected 
%d\n",trySumKey,sumKeys);
        }

        j=891;
        apr_hash_set(h2, &j,sizeof(int),NULL);
        
        if (apr_hash_get(h2,&j,sizeof(int))) {
          fprintf(stderr,"ERRROR: Delete not working\n");
        } else {
          fprintf(stdout,"Delete working\n");
        }
        sum_hash( h2, &i, &trySumKey,&trySumVal );

        sumKeys -=891;
        sumVal -=89;


        if ( i==99) {
           fprintf(stdout,"All keys accounted for.. Delete OK\n");
        } else {
           fprintf(stderr,"Only got %d (out of 99) Delete Not OK\n",i);
        }
        if ( trySumVal != sumVal ) {
           fprintf(stderr,"ERROR:Values don't add up Got %d expected 
%d\n",trySumVal ,sumVal);
        }
        if ( trySumKey != sumKeys ) {
           fprintf(stderr,"ERROR:Keys don't add up Got %d expected 
%d\n",trySumKey,sumKeys);
        }

        /* test overlay */
        h3 = apr_hash_make(cntxt);
        /* test with blank hash tables */
        h4 = apr_hash_overlay(cntxt, h3,h);
        
        if ( apr_hash_count(h4) != apr_hash_count(h)) {
                fprintf(stderr,"ERROR: overlay not working with blank overlay 
as overlay\n");
                dump_hash(h4);
        }

        h4 = apr_hash_overlay(cntxt, h,h3);
        if ( apr_hash_count(h4) != apr_hash_count(h)) {
                fprintf(stderr,"ERROR: overlay not working with blank overlay 
as base\n");
                dump_hash(h4);
        }

        h4 = apr_hash_overlay(cntxt, h,h2);
        if ( apr_hash_count(h4) != ( apr_hash_count(h) + apr_hash_count(h2)) )
                fprintf(stderr,"ERROR: overlay not working when overlaying 2 
unique hashs\n");

        h4 = apr_hash_overlay(cntxt, h,h);
        if ( apr_hash_count(h4) != apr_hash_count(h) )  {
                fprintf(stderr,"ERROR: overlay not working when overlaying same 
hash\n");       
                dump_hash(h4);
        }
        
        result=apr_hash_get(h4,"FOO2", APR_HASH_KEY_STRING);
        if (strcmp(result,"bar2"))
                fprintf(stderr,"ERROR:apr_hash_get FOO2 = %s (should be 
bar2)\n",result);

        result= apr_hash_get(h4,"SAME2", APR_HASH_KEY_STRING);
        if (strcmp(result,"same"))
                fprintf(stderr,"ERROR:apr_hash_get SAME2 = %s (should be 
same)\n",result);
        
        result=apr_hash_get(h4,"OVERWRITE", APR_HASH_KEY_STRING);
        if ( strcmp(result,"Overwrite key"))
                fprintf(stderr,"ERROR:apr_hash_get OVERWRITE = %s (should be 
'Overwrite key')\n",result);

        result=apr_hash_get(h4,"NOTTHERE", APR_HASH_KEY_STRING);
        if (result)
                fprintf(stderr,"ERROR:apr_hash_get NOTTHERE = %s (should be 
NULL)\n",result);
        
        result=apr_hash_get(h4,"FOO3", APR_HASH_KEY_STRING);
        if ( strcmp(result,"bar3"))
                fprintf(stderr,"ERROR:apr_hash_get FOO3 = %s (should be 
bar3)\n",result);

        apr_hash_set(h4, "FOO3",sizeof(int),NULL);              
        result=apr_hash_get(h4,"FOO3", APR_HASH_KEY_STRING);
        if ( result )
                fprintf(stderr,"ERROR:apr_hash_get FOO3 = %s (should be NULL, 
we just deleted it!)\n",result);

        return 0;
}

Reply via email to