Diff for /embedaddon/quagga/lib/hash.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 17:26:12 version 1.1.1.2, 2016/11/02 10:09:11
Line 31  hash_create_size (unsigned int size, unsigned int (*ha Line 31  hash_create_size (unsigned int size, unsigned int (*ha
 {  {
   struct hash *hash;    struct hash *hash;
   
     assert ((size & (size-1)) == 0);
   hash = XMALLOC (MTYPE_HASH, sizeof (struct hash));    hash = XMALLOC (MTYPE_HASH, sizeof (struct hash));
   hash->index = XCALLOC (MTYPE_HASH_INDEX,    hash->index = XCALLOC (MTYPE_HASH_INDEX,
                          sizeof (struct hash_backet *) * size);                           sizeof (struct hash_backet *) * size);
   hash->size = size;    hash->size = size;
     hash->no_expand = 0;
   hash->hash_key = hash_key;    hash->hash_key = hash_key;
   hash->hash_cmp = hash_cmp;    hash->hash_cmp = hash_cmp;
   hash->count = 0;    hash->count = 0;
Line 47  struct hash * Line 49  struct hash *
 hash_create (unsigned int (*hash_key) (void *),   hash_create (unsigned int (*hash_key) (void *), 
              int (*hash_cmp) (const void *, const void *))               int (*hash_cmp) (const void *, const void *))
 {  {
  return hash_create_size (HASHTABSIZE, hash_key, hash_cmp);  return hash_create_size (HASH_INITIAL_SIZE, hash_key, hash_cmp);
 }  }
   
 /* Utility function for hash_get().  When this function is specified  /* Utility function for hash_get().  When this function is specified
Line 59  hash_alloc_intern (void *arg) Line 61  hash_alloc_intern (void *arg)
   return arg;    return arg;
 }  }
   
   /* Expand hash if the chain length exceeds the threshold. */
   static void hash_expand (struct hash *hash)
   {
     unsigned int i, new_size, losers;
     struct hash_backet *hb, *hbnext, **new_index;
   
     new_size = hash->size * 2;
     new_index = XCALLOC(MTYPE_HASH_INDEX, sizeof(struct hash_backet *) * new_size);
     if (new_index == NULL)
       return;
   
     for (i = 0; i < hash->size; i++)
       for (hb = hash->index[i]; hb; hb = hbnext)
         {
           unsigned int h = hb->key & (new_size - 1);
   
           hbnext = hb->next;
           hb->next = new_index[h];
           new_index[h] = hb;
         }
   
     /* Switch to new table */
     XFREE(MTYPE_HASH_INDEX, hash->index);
     hash->size = new_size;
     hash->index = new_index;
   
     /* Ideally, new index should have chains half as long as the original.
        If expansion didn't help, then not worth expanding again,
        the problem is the hash function. */
     losers = 0;
     for (i = 0; i < hash->size; i++)
       {
         unsigned int len = 0;
         for (hb = hash->index[i]; hb; hb = hb->next)
           {
             if (++len > HASH_THRESHOLD/2)
               ++losers;
             if (len >= HASH_THRESHOLD)
               hash->no_expand = 1;
           }
       }
   
     if (losers > hash->count / 2)
       hash->no_expand = 1;
   }
   
 /* Lookup and return hash backet in hash.  If there is no  /* Lookup and return hash backet in hash.  If there is no
    corresponding hash backet and alloc_func is specified, create new     corresponding hash backet and alloc_func is specified, create new
    hash backet.  */     hash backet.  */
Line 68  hash_get (struct hash *hash, void *data, void * (*allo Line 116  hash_get (struct hash *hash, void *data, void * (*allo
   unsigned int key;    unsigned int key;
   unsigned int index;    unsigned int index;
   void *newdata;    void *newdata;
     unsigned int len;
   struct hash_backet *backet;    struct hash_backet *backet;
   
   key = (*hash->hash_key) (data);    key = (*hash->hash_key) (data);
  index = key % hash->size;  index = key & (hash->size - 1);
   len = 0;
   
  for (backet = hash->index[index]; backet != NULL; backet = backet->next)   for (backet = hash->index[index]; backet != NULL; backet = backet->next)
    if (backet->key == key && (*hash->hash_cmp) (backet->data, data))    {
      return backet->data;      if (backet->key == key && (*hash->hash_cmp) (backet->data, data))
         return backet->data;
       ++len;
     }
   
   if (alloc_func)    if (alloc_func)
     {      {
Line 83  hash_get (struct hash *hash, void *data, void * (*allo Line 136  hash_get (struct hash *hash, void *data, void * (*allo
       if (newdata == NULL)        if (newdata == NULL)
         return NULL;          return NULL;
   
         if (len > HASH_THRESHOLD && !hash->no_expand)
           {
             hash_expand (hash);
             index = key & (hash->size - 1);
           }
   
       backet = XMALLOC (MTYPE_HASH_BACKET, sizeof (struct hash_backet));        backet = XMALLOC (MTYPE_HASH_BACKET, sizeof (struct hash_backet));
       backet->data = newdata;        backet->data = newdata;
       backet->key = key;        backet->key = key;
Line 125  hash_release (struct hash *hash, void *data) Line 184  hash_release (struct hash *hash, void *data)
   struct hash_backet *pp;    struct hash_backet *pp;
   
   key = (*hash->hash_key) (data);    key = (*hash->hash_key) (data);
  index = key % hash->size;  index = key & (hash->size - 1);
   
   for (backet = pp = hash->index[index]; backet; backet = backet->next)    for (backet = pp = hash->index[index]; backet; backet = backet->next)
     {      {

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>