1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                 Eclipse Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*          http://www.eclipse.org/org/documents/epl-v10.html           *
11*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                  David Korn <dgk@research.att.com>                   *
19*                   Phong Vo <kpv@research.att.com>                    *
20*                                                                      *
21***********************************************************************/
22#pragma prototyped
23/*
24 * Glenn Fowler
25 * AT&T Research
26 *
27 * hash table library
28 */
29
30#include "hashlib.h"
31
32/*
33 * change table size and rehash
34 * size must be a power of 2
35 */
36
37void
38hashsize(register Hash_table_t* tab, int size)
39{
40	register Hash_bucket_t**	old_s;
41	register Hash_bucket_t**	new_s;
42	register Hash_bucket_t*		old_b;
43	register Hash_bucket_t*		new_b;
44	Hash_bucket_t**			old_sx;
45	unsigned int			index;
46	Hash_region_f			region;
47	void*				handle;
48
49	if (size > 0 && size != tab->size && !(size & (size - 1)))
50	{
51		if (region = tab->root->local->region)
52		{
53			handle = tab->root->local->handle;
54			new_s = (Hash_bucket_t**)(*region)(handle, NiL, sizeof(Hash_bucket_t*) * size, 0);
55		}
56		else new_s = newof(0, Hash_bucket_t*, size, 0);
57		if (!new_s) tab->flags |= HASH_FIXED;
58		else
59		{
60			old_sx = (old_s = tab->table) + tab->size;
61			tab->size = size;
62			while (old_s < old_sx)
63			{
64				old_b = *old_s++;
65				while (old_b)
66				{
67					new_b = old_b;
68					old_b = old_b->next;
69					index = new_b->hash;
70					HASHMOD(tab, index);
71					new_b->next = new_s[index];
72					new_s[index] = new_b;
73				}
74			}
75			if ((tab->flags & (HASH_RESIZE|HASH_STATIC)) != HASH_STATIC)
76			{
77				if (region) (*region)(handle, tab->table, 0, 0);
78				else free(tab->table);
79			}
80			tab->table = new_s;
81			tab->flags |= HASH_RESIZE;
82		}
83	}
84}
85