Return-Path: Delivered-To: apmail-httpd-dev-archive@httpd.apache.org Received: (qmail 79594 invoked by uid 500); 11 Nov 2001 18:41:24 -0000 Mailing-List: contact dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list dev@httpd.apache.org Received: (qmail 79583 invoked from network); 11 Nov 2001 18:41:23 -0000 From: "Mladen Turk" To: Cc: Subject: RE: [PATCH] apr_table WAS: What to do about tables? Date: Sun, 11 Nov 2001 19:41:38 +0100 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0000_01C16AE8.E104CE30" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 In-Reply-To: <3BEBF5C0.3090408@pacbell.net> Importance: Normal X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - ns.promo-grupa.com X-AntiAbuse: Original Domain - httpd.apache.org X-AntiAbuse: Originator/Caller UID/GID - [0 0] / [0 0] X-AntiAbuse: Sender Address Domain - mappingsoft.com X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N This is a multi-part message in MIME format. ------=_NextPart_000_0000_01C16AE8.E104CE30 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit > -----Original Message----- > From: Brian Pane [mailto:bpane@pacbell.net] > Sent: Friday, November 09, 2001 4:27 PM > To: dev@httpd.apache.org > Subject: Re: [PATCH] apr_table WAS: What to do about tables? > > Here's the distribution of CPU time to these functions in a recent CVS > snapshot of 2.0: > > apr_table_set/apr_table_setn: 3.0% of usr CPU > apr_table_get: 2.0% > apr_table_add: 0.24% > > Based on these numbers, if you double the cost of apr_table_set and > reduce the cost of apr_table_get by a factor of 120, the httpd overall > will get *slower*. > > If you can improve the performance of updates in your implementation, > though, then the table-with-index approach would be a big win. I'm posting the new table indexing schema that doesn't require reindexing on table_set when duplicate keys found, or when resizing table. The table implementation is named apr_stable, just to be able to compare with original. I've focused on add/set/get so these are only implemented for now. I'm sending two test programs, one for apr_table, and other for the new one. Here are the results of benchmarks (useconds) old new seq add 50.072 60.087 seq set 22.782.760 60.086 seq get 370.533 10.015 rnd add 40.058 40.057 rnd set 28.370.795 3.655.256 rnd get 26.628.289 40.058 But... It would be nice to benchmark those using some real data. Do I have some +1 to continue working on that? MT. ------=_NextPart_000_0000_01C16AE8.E104CE30 Content-Type: application/octet-stream; name="apr_stable.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="apr_stable.c" /* = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= * The Apache Software License, Version 1.1=0A= *=0A= * Copyright (c) 2000-2001 The Apache Software Foundation. All rights=0A= * reserved.=0A= *=0A= * Redistribution and use in source and binary forms, with or without=0A= * modification, are permitted provided that the following conditions=0A= * are met:=0A= *=0A= * 1. Redistributions of source code must retain the above copyright=0A= * notice, this list of conditions and the following disclaimer.=0A= *=0A= * 2. Redistributions in binary form must reproduce the above copyright=0A= * notice, this list of conditions and the following disclaimer in=0A= * the documentation and/or other materials provided with the=0A= * distribution.=0A= *=0A= * 3. The end-user documentation included with the redistribution,=0A= * if any, must include the following acknowledgment:=0A= * "This product includes software developed by the=0A= * Apache Software Foundation (http://www.apache.org/)."=0A= * Alternately, this acknowledgment may appear in the software itself,=0A= * if and wherever such third-party acknowledgments normally appear.=0A= *=0A= * 4. The names "Apache" and "Apache Software Foundation" must=0A= * not be used to endorse or promote products derived from this=0A= * software without prior written permission. For written=0A= * permission, please contact apache@apache.org.=0A= *=0A= * 5. Products derived from this software may not be called "Apache",=0A= * nor may "Apache" appear in their name, without prior written=0A= * permission of the Apache Software Foundation.=0A= *=0A= * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED=0A= * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES=0A= * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE=0A= * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR=0A= * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,=0A= * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT=0A= * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF=0A= * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND=0A= * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,=0A= * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT=0A= * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF=0A= * SUCH DAMAGE.=0A= * = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= *=0A= * This software consists of voluntary contributions made by many=0A= * individuals on behalf of the Apache Software Foundation. For more=0A= * information on the Apache Software Foundation, please see=0A= * .=0A= */=0A= =0A= /*=0A= * Resource allocation code... the code here is responsible for making=0A= * sure that nothing leaks.=0A= *=0A= * rst --- 4/95 --- 6/95=0A= */=0A= =0A= #include "apr_private.h"=0A= =0A= #include "apr_general.h"=0A= #include "apr_pools.h"=0A= #include "apr_stable.h"=0A= #include "apr_strings.h"=0A= #include "apr_lib.h"=0A= #if APR_HAVE_STDLIB_H=0A= #include =0A= #endif=0A= #ifdef HAVE_MALLOC_H=0A= #include =0A= #endif=0A= #if APR_HAVE_STRING_H=0A= #include =0A= #endif=0A= #if APR_HAVE_STRINGS_H=0A= #include =0A= #endif=0A= =0A= #define INITIAL_MIN 31=0A= =0A= struct apr_stable_bucket_t {=0A= /** The next bucket in bucket list*/=0A= apr_stable_bucket_t *next; =0A= /** The previous bucket in bucket list */=0A= apr_stable_bucket_t *prev;=0A= /** The current table entry pointer */=0A= apr_stable_entry_t *elt;=0A= /** The hash bucket value */=0A= int hash;=0A= };=0A= =0A= =0A= /** The opaque string-content table type */=0A= struct apr_stable_index_t {=0A= /** The table of hash buckets */=0A= apr_stable_bucket_t **buckets;=0A= /** The number of hash buckets */ =0A= int size;=0A= /** The allocated number of hash buckets */ =0A= int count;=0A= };=0A= =0A= =0A= =0A= =0A= APR_DECLARE(apr_stable_t *) apr_stable_make(apr_pool_t *p, int nelts)=0A= {=0A= apr_stable_t *t =3D apr_palloc(p, sizeof(apr_stable_t));=0A= if (nelts < 1)=0A= nelts =3D 1;=0A= t->a.elts =3D apr_pcalloc(p, nelts * sizeof(apr_stable_entry_t));=0A= t->a.pool =3D p;=0A= t->a.elt_size =3D sizeof(apr_stable_entry_t);=0A= t->a.nelts =3D 0;=0A= t->a.nalloc =3D nelts;=0A= t->i =3D apr_pcalloc(p, sizeof(apr_stable_index_t));=0A= if (nelts < INITIAL_MIN)=0A= nelts =3D INITIAL_MIN;=0A= t->i->buckets =3D apr_pcalloc(p, (nelts + 1) * = sizeof(apr_stable_bucket_t *));=0A= t->i->size =3D nelts;=0A= t->i->count =3D 0;=0A= return t;=0A= }=0A= =0A= =0A= APR_DECLARE(void) apr_stable_clear(apr_stable_t *t)=0A= {=0A= memset(*t->i->buckets, 0, t->i->size * sizeof(apr_stable_bucket_t = *));=0A= t->a.nelts =3D 0;=0A= }=0A= =0A= APR_DECLARE(apr_stable_entry_t *) apr_stable_elts(apr_stable_t *t)=0A= {=0A= return (apr_stable_entry_t *)t->a.elts;=0A= }=0A= =0A= APR_DECLARE(int) apr_stable_count(apr_stable_t *t)=0A= {=0A= return t->a.nelts;=0A= }=0A= =0A= static int hash2(const char *key)=0A= {=0A= int hash;=0A= for (hash =3D 0; *key; key++)=0A= hash =3D hash * 33 + toupper(*key);=0A= return hash;=0A= }=0A= =0A= static void expand_index(apr_stable_t *t)=0A= {=0A= apr_stable_bucket_t **n_b;=0A= apr_stable_bucket_t *b;=0A= apr_stable_entry_t *e =3D (apr_stable_entry_t *) t->a.elts;=0A= int n_nalloc;=0A= int i, h;=0A= =0A= n_nalloc =3D t->i->size << 2 + 3;=0A= =0A= n_b =3D apr_pcalloc(t->a.pool, sizeof(apr_stable_bucket_t *) * = n_nalloc);=0A= for (i =3D 0; i < t->a.nelts; i++) {=0A= h =3D e[i].idx->hash & n_nalloc;=0A= b =3D apr_palloc(t->a.pool, sizeof(apr_stable_bucket_t)); =0A= b->next =3D n_b[h];=0A= b->prev =3D NULL;=0A= b->elt =3D &e[i];=0A= b->hash =3D e[i].idx->hash;=0A= b->elt =3D NULL;=0A= e[i].idx =3D b;=0A= if (n_b[h])=0A= n_b[h]->prev =3D b;=0A= n_b[h] =3D b;=0A= }=0A= t->i->size =3D n_nalloc;=0A= t->i->buckets =3D n_b;=0A= }=0A= =0A= static void expand_table(apr_stable_t *t)=0A= {=0A= int n_nalloc =3D (t->a.nalloc <=3D 0) ? 1 : t->a.nalloc * 2;=0A= char *new_data;=0A= apr_stable_entry_t *e;=0A= int i;=0A= =0A= new_data =3D apr_pcalloc(t->a.pool, sizeof(apr_stable_entry_t) * = n_nalloc);=0A= memcpy(new_data, t->a.elts, t->a.nalloc * = sizeof(apr_stable_entry_t));=0A= e =3D (apr_stable_entry_t *) new_data;=0A= /* fix the index pointers */=0A= for (i =3D 0; i < t->a.nelts; i++)=0A= e[i].idx->elt =3D &e[i];=0A= t->a.elts =3D new_data;=0A= t->a.nalloc =3D n_nalloc;=0A= }=0A= =0A= static apr_stable_entry_t *stable_push(apr_stable_t *t)=0A= {=0A= apr_stable_entry_t *e;=0A= if (t->a.nalloc =3D=3D t->a.nelts)=0A= expand_table(t);=0A= e =3D (apr_stable_entry_t *)(t->a.elts + t->a.nelts * = sizeof(apr_stable_entry_t));=0A= ++t->a.nelts;=0A= return e;=0A= }=0A= =0A= static apr_stable_bucket_t *lookup_bucket(const apr_stable_t *t, const = char *key)=0A= {=0A= apr_stable_bucket_t *b;=0A= int hash =3D hash2(key);=0A= =0A= for (b =3D t->i->buckets[hash & t->i->size]; b; b =3D b->next) {=0A= if (hash =3D=3D b->hash && b->elt && !strcasecmp(b->elt->key, = key))=0A= return b;=0A= } =0A= return NULL;=0A= }=0A= =0A= APR_DECLARE(const char *) apr_stable_get(const apr_stable_t *t, const = char *key)=0A= {=0A= =0A= apr_stable_bucket_t *b =3D lookup_bucket(t, key);=0A= return b ? b->elt->val : NULL;=0A= =0A= }=0A= =0A= static apr_stable_bucket_t *create_bucket(apr_stable_t *t, = apr_stable_entry_t *e)=0A= {=0A= apr_stable_bucket_t *b;=0A= int hash =3D hash2(e->key);=0A= =0A= b =3D apr_palloc(t->a.pool, sizeof(apr_stable_bucket_t));=0A= =0A= b->next =3D t->i->buckets[hash & t->i->size];=0A= b->prev =3D NULL;=0A= b->hash =3D hash;=0A= b->elt =3D e;=0A= if (t->i->buckets[hash & t->i->size])=0A= t->i->buckets[hash & t->i->size]->prev =3D b;=0A= t->i->buckets[hash & t->i->size] =3D b;=0A= ++t->i->count;=0A= return b;=0A= }=0A= =0A= APR_DECLARE(void) apr_stable_add(apr_stable_t *t, const char *key,=0A= const char *val)=0A= {=0A= apr_stable_entry_t *e;=0A= =0A= e =3D stable_push(t);=0A= e->key =3D apr_pstrdup(t->a.pool, key);=0A= e->val =3D apr_pstrdup(t->a.pool, val);=0A= e->idx =3D create_bucket(t, e);=0A= if (t->a.nelts > t->i->size * 4)=0A= expand_index(t); =0A= }=0A= =0A= APR_DECLARE(void) apr_stable_addn(apr_stable_t *t, const char *key,=0A= const char *val)=0A= {=0A= apr_stable_entry_t *e;=0A= =0A= e =3D stable_push(t);=0A= e->key =3D (char *) key;=0A= e->val =3D (char *) val;=0A= e->idx =3D create_bucket(t, e);=0A= if (t->a.nelts > t->i->size * 4)=0A= expand_index(t); =0A= }=0A= =0A= static apr_stable_bucket_t *lookup_dups(apr_stable_t *t, const char = *key, int *dups)=0A= {=0A= =0A= apr_stable_bucket_t *b, *f =3D NULL;=0A= int hash =3D hash2(key);=0A= =0A= for (b =3D t->i->buckets[hash & t->i->size]; b; b =3D b->next) {=0A= if (hash =3D=3D b->hash && b->elt && !strcasecmp(b->elt->key, = key)) {=0A= if (!f)=0A= f =3D b;=0A= else {=0A= b->elt->key =3D NULL;=0A= ++*dups;=0A= }=0A= }=0A= } =0A= return f;=0A= =0A= }=0A= =0A= static int lookup_del(apr_stable_t *t, const char *key)=0A= {=0A= apr_stable_bucket_t *b;=0A= int hash =3D hash2(key);=0A= int count =3D 0;=0A= =0A= for (b =3D t->i->buckets[hash & t->i->size]; b; b =3D b->next) {=0A= b->elt->key =3D NULL;=0A= ++count;=0A= }=0A= =0A= return count;=0A= }=0A= =0A= APR_DECLARE(void) apr_stable_set(apr_stable_t *t, const char *key,=0A= const char *val)=0A= {=0A= apr_stable_bucket_t *b;=0A= apr_stable_entry_t *e;=0A= int dups =3D 0;=0A= =0A= b =3D lookup_dups(t, key, &dups);=0A= if (!b) {=0A= e =3D stable_push(t);=0A= e->key =3D apr_pstrdup(t->a.pool, key);=0A= e->val =3D apr_pstrdup(t->a.pool, val);=0A= e->idx =3D create_bucket(t, e);=0A= if (t->a.nelts > t->i->size * 4)=0A= expand_index(t);=0A= }=0A= else {=0A= if (dups) {=0A= register int i, j, k;=0A= int done;=0A= e =3D (apr_stable_entry_t *) t->a.elts;=0A= =0A= for (i =3D 0; i < t->a.nelts; ) {=0A= done =3D 0;=0A= if (e[i].key =3D=3D NULL) {=0A= if (!done) {=0A= if (e[i].idx->prev)=0A= e[i].idx->prev->next =3D e[i].idx->next;=0A= else=0A= t->i->buckets[e[i].idx->hash & t->i->size] = =3D e[i].idx->next;=0A= if (e[i].idx->next)=0A= e[i].idx->next->prev =3D e[i].idx->prev; = =0A= --t->i->count;=0A= done =3D 1;=0A= }=0A= for (j =3D i, k =3D i + 1; k < t->a.nelts; ++j, ++k) = {=0A= e[j].key =3D e[k].key;=0A= e[j].val =3D e[k].val;=0A= e[j].idx =3D e[k].idx;=0A= e[k].idx->elt =3D &e[j];=0A= }=0A= --t->a.nelts;=0A= }=0A= else=0A= ++i;=0A= =0A= }=0A= }=0A= b->elt->val =3D apr_pstrdup(t->a.pool, val);=0A= }=0A= }=0A= =0A= APR_DECLARE(void) apr_stable_setn(apr_stable_t *t, const char *key,=0A= const char *val)=0A= {=0A= apr_stable_bucket_t *b;=0A= apr_stable_entry_t *e;=0A= int dups =3D 0;=0A= =0A= b =3D lookup_dups(t, key, &dups);=0A= if (!b) {=0A= e =3D stable_push(t);=0A= e->key =3D (char *) key;=0A= e->val =3D (char *) val;=0A= e->idx =3D create_bucket(t, e);=0A= if (t->a.nelts > t->i->size * 4)=0A= expand_index(t);=0A= }=0A= else {=0A= if (dups) {=0A= register int i, j, k;=0A= int done;=0A= e =3D (apr_stable_entry_t *) t->a.elts;=0A= =0A= for (i =3D 0; i < t->a.nelts; ) {=0A= done =3D 0;=0A= if (e[i].key =3D=3D NULL) {=0A= if (!done) {=0A= if (e[i].idx->prev)=0A= e[i].idx->prev->next =3D e[i].idx->next;=0A= else=0A= t->i->buckets[e[i].idx->hash & t->i->size] = =3D e[i].idx->next;=0A= if (e[i].idx->next)=0A= e[i].idx->next->prev =3D e[i].idx->prev; = =0A= --t->i->count;=0A= done =3D 1;=0A= }=0A= for (j =3D i, k =3D i + 1; k < t->a.nelts; ++j, ++k) = {=0A= e[j].key =3D e[k].key;=0A= e[j].val =3D e[k].val;=0A= e[j].idx =3D e[k].idx;=0A= e[k].idx->elt =3D &e[j];=0A= }=0A= --t->a.nelts;=0A= }=0A= else=0A= ++i;=0A= =0A= }=0A= }=0A= b->elt->val =3D (char *) val;=0A= }=0A= }=0A= =0A= APR_DECLARE(void) apr_stable_unset(apr_stable_t *t, const char *key)=0A= {=0A= apr_stable_bucket_t *b;=0A= apr_stable_entry_t *e;=0A= =0A= int hash =3D hash2(key);=0A= int found =3D 0;=0A= =0A= for (b =3D t->i->buckets[hash & t->i->size]; b; b =3D b->next) {=0A= b->elt->key =3D NULL;=0A= ++found;=0A= }=0A= =0A= if (found) {=0A= register int i, j, k;=0A= int done;=0A= e =3D (apr_stable_entry_t *) t->a.elts;=0A= =0A= for (i =3D 0; i < t->a.nelts; ) {=0A= done =3D 0;=0A= if (e[i].key =3D=3D NULL) {=0A= if (!done) {=0A= if (e[i].idx->prev)=0A= e[i].idx->prev->next =3D e[i].idx->next;=0A= else=0A= t->i->buckets[e[i].idx->hash & t->i->size] =3D = e[i].idx->next;=0A= if (e[i].idx->next)=0A= e[i].idx->next->prev =3D e[i].idx->prev; = =0A= --t->i->count;=0A= done =3D 1;=0A= }=0A= for (j =3D i, k =3D i + 1; k < t->a.nelts; ++j, ++k) {=0A= e[j].key =3D e[k].key;=0A= e[j].val =3D e[k].val;=0A= e[j].idx =3D e[k].idx;=0A= e[k].idx->elt =3D &e[j];=0A= }=0A= --t->a.nelts;=0A= }=0A= else=0A= ++i;=0A= }=0A= }=0A= }=0A= =0A= ------=_NextPart_000_0000_01C16AE8.E104CE30 Content-Type: application/octet-stream; name="apr_stable.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="apr_stable.h" /* = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= * The Apache Software License, Version 1.1=0A= *=0A= * Copyright (c) 2000-2001 The Apache Software Foundation. All rights=0A= * reserved.=0A= *=0A= * Redistribution and use in source and binary forms, with or without=0A= * modification, are permitted provided that the following conditions=0A= * are met:=0A= *=0A= * 1. Redistributions of source code must retain the above copyright=0A= * notice, this list of conditions and the following disclaimer.=0A= *=0A= * 2. Redistributions in binary form must reproduce the above copyright=0A= * notice, this list of conditions and the following disclaimer in=0A= * the documentation and/or other materials provided with the=0A= * distribution.=0A= *=0A= * 3. The end-user documentation included with the redistribution,=0A= * if any, must include the following acknowledgment:=0A= * "This product includes software developed by the=0A= * Apache Software Foundation (http://www.apache.org/)."=0A= * Alternately, this acknowledgment may appear in the software itself,=0A= * if and wherever such third-party acknowledgments normally appear.=0A= *=0A= * 4. The names "Apache" and "Apache Software Foundation" must=0A= * not be used to endorse or promote products derived from this=0A= * software without prior written permission. For written=0A= * permission, please contact apache@apache.org.=0A= *=0A= * 5. Products derived from this software may not be called "Apache",=0A= * nor may "Apache" appear in their name, without prior written=0A= * permission of the Apache Software Foundation.=0A= *=0A= * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED=0A= * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES=0A= * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE=0A= * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR=0A= * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,=0A= * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT=0A= * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF=0A= * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND=0A= * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,=0A= * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT=0A= * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF=0A= * SUCH DAMAGE.=0A= * = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= *=0A= * This software consists of voluntary contributions made by many=0A= * individuals on behalf of the Apache Software Foundation. For more=0A= * information on the Apache Software Foundation, please see=0A= * .=0A= */=0A= =0A= #ifndef APR_STABLE_H=0A= #define APR_STABLE_H=0A= =0A= #include "apr.h"=0A= #include "apr_pools.h"=0A= =0A= #if APR_HAVE_STDARG_H=0A= #include /* for va_list */=0A= #endif=0A= =0A= #ifdef __cplusplus=0A= extern "C" {=0A= #endif /* __cplusplus */=0A= =0A= /*=0A= * Define the structures used by the APR general-purpose library.=0A= */=0A= =0A= /**=0A= * @file apr_tables.h=0A= * @brief APR Table library=0A= */=0A= /**=0A= * @defgroup APR_Table Table routines=0A= * @ingroup APR=0A= *=0A= * Memory allocation stuff, like pools, arrays, and tables. Pools=0A= * and tables are opaque structures to applications, but arrays are=0A= * published.=0A= * @{=0A= */=0A= =0A= typedef struct apr_stable_bucket_t apr_stable_bucket_t;=0A= =0A= /** the table abstract data type */=0A= typedef struct apr_stable_t apr_stable_t;=0A= =0A= /** the table abstract index structure */=0A= typedef struct apr_stable_index_t apr_stable_index_t;=0A= =0A= /** An opaque array type */=0A= typedef struct apr_sarray_header_t apr_sarray_header_t;=0A= =0A= /**=0A= * The (opaque) structure for string-content tables.=0A= */=0A= typedef struct apr_stable_entry_t apr_stable_entry_t;=0A= =0A= /** The type for each entry in a string-content table */=0A= struct apr_stable_entry_t {=0A= /** The key for the current table entry */=0A= char *key; /* maybe NULL in future;=0A= * check when iterating thru table_elts=0A= */=0A= /** The value for the current table entry */=0A= char *val;=0A= =0A= /** The index for the current table entry */=0A= apr_stable_bucket_t *idx;=0A= };=0A= =0A= struct apr_sarray_header_t {=0A= /** The pool the array is allocated out of */=0A= apr_pool_t *pool;=0A= /** The amount of memory allocated for each element of the array */=0A= int elt_size;=0A= /** The number of active elements in the array */=0A= int nelts;=0A= /** The number of elements allocated in the array */=0A= int nalloc;=0A= /** The elements in the array */=0A= char *elts;=0A= };=0A= =0A= =0A= /** The opaque string-content table type */=0A= struct apr_stable_t {=0A= /* This has to be first to promote backwards compatibility with=0A= * older modules which cast a apr_table_t * to an apr_array_header_t = *...=0A= * they should use the table_elts() function for most of the=0A= * cases they do this for.=0A= */=0A= /** The underlying array for the table */=0A= apr_sarray_header_t a;=0A= #ifdef MAKE_TABLE_PROFILE=0A= /** Who created the array. */=0A= void *creator;=0A= #endif=0A= /** The underlying index for the table */=0A= apr_stable_index_t *i;=0A= };=0A= =0A= /**=0A= * Get the number of elements from a table=0A= * @param t The table=0A= * @return Number of elements in the table=0A= */=0A= =0A= APR_DECLARE(int) apr_stable_count(apr_stable_t *t);=0A= =0A= /**=0A= * Get the elements from a table=0A= * @param t The table=0A= * @return An array containing the contents of the table=0A= */=0A= =0A= APR_DECLARE(apr_stable_entry_t *) apr_stable_elts(apr_stable_t *t);=0A= /**=0A= * Make a new table=0A= * @param p The pool to allocate the pool out of=0A= * @param nelts The number of elements in the initial table.=0A= * @return The new table.=0A= * @warning This table can only store text data=0A= */=0A= APR_DECLARE(apr_stable_t *) apr_stable_make(apr_pool_t *p, int nelts);=0A= =0A= /**=0A= * Delete all of the elements from a table=0A= * @param t The table to clear=0A= */=0A= APR_DECLARE(void) apr_stable_clear(apr_stable_t *t);=0A= =0A= /**=0A= * Get the value associated with a given key from the table. After this = call,=0A= * The data is still in the table=0A= * @param t The table to search for the key=0A= * @param key The key to search for=0A= * @return The value associated with the key=0A= */=0A= APR_DECLARE(const char *) apr_stable_get(const apr_stable_t *t, const = char *key);=0A= =0A= /**=0A= * Add a key/value pair to a table, if another element already exists = with the=0A= * same key, this will over-write the old data.=0A= * @param t The table to add the data to.=0A= * @param key The key fo use=0A= * @param val The value to add=0A= * @remark When adding data, this function makes a copy of both the key = and the=0A= * value.=0A= */=0A= APR_DECLARE(void) apr_stable_set(apr_stable_t *t, const char *key,=0A= const char *val);=0A= =0A= /**=0A= * Add a key/value pair to a table, if another element already exists = with the=0A= * same key, this will over-write the old data.=0A= * @param t The table to add the data to.=0A= * @param key The key fo use=0A= * @param val The value to add=0A= * @warning When adding data, this function does not make a copy of the = key or =0A= * the value, so care should be taken to ensure that the values = will =0A= * not change after they have been added..=0A= */=0A= APR_DECLARE(void) apr_stable_setn(apr_stable_t *t, const char *key,=0A= const char *val);=0A= =0A= /**=0A= * Remove data from the table=0A= * @param t The table to remove data from=0A= * @param key The key of the data being removed=0A= */=0A= APR_DECLARE(void) apr_stable_unset(apr_stable_t *t, const char *key);=0A= =0A= /**=0A= * Add data to a table, regardless of whether there is another element = with the=0A= * same key.=0A= * @param t The table to add to=0A= * @param key The key to use=0A= * @param val The value to add.=0A= * @remark When adding data, this function makes a copy of both the key = and the=0A= * value.=0A= */=0A= APR_DECLARE(void) apr_stable_add(apr_stable_t *t, const char *key,=0A= const char *val);=0A= =0A= =0A= /**=0A= * Add data to a table, regardless of whether there is another element = with the=0A= * same key.=0A= * @param t The table to add to=0A= * @param key The key to use=0A= * @param val The value to add.=0A= * @remark When adding data, this function does not make a copy of the = key or the=0A= * value, so care should be taken to ensure that the values will = not =0A= * change after they have been added..=0A= */=0A= APR_DECLARE(void) apr_stable_addn(apr_stable_t *t, const char *key,=0A= const char *val);=0A= =0A= /** @} */=0A= #ifdef __cplusplus=0A= }=0A= #endif=0A= =0A= #endif /* ! APR_ITABLE_H */=0A= ------=_NextPart_000_0000_01C16AE8.E104CE30 Content-Type: application/octet-stream; name="teststable.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="teststable.c" /* = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= * The Apache Software License, Version 1.1=0A= *=0A= * Copyright (c) 2000-2001 The Apache Software Foundation. All rights=0A= * reserved.=0A= *=0A= * Redistribution and use in source and binary forms, with or without=0A= * modification, are permitted provided that the following conditions=0A= * are met:=0A= *=0A= * 1. Redistributions of source code must retain the above copyright=0A= * notice, this list of conditions and the following disclaimer.=0A= *=0A= * 2. Redistributions in binary form must reproduce the above copyright=0A= * notice, this list of conditions and the following disclaimer in=0A= * the documentation and/or other materials provided with the=0A= * distribution.=0A= *=0A= * 3. The end-user documentation included with the redistribution,=0A= * if any, must include the following acknowledgment:=0A= * "This product includes software developed by the=0A= * Apache Software Foundation (http://www.apache.org/)."=0A= * Alternately, this acknowledgment may appear in the software itself,=0A= * if and wherever such third-party acknowledgments normally appear.=0A= *=0A= * 4. The names "Apache" and "Apache Software Foundation" must=0A= * not be used to endorse or promote products derived from this=0A= * software without prior written permission. For written=0A= * permission, please contact apache@apache.org.=0A= *=0A= * 5. Products derived from this software may not be called "Apache",=0A= * nor may "Apache" appear in their name, without prior written=0A= * permission of the Apache Software Foundation.=0A= *=0A= * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED=0A= * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES=0A= * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE=0A= * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR=0A= * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,=0A= * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT=0A= * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF=0A= * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND=0A= * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,=0A= * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT=0A= * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF=0A= * SUCH DAMAGE.=0A= * = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= *=0A= * This software consists of voluntary contributions made by many=0A= * individuals on behalf of the Apache Software Foundation. For more=0A= * information on the Apache Software Foundation, please see=0A= * .=0A= */=0A= =0A= #include "apr.h"=0A= #include "apr_strings.h"=0A= #include "apr_general.h"=0A= #include "apr_pools.h"=0A= #include "apr_tables.h"=0A= #include "apr_stable.h"=0A= #include "apr_time.h"=0A= =0A= #if APR_HAVE_STDIO_H=0A= #include =0A= #endif=0A= #if APR_HAVE_STDLIB_H=0A= #include =0A= #endif=0A= #if APR_HAVE_STRING_H=0A= #include =0A= #endif=0A= =0A= void do_validadd(apr_stable_t *t)=0A= {=0A= int i, j;=0A= char key[64];=0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (j =3D 0; j < 4; j++) {=0A= for (i =3D 0; i < 2000; i++) {=0A= sprintf(key, "KEY%02d", i);=0A= apr_stable_add(t, key, "SOME_VALUE ADD");=0A= }=0A= }=0A= e =3D apr_time_now();=0A= printf("valid apr_table_add finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= =0A= }=0A= =0A= void do_validset(apr_stable_t *t)=0A= {=0A= int i, j;=0A= char key[64];=0A= =0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (j =3D 0; j < 2000; j++) {=0A= for (i =3D 0; i < 4; i++) {=0A= sprintf(key, "KEY%02d", i);=0A= apr_stable_set(t, key, "SOME_VALUE SET");=0A= }=0A= }=0A= e =3D apr_time_now();=0A= printf("valid apr_table_set finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= }=0A= =0A= void do_validget(apr_stable_t *t)=0A= {=0A= int i;=0A= char key[64];=0A= =0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (i =3D 2000; i >=3D 0; --i) {=0A= sprintf(key, "KEY%02d", i);=0A= apr_stable_get(t, key);=0A= }=0A= e =3D apr_time_now();=0A= printf("valid apr_table_get finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= }=0A= =0A= void do_rndadd(apr_stable_t *t)=0A= {=0A= int i;=0A= char key[64];=0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (i =3D 0; i < 5000; i++) {=0A= sprintf(key, "KEY%02d", rand());=0A= apr_stable_add(t, key, "SOME_VALUE ADD");=0A= }=0A= e =3D apr_time_now();=0A= printf("random apr_table_add finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= =0A= }=0A= =0A= void do_rndset(apr_stable_t *t)=0A= {=0A= int i;=0A= char key[64];=0A= =0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (i =3D 0; i < 5000; i++) {=0A= sprintf(key, "KEY%02d", rand());=0A= apr_stable_set(t, key, "SOME_VALUE SET");=0A= }=0A= e =3D apr_time_now();=0A= printf("random apr_table_set finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= }=0A= =0A= void do_rndget(apr_stable_t *t)=0A= {=0A= int i;=0A= char key[64];=0A= =0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (i =3D 0; i < 5000; i++) {=0A= sprintf(key, "KEY%02d", rand());=0A= apr_stable_get(t, key);=0A= }=0A= e =3D apr_time_now();=0A= printf("random apr_table_get finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= }=0A= =0A= void do_dump(apr_stable_t *t)=0A= {=0A= int i;=0A= apr_stable_entry_t *elts =3D (apr_stable_entry_t *) t->a.elts;=0A= =0A= for (i =3D 0; i < t->a.nelts; i++) {=0A= printf("%02d %s\t\t%s\t%p\n", i, elts[i].key, elts[i].val, = elts[i].idx);=0A= }=0A= }=0A= =0A= void do_info(apr_stable_t *t)=0A= {=0A= apr_stable_entry_t *elts =3D (apr_stable_entry_t *) t->a.elts;=0A= =0A= printf("Total # entries %d\n", t->a.nelts);=0A= }=0A= =0A= int main(int argc, const char *const argv[])=0A= {=0A= apr_pool_t *cntxt;=0A= apr_stable_t *t;=0A= =0A= apr_initialize();=0A= atexit(apr_terminate);=0A= =0A= apr_pool_create(&cntxt, NULL);=0A= =0A= /* table defaults */=0A= t =3D apr_stable_make(cntxt, 0xFFFF);=0A= if (t =3D=3D NULL) {=0A= fprintf(stderr, "ERROR: can not allocate TABLE!\n");=0A= exit(-1);=0A= }=0A= srand((unsigned)time(NULL));=0A= do_validadd(t);=0A= do_validset(t);=0A= do_validget(t);=0A= do_rndadd(t);=0A= do_rndset(t);=0A= do_rndget(t);=0A= =0A= do_info(t);=0A= return 0;=0A= }=0A= ------=_NextPart_000_0000_01C16AE8.E104CE30 Content-Type: application/octet-stream; name="testtable.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="testtable.c" /* = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= * The Apache Software License, Version 1.1=0A= *=0A= * Copyright (c) 2000-2001 The Apache Software Foundation. All rights=0A= * reserved.=0A= *=0A= * Redistribution and use in source and binary forms, with or without=0A= * modification, are permitted provided that the following conditions=0A= * are met:=0A= *=0A= * 1. Redistributions of source code must retain the above copyright=0A= * notice, this list of conditions and the following disclaimer.=0A= *=0A= * 2. Redistributions in binary form must reproduce the above copyright=0A= * notice, this list of conditions and the following disclaimer in=0A= * the documentation and/or other materials provided with the=0A= * distribution.=0A= *=0A= * 3. The end-user documentation included with the redistribution,=0A= * if any, must include the following acknowledgment:=0A= * "This product includes software developed by the=0A= * Apache Software Foundation (http://www.apache.org/)."=0A= * Alternately, this acknowledgment may appear in the software itself,=0A= * if and wherever such third-party acknowledgments normally appear.=0A= *=0A= * 4. The names "Apache" and "Apache Software Foundation" must=0A= * not be used to endorse or promote products derived from this=0A= * software without prior written permission. For written=0A= * permission, please contact apache@apache.org.=0A= *=0A= * 5. Products derived from this software may not be called "Apache",=0A= * nor may "Apache" appear in their name, without prior written=0A= * permission of the Apache Software Foundation.=0A= *=0A= * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED=0A= * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES=0A= * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE=0A= * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR=0A= * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,=0A= * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT=0A= * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF=0A= * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND=0A= * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,=0A= * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT=0A= * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF=0A= * SUCH DAMAGE.=0A= * = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= *=0A= * This software consists of voluntary contributions made by many=0A= * individuals on behalf of the Apache Software Foundation. For more=0A= * information on the Apache Software Foundation, please see=0A= * .=0A= */=0A= =0A= #include "apr.h"=0A= #include "apr_strings.h"=0A= #include "apr_general.h"=0A= #include "apr_pools.h"=0A= #include "apr_tables.h"=0A= #include "apr_time.h"=0A= =0A= #if APR_HAVE_STDIO_H=0A= #include =0A= #endif=0A= #if APR_HAVE_STDLIB_H=0A= #include =0A= #endif=0A= #if APR_HAVE_STRING_H=0A= #include =0A= #endif=0A= =0A= void do_validadd(apr_table_t *t)=0A= {=0A= int i, j;=0A= char key[64];=0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (j =3D 0; j < 4; j++) {=0A= for (i =3D 0; i < 2000; i++) {=0A= sprintf(key, "KEY%02d", i);=0A= apr_table_add(t, key, "SOME_VALUE ADD");=0A= }=0A= }=0A= e =3D apr_time_now();=0A= printf("valid apr_table_add finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= =0A= }=0A= =0A= void do_validset(apr_table_t *t)=0A= {=0A= int i, j;=0A= char key[64];=0A= =0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (j =3D 0; j < 2000; j++) {=0A= for (i =3D 0; i < 4; i++) {=0A= sprintf(key, "KEY%02d", i);=0A= apr_table_set(t, key, "SOME_VALUE SET");=0A= }=0A= }=0A= e =3D apr_time_now();=0A= printf("valid apr_table_set finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= }=0A= =0A= void do_validget(apr_table_t *t)=0A= {=0A= int i;=0A= char key[64];=0A= =0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (i =3D 2000; i >=3D 0; --i) {=0A= sprintf(key, "KEY%02d", i);=0A= apr_table_get(t, key);=0A= }=0A= e =3D apr_time_now();=0A= printf("valid apr_table_get finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= }=0A= =0A= void do_rndadd(apr_table_t *t)=0A= {=0A= int i;=0A= char key[64];=0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (i =3D 0; i < 5000; i++) {=0A= sprintf(key, "KEY%02d", rand());=0A= apr_table_add(t, key, "SOME_VALUE ADD");=0A= }=0A= e =3D apr_time_now();=0A= printf("random apr_table_add finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= =0A= }=0A= =0A= void do_rndset(apr_table_t *t)=0A= {=0A= int i;=0A= char key[64];=0A= =0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (i =3D 0; i < 5000; i++) {=0A= sprintf(key, "KEY%02d", rand());=0A= apr_table_set(t, key, "SOME_VALUE SET");=0A= }=0A= e =3D apr_time_now();=0A= printf("random apr_table_set finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= }=0A= =0A= void do_rndget(apr_table_t *t)=0A= {=0A= int i;=0A= char key[64];=0A= =0A= apr_time_t s, e;=0A= =0A= s =3D apr_time_now();=0A= for (i =3D 0; i < 5000; i++) {=0A= sprintf(key, "KEY%02d", rand());=0A= apr_table_get(t, key);=0A= }=0A= e =3D apr_time_now();=0A= printf("random apr_table_get finished in %"APR_INT64_T_FMT"\n", e - = s);=0A= }=0A= =0A= void do_dump(apr_table_t *t)=0A= {=0A= int i;=0A= apr_table_entry_t *elts =3D (apr_table_entry_t *) t->a.elts;=0A= =0A= for (i =3D 0; i < t->a.nelts; i++) {=0A= printf("%02d %s\t\t%s\n", i, elts[i].key, elts[i].val);=0A= }=0A= }=0A= =0A= void do_info(apr_table_t *t)=0A= {=0A= apr_table_entry_t *elts =3D (apr_table_entry_t *) t->a.elts;=0A= =0A= printf("Total # entries %d\n", t->a.nelts);=0A= }=0A= =0A= int main(int argc, const char *const argv[])=0A= {=0A= apr_pool_t *cntxt;=0A= apr_table_t *t;=0A= =0A= apr_initialize();=0A= atexit(apr_terminate);=0A= =0A= apr_pool_create(&cntxt, NULL);=0A= =0A= /* table defaults */=0A= t =3D apr_table_make(cntxt, 0xFFFF);=0A= if (t =3D=3D NULL) {=0A= fprintf(stderr, "ERROR: can not allocate TABLE!\n");=0A= exit(-1);=0A= }=0A= srand((unsigned)time(NULL));=0A= do_validadd(t);=0A= do_validset(t);=0A= do_validget(t);=0A= do_rndadd(t);=0A= do_rndset(t);=0A= do_rndget(t);=0A= =0A= do_info(t);=0A= return 0;=0A= }=0A= ------=_NextPart_000_0000_01C16AE8.E104CE30--