Ignore:
Timestamp:
Jan 30, 2006 6:40:05 PM (18 years ago)
Author:
bennylp
Message:

Finished implementation of UA layer (to be tested)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/src/pj/hash.c

    r108 r127  
    2323#include <pj/os.h> 
    2424#include <pj/ctype.h> 
     25#include <pj/assert.h> 
    2526 
    2627/** 
     
    5859            hash = hash * PJ_HASH_MULTIPLIER + *p; 
    5960        } 
    60         keylen = p - (const unsigned char*)key; 
    6161    } else { 
    6262        const unsigned char *p = key, 
     
    8989    unsigned table_size; 
    9090     
     91    /* Check that PJ_HASH_ENTRY_SIZE is correct. */ 
     92    PJ_ASSERT_RETURN(sizeof(pj_hash_entry)==PJ_HASH_ENTRY_SIZE, NULL); 
     93 
    9194    h = pj_pool_alloc(pool, sizeof(pj_hash_table_t)); 
    9295    h->count = 0; 
     
    111114static pj_hash_entry **find_entry( pj_pool_t *pool, pj_hash_table_t *ht,  
    112115                                   const void *key, unsigned keylen, 
    113                                    void *val) 
     116                                   void *val, pj_uint32_t *hval, 
     117                                   void *entry_buf) 
    114118{ 
    115119    pj_uint32_t hash; 
    116120    pj_hash_entry **p_entry, *entry; 
    117121 
    118     hash=0; 
    119     if (keylen==PJ_HASH_KEY_STRING) { 
    120         const unsigned char *p = key; 
    121         for ( ; *p; ++p ) { 
    122             hash = hash * PJ_HASH_MULTIPLIER + *p; 
    123         } 
    124         keylen = p - (const unsigned char*)key; 
     122    if (hval && *hval != 0) { 
     123        hash = *hval; 
    125124    } else { 
    126         const unsigned char *p = key, 
    127                             *end = p + keylen; 
    128         for ( ; p!=end; ++p) { 
    129             hash = hash * PJ_HASH_MULTIPLIER + *p; 
    130         } 
     125        /* This slightly differs with pj_hash_calc() because we need  
     126         * to get the keylen when keylen is PJ_HASH_KEY_STRING. 
     127         */ 
     128        hash=0; 
     129        if (keylen==PJ_HASH_KEY_STRING) { 
     130            const unsigned char *p = key; 
     131            for ( ; *p; ++p ) { 
     132                hash = hash * PJ_HASH_MULTIPLIER + *p; 
     133            } 
     134            keylen = p - (const unsigned char*)key; 
     135        } else { 
     136            const unsigned char *p = key, 
     137                                *end = p + keylen; 
     138            for ( ; p!=end; ++p) { 
     139                hash = hash * PJ_HASH_MULTIPLIER + *p; 
     140            } 
     141        } 
     142 
     143        /* Report back the computed hash. */ 
     144        if (hval) 
     145            *hval = hash; 
    131146    } 
    132147 
     
    137152    { 
    138153        if (entry->hash==hash && entry->keylen==keylen && 
    139             memcmp(entry->key, key, keylen)==0)  
     154            pj_memcmp(entry->key, key, keylen)==0)  
    140155        { 
    141156            break;       
     
    146161        return p_entry; 
    147162 
    148     /* create a new entry */ 
    149     entry = pj_pool_alloc(pool, sizeof(pj_hash_entry)); 
    150     PJ_LOG(6, ("hashtbl", "%p: New p_entry %p created, pool used=%u, cap=%u", ht, entry,  
    151                           pj_pool_get_used_size(pool), pj_pool_get_capacity(pool))); 
     163    /* Entry not found, create a new one.  
     164     * If entry_buf is specified, use it. Otherwise allocate from pool. 
     165     */ 
     166    if (entry_buf) { 
     167        entry = entry_buf; 
     168    } else { 
     169        /* Pool must be specified! */ 
     170        PJ_ASSERT_RETURN(pool != NULL, NULL); 
     171 
     172        entry = pj_pool_alloc(pool, sizeof(pj_hash_entry)); 
     173        PJ_LOG(6, ("hashtbl",  
     174                   "%p: New p_entry %p created, pool used=%u, cap=%u",  
     175                   ht, entry,  pj_pool_get_used_size(pool),  
     176                   pj_pool_get_capacity(pool))); 
     177    } 
    152178    entry->next = NULL; 
    153179    entry->hash = hash; 
     
    163189 
    164190PJ_DEF(void *) pj_hash_get( pj_hash_table_t *ht, 
    165                             const void *key, unsigned keylen ) 
     191                            const void *key, unsigned keylen, 
     192                            pj_uint32_t *hval) 
    166193{ 
    167194    pj_hash_entry *entry; 
    168     entry = *find_entry( NULL, ht, key, keylen, NULL); 
     195 
     196    if (hval) *hval = 0; 
     197    entry = *find_entry( NULL, ht, key, keylen, NULL, hval, NULL); 
    169198    return entry ? entry->value : NULL; 
    170199} 
    171200 
    172201PJ_DEF(void) pj_hash_set( pj_pool_t *pool, pj_hash_table_t *ht, 
    173                           const void *key, unsigned keylen, 
     202                          const void *key, unsigned keylen, pj_uint32_t hval, 
    174203                          void *value ) 
    175204{ 
    176205    pj_hash_entry **p_entry; 
    177206 
    178     p_entry = find_entry( pool, ht, key, keylen, value ); 
     207    p_entry = find_entry( pool, ht, key, keylen, value, &hval, NULL); 
    179208    if (*p_entry) { 
    180209        if (value == NULL) { 
     
    187216            /* overwrite */ 
    188217            (*p_entry)->value = value; 
    189             PJ_LOG(6, ("hashtbl", "%p: p_entry %p value set to %p", ht, *p_entry, value)); 
     218            PJ_LOG(6, ("hashtbl", "%p: p_entry %p value set to %p", ht,  
     219                       *p_entry, value)); 
     220        } 
     221    } 
     222} 
     223 
     224PJ_DEF(void) pj_hash_set_np( pj_hash_table_t *ht, 
     225                             const void *key, unsigned keylen,  
     226                             pj_uint32_t hval, void *entry_buf, void *value) 
     227{ 
     228    pj_hash_entry **p_entry; 
     229 
     230    p_entry = find_entry( NULL, ht, key, keylen, value, &hval, entry_buf ); 
     231    if (*p_entry) { 
     232        if (value == NULL) { 
     233            /* delete entry */ 
     234            PJ_LOG(6, ("hashtbl", "%p: p_entry %p deleted", ht, *p_entry)); 
     235            *p_entry = (*p_entry)->next; 
     236            --ht->count; 
     237             
     238        } else { 
     239            /* overwrite */ 
     240            (*p_entry)->value = value; 
     241            PJ_LOG(6, ("hashtbl", "%p: p_entry %p value set to %p", ht,  
     242                       *p_entry, value)); 
    190243        } 
    191244    } 
Note: See TracChangeset for help on using the changeset viewer.