apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joe Schaefer <joe+gm...@sunstarsys.com>
Subject Re: Frankentables
Date Sat, 10 May 2003 22:22:13 GMT
Joe Schaefer <joe+gmane@sunstarsys.com> 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);
 
 /** @} */
 


Mime
View raw message