Joe Schaefer <[EMAIL PROTECTED]> writes: [...]
> Has anyone given any thought to the changes I proposed > to the table implementation? Hmm, since the patch to apr_tables.c is pretty large, maybe I should start by posting the small patch to apr_tables.h and discuss that first. Here is a list of the changes: 1) use a native unsigned int for the key_checksum. This should allow 64 bit machines to use 8 chars for the table hash & key_offset instead of just 4. 2) superimpose a tree-node onto the table entry, with a next node to keep track of multivalued keys. These are implemented as ints (which represent offsets from t->a.elts) instead of raw pointers to memory addresses. This is necessary to allow the underlying array to realloc itself as new entries are added. 3) add some bitfields to the table_entry: key_offset- marks where the checksum leaves off so we don't have to start strcasecmp at the start of the string. color- tracks the color (red or black) of the entry. dead- marks the entry as dead. Dead entries are entries that were removed from the table, but haven't been "paved over" yet by shifting & reindexing the remaining (live) entries. Potential dead entries are expunged from the table by calling apr_table_elts(). 4) associate copy & merge functions with a table, which allows the values in the table to be treated more generally than just as ", "-combinable header strings. 5) apr_array_pstrcat would be more useful if it allowed the separator to be a string instead of just a single character. I added a new function that does this and called it apr_array_pstrjoin. 6) Add a new function called apr_table_cat. The apr_tables.h patch is below. Thanks in advance. -- Joe Schaefer Index: include/apr_tables.h =================================================================== RCS file: /home/cvspublic/apr/include/apr_tables.h,v retrieving revision 1.37 diff -u -r1.37 apr_tables.h --- include/apr_tables.h 5 Mar 2003 21:22:26 -0000 1.37 +++ include/apr_tables.h 10 May 2003 21:33:49 -0000 @@ -108,14 +108,20 @@ /** The type for each entry in a string-content table */ struct apr_table_entry_t { /** The key for the current table entry */ - char *key; /* maybe NULL in future; - * check when iterating thru table_elts - */ + const char *key; /* maybe NULL in future; + * check when iterating thru table_elts + */ /** The value for the current table entry */ - char *val; + const char *val; + /** indices of related entries: LEFT RIGHT UP NEXT */ + int tree[4]; /** A checksum for the key, for use by the apr_table internals */ - apr_uint32_t key_checksum; + unsigned int key_checksum; + unsigned int key_offset : 4; + + unsigned int color : 1; + unsigned int dead : 1; }; /** @@ -123,7 +129,7 @@ * @param t The table * @return An array containing the contents of the table */ -APR_DECLARE(const apr_array_header_t *) apr_table_elts(const apr_table_t *t); +APR_DECLARE(const apr_array_header_t *) apr_table_elts(apr_table_t *t); /** * Determine if the table is empty @@ -131,6 +137,8 @@ * @return True if empty, False otherwise */ APR_DECLARE(int) apr_is_empty_table(const apr_table_t *t); +#define apr_is_empty_table(t) ( apr_table_nelts(t) == 0 ) + /** * Determine if the array is empty @@ -222,6 +230,15 @@ APR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p, const apr_array_header_t *arr, const char sep); +/** + * Same as apr_array_pstrcat, but takes a (char *) as third argument. + * This allows the array elements to be joined on a string instead of + * a single character. + */ + +APR_DECLARE(char *)apr_array_pstrjoin(apr_pool_t *p, + const apr_array_header_t *arr, + const char *sep); /** * Make a new table @@ -242,6 +259,37 @@ const apr_table_t *t); /** + * Get/set method for the table's value copier. + * @param t Table. + * @param c The new t->copy callback. c = NULL is ignored; + * a non-NULL value replaces the table's internal copier. + * @return The original t->copy callback (prior to any assignment). + */ +typedef char *(apr_table_copier_t)(apr_pool_t *p, const char *val); + +APR_DECLARE(apr_table_copier_t *) apr_table_copier(apr_table_t *t, + apr_table_copier_t *c); + +/** + * Get/set method for the table's value merger. + * @param t Table. + * @param m The new t->merge callback. m = NULL is ignored; + * a non-NULL value replaces the table's internal merger. + * @return The original t->merge callback (prior to any assignment). + */ +typedef char *(apr_table_merger_t)(apr_pool_t *p, + const apr_array_header_t *a); + +APR_DECLARE(apr_table_merger_t *) apr_table_merger(apr_table_t *t, + apr_table_merger_t *m); + +/** + * Return the number of elements within the table. + * @param t The table + */ +APR_DECLARE(int) apr_table_nelts(const apr_table_t *t); + +/** * Delete all of the elements from a table * @param t The table to clear */ @@ -336,6 +384,24 @@ const char *val); /** + * Merges multivalued entries together, eliminating redunandant + * entries with t->merge. + * + * @param t Table. + */ +APR_DECLARE(apr_status_t)apr_table_normalize(apr_table_t *t); + +/** + * Append one table to the end of another. + * @param t The table to be modified. + * @param s The entries from this table are added to "t". + * @remark This function splices the internal trees from "s" + * into "t", so it will be faster than iterating over s with apr_table_addn. + * From a user's perspective, the result should be identical. + */ +APR_DECLARE(void) apr_table_cat(apr_table_t *t, const apr_table_t *s); + +/** * Merge two tables into one new table * @param p The pool to use for the new table * @param overlay The first table to put in the new table @@ -439,7 +505,7 @@ */ APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b, - unsigned flags); + unsigned flags); /** @} */