* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: hasher.c
* Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
* 4150 Network Circle, Santa Clara, California 95054, U.S.A.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* For the avoidance of doubt, and except that if any non-GPL license
* choice is available it will apply instead, Sun elects to use only
* the General Public License version 2 (GPLv2) at this time for any
* software where a choice of GPL license versions is made
* available with the language indicating that GPLv2 or any later version
* may be used, or where a choice of which version of the GPL is applied is
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* ========== Copyright Header End ============================================
HASH_TBL
*ht_new(unsigned int ht_size
)
/* ht_size should be power of 2 */
retval
=(HASH_TBL
*)malloc(sizeof(HASH_TBL
));
perror("Not enough memory to create hash table...");
retval
->size
=(long)pow(2.0, log((double)ht_size
)/log(2.0) + 0.5 );
retval
->mask
=retval
->size
-1;
retval
->limit
=(retval
->size
*2)/3;
retval
->tbl
=(struct hash_ent
**)malloc(retval
->size
*sizeof(struct hash_ent
*));
perror("Not enough memory to create hash table entries...");
for(i
=0; i
<retval
->size
; retval
->tbl
[i
++]=0)
/* GCCism, get rid of inline if we migrate away from GCC */
static unsigned long hash_value(const char *string
)
unsigned char *p
; /* or signed char *, not really important */
for (p
= (unsigned char *)string
; *p
!= '\0'; p
++)
static void expand_table(register HASH_TBL
*table
)
register int n
= table
->size
* 2, i
;
register struct hash_ent
*p
, **h
, **newh
, **oldh
, *q
;
newh
= (struct hash_ent
**)malloc(n
* sizeof *newh
);
perror("Not enough memory to expand hash table...");
for (h
= newh
, i
= n
; --i
>= 0;)
n
--; /* change to mask */
for (i
= table
->size
; --i
>= 0;)
for (p
= *oldh
++; p
!= NULL
; p
= q
)
p
->next
= newh
[p
->h_hash
& n
];
free((char *)table
->tbl
);
table
->limit
= (table
->size
*2)/3;
void *ht_get(HASH_TBL
*table
, const char *key
)
unsigned long hash
=hash_value(key
);
for (ptr
=table
->tbl
[hash
&table
->mask
]; ptr
&& strcmp(key
, ptr
->key
);
return ptr
? ptr
->data
: NULL
;
/* assumes that entry is not already in table */
void ht_put(HASH_TBL
*table
, char *key
, void *data
)
struct hash_ent
*newnode
;
newnode
=(struct hash_ent
*)malloc(sizeof(struct hash_ent
));
unsigned long hash
=hash_value(key
);
perror("Not enough memory to add to hash table...");
newnode
->key
=strdup(key
);
newnode
->next
=table
->tbl
[hash
&table
->mask
];
table
->tbl
[hash
&table
->mask
]=newnode
;
if (table
->used
>table
->limit
)
char *ht_rm_ent(HASH_TBL
*table
, char *key
)
unsigned long hash
=hash_value(key
);
struct hash_ent
*nxt
=0, *prv
=0;
for (nxt
=table
->tbl
[hash
&table
->mask
]; nxt
&& strcmp(key
, nxt
->key
);
table
->tbl
[hash
&table
->mask
]=nxt
->next
;
/* returns a sorted list of (void *),
each of which points to one of the objects in the hash table */
/* The list is sorted by data. The comparison routine doesn't get the key
explicitly so if you want to sort by key you have to get what the keys are
some other way (such as if the key happens to be in the objects pointed by
the void pointers). Yes, the return type is "wrong", you can't get it
/* it takes a comparison function, which gets passed into qsort() */
/* be careful since qsort() will give the comparison function a pointer
to a pointer to the actual object */
/* a 0 terminates the list */
void *ht_sorted_list(HASH_TBL
*table
, int (*cmp
)(const void *, const void *))
void **list
=(void**)malloc((table
->used
+1)*sizeof(void *));
for(bucket
=table
->size
; --bucket
>=0; )
for (p
= *h
++; p
; p
= p
->next
)
qsort(list
, i
, sizeof(void *), cmp
);
/* this only frees all memory if the data have already been freed somehow */
void ht_delete(HASH_TBL
*table
)
struct hash_ent
*p
, *q
, **ht
;
for(i
=table
->size
, ht
=table
->tbl
; --i
>=0;)
free((void *)table
->tbl
);