]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add hashing to event header lookup
authorAnthony Minessale <anthony.minessale@gmail.com>
Mon, 3 Nov 2008 20:08:44 +0000 (20:08 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Mon, 3 Nov 2008 20:08:44 +0000 (20:08 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10227 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_apr.h
src/include/switch_event.h
src/include/switch_utils.h
src/switch_apr.c
src/switch_event.c

index 8e98893edae22ab703608b7198b9cc746884bd7d..75cc0a09c882dc144aaa6afaf9796e269a82306c 100644 (file)
@@ -202,6 +202,8 @@ SWITCH_DECLARE(switch_memory_pool_t *) switch_hash_pool_get(switch_hash_t *ht);
  */
 SWITCH_DECLARE(unsigned int) switch_hashfunc_default(const char *key, switch_ssize_t *klen);
 
+SWITCH_DECLARE(unsigned int) switch_ci_hashfunc_default(const char *char_key, switch_ssize_t *klen);
+
 
  /**
  * @defgroup switch_time Time Routines
index a94440d319e6194f79661fdf9ed3e6d1e3790206..07bfe1f93c71b52e6e740766513a4b114efd9d76 100644 (file)
@@ -67,6 +67,8 @@ SWITCH_BEGIN_EXTERN_C
        char *name;
        /*! the header value */
        char *value;
+       /*! hash of the header name */
+       unsigned long hash;
        struct switch_event_header *next;
 };
 
index 64841ec5c8ea91aa55ee30a32ea83c397a1622c2..32a553faa1768402bf69484c40c63f1024faf905 100644 (file)
@@ -295,6 +295,40 @@ static inline char *switch_safe_strdup(const char *it)
 }
 
 
+static inline char *switch_lc_strdup(const char *it) 
+{
+       char *dup;
+       char *p;
+
+       if (it) {
+               dup = strdup(it);
+               for(p = dup; p && *p; p++) {
+                       *p = tolower(*p);
+               }
+               return dup;
+       }
+
+       return NULL;
+}
+
+
+static inline char *switch_uc_strdup(const char *it) 
+{
+       char *dup;
+       char *p;
+
+       if (it) {
+               dup = strdup(it);
+               for(p = dup; p && *p; p++) {
+                       *p = toupper(*p);
+               }
+               return dup;
+       }
+
+       return NULL;
+}
+
+
 /*!
   \brief Test if one string is inside another with extra case checking
   \param s the inner string
index d46b8608d06ce094ccb4c812eaa5c56a98a8c425..f2c644779db03eebcd60f56e2705b5392cf3a910 100644 (file)
@@ -74,6 +74,30 @@ SWITCH_DECLARE(void) switch_pool_clear(switch_memory_pool_t *p)
        apr_pool_clear(p);
 }
 
+SWITCH_DECLARE(unsigned int) switch_ci_hashfunc_default(const char *char_key, switch_ssize_t *klen)
+                                                                                                               
+{
+    unsigned int hash = 0;
+    const unsigned char *key = (const unsigned char *)char_key;
+    const unsigned char *p;
+    apr_ssize_t i;
+    
+    if (*klen == APR_HASH_KEY_STRING) {
+        for (p = key; *p; p++) {
+            hash = hash * 33 + tolower(*p);
+        }
+        *klen = p - key;
+    }
+    else {
+        for (p = key, i = *klen; i; i--, p++) {
+            hash = hash * 33 + tolower(*p);
+        }
+    }
+
+    return hash;
+}
+
+
 SWITCH_DECLARE(unsigned int) switch_hashfunc_default(const char *key, switch_ssize_t *klen)
 {
        return apr_hashfunc_default(key, klen);
index c8b57e0741357afdbceb7b87768ffa48b8d71cf0..31e7d2e5a3b5bf480c3a1cdafc2d1fff2c6b2f5a 100644 (file)
@@ -586,12 +586,17 @@ SWITCH_DECLARE(switch_status_t) switch_event_set_priority(switch_event_t *event,
 SWITCH_DECLARE(char *) switch_event_get_header(switch_event_t *event, const char *header_name)
 {
        switch_event_header_t *hp;
+       switch_ssize_t hlen = -1;
+       unsigned long hash = 0;
+
        switch_assert(event);
-       if (!header_name)
-               return NULL;
 
+       if (!header_name) return NULL;
+       
+       hash = switch_ci_hashfunc_default(header_name, &hlen);
+       
        for (hp = event->headers; hp; hp = hp->next) {
-               if (!strcasecmp(hp->name, header_name)) {
+               if ((!hp->hash || hash == hp->hash) && !strcasecmp(hp->name, header_name) ) {
                        return hp->value;
                }
        }
@@ -608,6 +613,9 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header(switch_event_t *event, c
        switch_event_header_t *hp, *lp = NULL, *tp;
        switch_status_t status = SWITCH_STATUS_FALSE;
        int x = 0;
+       switch_ssize_t hlen = -1;
+       unsigned long hash = 0;
+
        tp = event->headers;
        while (tp) {
                hp = tp;
@@ -615,7 +623,9 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header(switch_event_t *event, c
                
                x++;
                switch_assert(x < 1000);
-               if (!strcasecmp(header_name, hp->name)) {
+               hash = switch_ci_hashfunc_default(header_name, &hlen);
+
+               if ((!hp->hash || hash == hp->hash) && !strcasecmp(header_name, hp->name)) {
                        if (lp) {
                                lp->next = hp->next;
                        } else {
@@ -642,6 +652,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header(switch_event_t *event, c
 switch_status_t switch_event_base_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, char *data)
 {
        switch_event_header_t *header;
+       switch_ssize_t hlen = -1;
        void *pop;
 
        if (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) {
@@ -655,7 +666,8 @@ switch_status_t switch_event_base_add_header(switch_event_t *event, switch_stack
 
        header->name = DUP(header_name);
        header->value = data;
-
+       header->hash = switch_ci_hashfunc_default(header->name, &hlen);
+       
        if (stack == SWITCH_STACK_TOP) {
                header->next = event->headers;
                event->headers = header;