Beispiel #1
0
static void
grow_hash_table (struct hash_table *ht)
{
  struct mapping *old_mappings = ht->mappings;
  struct mapping *old_end      = ht->mappings + ht->size;
  struct mapping *mp, *mappings;
  int newsize;

  newsize = prime_size (ht->size * 2);
#if 0
  printf ("growing from %d to %d\n", ht->size, newsize);
#endif

  ht->size = newsize;
  ht->resize_threshold = newsize * 3 / 4;

  mappings = xmalloc (ht->size * sizeof (struct mapping));
  memset (mappings, '\0', ht->size * sizeof (struct mapping));
  ht->mappings = mappings;

  for (mp = old_mappings; mp < old_end; mp++)
    if (!EMPTY_MAPPING_P (mp))
      {
	struct mapping *new_mp = mappings + HASH_POSITION (ht, mp->key);
	/* We don't need to call test function and worry about
	   collisions because all the keys come from the hash table
	   and are therefore guaranteed to be unique.  */
	LOOP_NON_EMPTY (new_mp, mappings, newsize)
	  ;
	*new_mp = *mp;
      }

  xfree (old_mappings);
}
Beispiel #2
0
struct hash_table *
hash_table_new (int items,
                unsigned long (*hash_function) (const void *),
                int (*test_function) (const void *, const void *))
{
  int size;
  struct hash_table *ht = xnew (struct hash_table);

  ht->hash_function = hash_function ? hash_function : hash_pointer;
  ht->test_function = test_function ? test_function : cmp_pointer;

  /* If the size of struct hash_table ever becomes a concern, this
     field can go.  (Wget doesn't create many hashes.)  */
  ht->prime_offset = 0;

  /* Calculate the size that ensures that the table will store at
     least ITEMS keys without the need to resize.  */
  size = 1 + items / HASH_MAX_FULLNESS;
  size = prime_size (size, &ht->prime_offset);
  ht->size = size;
  ht->resize_threshold = size * HASH_MAX_FULLNESS;
  /*assert (ht->resize_threshold >= items);*/

  ht->cells = xnew_array (struct cell, ht->size);

  /* Mark cells as empty.  We use 0xff rather than 0 to mark empty
     keys because it allows us to use NULL/0 as keys.  */
  memset (ht->cells, INVALID_PTR_CHAR, size * sizeof (struct cell));

  ht->count = 0;

  return ht;
}
Beispiel #3
0
int createhash(hash* h,int defaultsize,hashfun_t hf)
{
    h->prime_offset=0;
    h->size=prime_size(defaultsize,&h->prime_offset);
    if((h->addr=(cell*)malloc(sizeof(cell)*h->size))==0)
        return 1;
    h->hashfunction=hf?hf:defaulthash;
    h->currentsize=0;
    h->tombsize=0;
    int i;
    for(i=0;i<h->size;++i)          //初始化为空
        (h->addr+i)->stat=EMPTY;
    return 0;
}
Beispiel #4
0
/*
 *增长过程,把原来表的size和prime_size变动了。并更新了存储空间。currentsize不变,tombsize清零
 */
static int grow(hash* h)
{
    int oldsize=h->size;
    h->size=prime_size(oldsize*hash_resize_factor,&h->prime_offset);    //更新size...函数调用prime_size还会自动更新prime_offset
    cell* oldaddr=h->addr;
    if((h->addr=(cell*)malloc(h->size*sizeof(cell)))==0)     //更新存储空间
        return 1;
    int i;
    for(i=0;i<h->size;++i)
        (h->addr+i)->stat=EMPTY;    //初始化新表
    h->currentsize=0;               //currentsize计数清零
    for(i=0;i<oldsize;++i)          //把原来表的数据转到新存储空间
    {
        if((oldaddr+i)->stat==OCCUPY)
           push(h,(oldaddr+i)->key,(oldaddr+i)->value);     //这里会更新currentsize计数
    }
    free(oldaddr);      //销毁原来的存储空间
    h->tombsize=0;         //tomb计数清0
    return 0;
}
Beispiel #5
0
struct hash_table *
hash_table_new (int initial_size,
		unsigned long (*hash_function) (const void *),
		int (*test_function) (const void *, const void *))
{
  struct hash_table *ht
    = (struct hash_table *)xmalloc (sizeof (struct hash_table));

  ht->hash_function = hash_function;
  ht->test_function = test_function;

  ht->size = prime_size (initial_size);
  ht->resize_threshold = ht->size * 3 / 4;

  ht->count    = 0;

  ht->mappings = xmalloc (ht->size * sizeof (struct mapping));
  memset (ht->mappings, '\0', ht->size * sizeof (struct mapping));

  return ht;
}
Beispiel #6
0
static void
grow_hash_table (struct hash_table *ht)
{
  hashfun_t hasher = ht->hash_function;
  struct cell *old_cells = ht->cells;
  struct cell *old_end   = ht->cells + ht->size;
  struct cell *c, *cells;
  int newsize;

  newsize = prime_size (ht->size * HASH_RESIZE_FACTOR, &ht->prime_offset);
#if 0
  printf ("growing from %d to %d; fullness %.2f%% to %.2f%%\n",
          ht->size, newsize,
          100.0 * ht->count / ht->size,
          100.0 * ht->count / newsize);
#endif

  ht->size = newsize;
  ht->resize_threshold = newsize * HASH_MAX_FULLNESS;

  cells = xnew_array (struct cell, newsize);
  memset (cells, INVALID_PTR_CHAR, newsize * sizeof (struct cell));
  ht->cells = cells;

  for (c = old_cells; c < old_end; c++)
    if (CELL_OCCUPIED (c))
      {
        struct cell *new_c;
        /* We don't need to test for uniqueness of keys because they
           come from the hash table and are therefore known to be
           unique.  */
        new_c = cells + HASH_POSITION (c->key, hasher, newsize);
        FOREACH_OCCUPIED_ADJACENT (new_c, cells, newsize)
          ;
        *new_c = *c;
      }

  xfree (old_cells);
}