Skip to content
Snippets Groups Projects
Select Git revision
  • chacha96
  • master default
  • support_pre_UAL_arm_asm
  • skein
  • rsa-crt-hardening
  • fat-library
  • versioned-symbols
  • curve25519
  • dsa-reorg
  • aead-api
  • set_key-changes
  • poly1305
  • aes-reorg
  • nettle-2.7-fixes
  • size_t-changes
  • ecc-support
  • experimental-20050201
  • lsh-1.4.2
  • nettle_3.3_release_20161001
  • nettle_3.2_release_20160128
  • nettle_3.1.1_release_20150424
  • nettle_3.1_release_20150407
  • nettle_3.1rc3
  • nettle_3.1rc2
  • nettle_3.1rc1
  • nettle_3.0_release_20140607
  • nettle_2.7.1_release_20130528
  • nettle_2.7_release_20130424
  • nettle_2.6_release_20130116
  • nettle_2.5_release_20120707
  • converted-master-branch-to-git
  • nettle_2.4_release_20110903
  • nettle_2.3_release_20110902
  • nettle_2.2_release_20110711
  • nettle_2.1_release_20100725
  • camellia_32bit_20100720
  • nettle_2.0_release_20090608
  • nettle_1.15_release_20061128
38 results

COPYINGv3

Blame
  • Forked from Nettle / nettle
    Source project has a limited visibility.
    hashtable.c 3.59 KiB
    /*\
    ||| This file a part of Pike, and is copyright by Fredrik Hubinette
    ||| Pike is distributed as GPL (General Public License)
    ||| See the files COPYING and DISCLAIMER for more information.
    \*/
    /**/
    #include "global.h"
    #include "hashtable.h"
    #include "stralloc.h"
    #include "stuff.h"
    #include "error.h"
    
    RCSID("$Id: hashtable.c,v 1.7 2000/08/15 16:03:48 grubba Exp $");
    
    static size_t gobble(struct pike_string *s)
    {
      size_t i;
      i=my_hash_string(s);
      i+=i >> 3;
      i+=i >> 7;
      i+=i >> 12;
      return i;
    }
    
    /*
     * Search hash for a specific string.
     */
    struct hash_entry *hash_lookup(struct hash_table *h, struct pike_string *s)
    {
      struct hash_entry *e, **prev, **base;
    
      if(!h) return 0;
      base = prev = h->htable + (gobble(s) & h->mask);
      for( ;(e = *prev); prev= &e->next)
      {
        if(s == e->s)
        {
          /* Teleport entry to beginning of line */
          *prev = e->next;
          e->next = *base;
          *base = e;
          /* Entry arrives in a puff of smoke. */
    
          return e;
        }
      }
      return 0;
    }
    
    /*
     * We want to keep the order of the hash chain, as it has been carefully
     * built up to be fast.
     */
    static void rehash_list_backwards(struct hash_table *h,
    				  struct hash_entry *n)
    {
      struct hash_entry **base;
      if(!n) return;
      rehash_list_backwards(h,n->next);
      base=h->htable + (gobble(n->s) & h->mask);
      n->next = *base;
      *base=n;
    }
    
    /*
     * create a new, empty hashable
    */
    struct hash_table *create_hash_table(void)
    {
      struct hash_table *new;
      new=(struct hash_table *)calloc(1,sizeof(struct hash_table)+
    				  (NEW_HASHTABLE_SIZE-1)*sizeof(struct hash_entry *));
      new->entries=0;
      new->mask=NEW_HASHTABLE_SIZE-1;
      return new;
    }
    
    /*
     * rehash - ugh
     */
    struct hash_table *hash_rehash(struct hash_table *h,int size)
    {
      struct hash_table *new;
      int e;
    
    #ifdef PIKE_DEBUG
      if( 1 << my_log2(size) != size)
        fatal("Size is not a power of two!\n");
    #endif
    
      new=(struct hash_table *)calloc(1,sizeof(struct hash_table)+
    				  (size-1)*sizeof(struct hash_entry *));
      new->mask = size - 1;
      new->entries = h->entries;
    
      for(e=0; e<=h->mask; e++)
        rehash_list_backwards(new,h->htable[e]);
    
      free((char *)h);
      return new;
    }
    
    /*
     * insert a newly created hash entry on it's rightful place in the
     * hashtable
     */
    struct hash_table *hash_insert(struct hash_table *h, struct hash_entry *s)
    {
      struct hash_entry **base;
    
      if(!h) h=create_hash_table();
    
      if(h->entries > AVERAGE_HASH_LENGTH * 2 * h->mask)
        h=hash_rehash(h,(h->mask+1) * 2);
    
      base = h->htable + (gobble(s->s) & h->mask);
      s->next = *base;
      *base = s;
      h->entries++;
    
      return h;
    }
    
    /*
     * unlink an entry from an hash table
     */
    struct hash_table *hash_unlink(struct hash_table *h, struct hash_entry *s)
    {
      struct hash_entry **prev,*e;
    
      prev = h->htable + (gobble(s->s) & h->mask);
      for(;( e=*prev ); prev=&e->next)
      {
        if(e==s)
        {
          *prev = e->next;
          h->entries--;
          if(h->mask > NEW_HASHTABLE_SIZE  &&
    	 h->entries < AVERAGE_HASH_LENGTH / 2 * h->mask)
    	h=hash_rehash(h,(h->mask+1) / 2);
          return h;
        }
      }
    #ifdef PIKE_DEBUG
      fatal("hash_entry not in hashtable\n");
    #endif
      return h;
    }
    
    void map_hashtable(struct hash_table *h, void (*fun)(struct hash_entry *))
    {
      INT32 e;
      struct hash_entry *i, *n;
      for(e=0;e<=h->mask;e++)
      {
        for(i=h->htable[e];i;i=n)
        {
          n=i->next;
          fun(i);
        }
      }
    }
    
    void free_hashtable(struct hash_table *h,
    		    void (*free_entry)(struct hash_entry *))
    {
      INT32 e;
      struct hash_entry *i, *n;
      for(e=0;e<=h->mask;e++)
      {
        for(i=h->htable[e];i;i=n)
        {
          n=i->next;
          free_string(i->s);
          if(free_entry)
    	free_entry(i);
          else
    	free((char *)i);
        }
      }
      free((char *)h);
    }