/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* hash table library
*/
#include "hashlib.h"
/*
* hash table lookup
*/
char*
{
register Hash_bucket_t* b;
register unsigned int n;
unsigned int i;
{
register char* s1;
register const char* s2;
register int c;
else
{
n = 0;
}
i = n;
for (;;)
{
{
}
return(0);
n = i;
}
}
if (name)
{
{
}
{
n = (unsigned int)integralof(name);
}
for (;;)
{
{
if (i == HASHVAL(b->hash) && ((b->hash & (HASH_DELETED|HASH_OPAQUED)) != HASH_DELETED || (flags & (HASH_CREATE|HASH_DELETE|HASH_INSTALL|HASH_RENAME))))
{
{
{
}
}
{
}
}
}
n = i;
}
}
else
{
prev = 0;
{
/*
* found the bucket
*/
{
/*
* migrate popular buckets to the front
*/
}
{
case HASH_CREATE:
case HASH_CREATE|HASH_INSTALL:
case HASH_INSTALL:
goto exists;
case HASH_DELETE:
value = 0;
{
{
{
b->value = 0;
}
{
b->value = 0;
}
}
else
{
if (tab->root->local->free && (tab->root->flags & HASH_BUCKET)) (*tab->root->local->free)((char*)b);
{
else free(b);
}
if (name)
{
if (tab->root->local->region) (*tab->root->local->region)(tab->root->local->handle, (char*)name, 0, 0);
}
}
}
return((char*)value);
case HASH_RENAME:
if (tab != top || tab->frozen || (b->hash & (HASH_KEEP|HASH_OPAQUED)) || hashlook(top, value, (flags&(HASH_HASHED|HASH_INTERNAL))|HASH_LOOKUP, NiL))
return(0);
{
name = 0;
}
else
{
int m;
char* t;
if (!(i = tab->bucketsize))
i = (sizeof(Hash_bucket_t) + sizeof(char*) - 1) / sizeof(char*);
i *= sizeof(char*);
{
name = 0;
}
else
{
m++;
if (!(t = tab->root->local->region ? (char*)(*tab->root->local->region)(tab->root->local->handle, NiL, m, 0) : (char*)malloc(m)))
return(0);
}
}
{
b->hash &= ~HASH_FREENAME;
if (tab->root->local->region) (*tab->root->local->region)(tab->root->local->handle, (char*)name, 0, 0);
}
goto create;
default:
return(0);
}
}
}
/*
* create a new bucket
*/
else
{
if (prev = b)
{
i |= HASH_HIDES;
}
}
/*
* check for table expansion
*/
if (flags & HASH_INSTALL)
{
i |= HASH_KEEP;
}
else
{
int m = tab->bucketsize * sizeof(char*);
if (flags & HASH_VALUE)
{
if (m < sizeof(Hash_bucket_t))
{
m = tab->bucketsize * sizeof(char*);
}
n = m;
}
else if (!(n = HASH_SIZEOF(flags)))
{
if (!(flags & HASH_FIXED)) n = m;
else if ((n = (int)integralof(value)) < m) n = m;
}
else if (n < m) n = m;
{
{
return(0);
memset(b, 0, n + m);
}
else if (!(b = newof(0, Hash_bucket_t, 0, n + m)))
return(0);
b->name = (char*)b + n;
}
else
{
{
return(0);
memset(b, 0, n);
}
else if (!(b = newof(0, Hash_bucket_t, 0, n)))
return(0);
}
}
b->hash = n = i;
if (flags & HASH_OPAQUE)
{
return(0);
}
/*
* finally got the bucket
*/
if (b->hash & HASH_DELETED)
{
b->hash &= ~HASH_DELETED;
}
{
case HASH_CREATE|HASH_VALUE:
if (tab->root->local->free && !(tab->root->flags & HASH_BUCKET) && b->value) (*tab->root->local->free)(b->value);
if (value && tab->root->local->alloc) value = (*tab->root->local->alloc)((unsigned int)integralof(value));
return((char*)hashname(b));
case HASH_VALUE:
return(b->value);
default:
return((char*)b);
}
}