|
Packit Service |
a8c26c |
/***********************************************************************
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
* This software is part of the ast package *
|
|
Packit Service |
a8c26c |
* Copyright (c) 1985-2011 AT&T Intellectual Property *
|
|
Packit Service |
a8c26c |
* and is licensed under the *
|
|
Packit Service |
a8c26c |
* Eclipse Public License, Version 1.0 *
|
|
Packit Service |
a8c26c |
* by AT&T Intellectual Property *
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
* A copy of the License is available at *
|
|
Packit Service |
a8c26c |
* http://www.eclipse.org/org/documents/epl-v10.html *
|
|
Packit Service |
a8c26c |
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
* Information and Software Systems Research *
|
|
Packit Service |
a8c26c |
* AT&T Research *
|
|
Packit Service |
a8c26c |
* Florham Park NJ *
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
* Glenn Fowler <gsf@research.att.com> *
|
|
Packit Service |
a8c26c |
* David Korn <dgk@research.att.com> *
|
|
Packit Service |
a8c26c |
* Phong Vo <kpv@research.att.com> *
|
|
Packit Service |
a8c26c |
* *
|
|
Packit Service |
a8c26c |
***********************************************************************/
|
|
Packit Service |
a8c26c |
#pragma prototyped
|
|
Packit Service |
a8c26c |
/*
|
|
Packit Service |
a8c26c |
* Glenn Fowler
|
|
Packit Service |
a8c26c |
* AT&T Research
|
|
Packit Service |
a8c26c |
*
|
|
Packit Service |
a8c26c |
* hash table library
|
|
Packit Service |
a8c26c |
*/
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
#include "hashlib.h"
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
/*
|
|
Packit Service |
a8c26c |
* free (remove) a hash table
|
|
Packit Service |
a8c26c |
* can be called for partially constructed tables
|
|
Packit Service |
a8c26c |
* scope covered table pointer is returned
|
|
Packit Service |
a8c26c |
* root info freed when last reference freed
|
|
Packit Service |
a8c26c |
*/
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
Hash_table_t*
|
|
Packit Service |
a8c26c |
hashfree(register Hash_table_t* tab)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
register Hash_bucket_t** sp;
|
|
Packit Service |
a8c26c |
register Hash_bucket_t* b;
|
|
Packit Service |
a8c26c |
register Hash_bucket_t* p;
|
|
Packit Service |
a8c26c |
Hash_bucket_t** sx;
|
|
Packit Service |
a8c26c |
Hash_root_t* rp;
|
|
Packit Service |
a8c26c |
Hash_table_t* tp;
|
|
Packit Service |
a8c26c |
Hash_free_f freevalue;
|
|
Packit Service |
a8c26c |
Hash_free_f freebucket;
|
|
Packit Service |
a8c26c |
Hash_region_f region;
|
|
Packit Service |
a8c26c |
void* handle;
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if (!tab) return(0);
|
|
Packit Service |
a8c26c |
if (tab->table)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
freebucket = 0;
|
|
Packit Service |
a8c26c |
freevalue = 0;
|
|
Packit Service |
a8c26c |
if (tab->root->local->free)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
if (tab->root->flags & HASH_BUCKET) freebucket = tab->root->local->free;
|
|
Packit Service |
a8c26c |
else freevalue = tab->root->local->free;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
if (region = tab->root->local->region)
|
|
Packit Service |
a8c26c |
handle = tab->root->local->handle;
|
|
Packit Service |
a8c26c |
sx = &tab->table[tab->size];
|
|
Packit Service |
a8c26c |
sp = &tab->table[0];
|
|
Packit Service |
a8c26c |
while (sp < sx)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
b = *sp++;
|
|
Packit Service |
a8c26c |
while (b)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
p = b;
|
|
Packit Service |
a8c26c |
b = b->next;
|
|
Packit Service |
a8c26c |
if (freebucket) (*freebucket)((char*)p);
|
|
Packit Service |
a8c26c |
else if (freevalue && p->value) (*freevalue)(p->value);
|
|
Packit Service |
a8c26c |
if (p->hash & HASH_FREENAME)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
p->hash &= ~HASH_FREENAME;
|
|
Packit Service |
a8c26c |
if (region) (*region)(handle, p->name, 0, 0);
|
|
Packit Service |
a8c26c |
else free(p->name);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
if (!(p->hash & HASH_KEEP))
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
if (region) (*region)(handle, p, 0, 0);
|
|
Packit Service |
a8c26c |
else free(p);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
else if (p->hash & HASH_HIDES)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
p->hash &= ~HASH_HIDES;
|
|
Packit Service |
a8c26c |
p->name = ((Hash_bucket_t*)p->name)->name;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
if ((tab->flags & (HASH_RESIZE|HASH_STATIC)) != HASH_STATIC)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
if (region) (*region)(handle, tab->table, 0, 0);
|
|
Packit Service |
a8c26c |
else free(tab->table);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
else region = 0;
|
|
Packit Service |
a8c26c |
if (tab->root)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
if (!region)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
/*
|
|
Packit Service |
a8c26c |
* remove from the table lists
|
|
Packit Service |
a8c26c |
*/
|
|
Packit Service |
a8c26c |
|
|
Packit Service |
a8c26c |
if ((tp = tab->root->references) != tab)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
for (; tp; tp = tp->next)
|
|
Packit Service |
a8c26c |
if (tp->next == tab)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
tp->next = tab->next;
|
|
Packit Service |
a8c26c |
break;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
else if (!(tab->root->references = tp->next))
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
if ((rp = hash_info.list) != tab->root)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
for (; rp; rp = rp->next)
|
|
Packit Service |
a8c26c |
if (rp->next == tab->root)
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
rp->next = tab->root->next;
|
|
Packit Service |
a8c26c |
break;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
else hash_info.list = rp->next;
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
if (!(tab->root->references))
|
|
Packit Service |
a8c26c |
{
|
|
Packit Service |
a8c26c |
if (tab->root->local)
|
|
Packit Service |
a8c26c |
free(tab->root->local);
|
|
Packit Service |
a8c26c |
if (region) (*region)(handle, tab->root, 0, 0);
|
|
Packit Service |
a8c26c |
else free(tab->root);
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
}
|
|
Packit Service |
a8c26c |
if (tp = tab->scope) tp->frozen--;
|
|
Packit Service |
a8c26c |
if (region) (*region)(handle, tab, 0, 0);
|
|
Packit Service |
a8c26c |
else free(tab);
|
|
Packit Service |
a8c26c |
return(tp);
|
|
Packit Service |
a8c26c |
}
|