blob: 35b0aac1b2182ce703ee41be7a6ad36e4404e828 [file] [log] [blame]
/**************************************************************/
/* ********************************************************** */
/* * * */
/* * HASHING * */
/* * * */
/* * $Module: HASHARRAY * */
/* * * */
/* * Copyright (C) 1997, 1998, 1999, 2000, 2001 * */
/* * MPI fuer Informatik * */
/* * * */
/* * 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; either version 2 of the License, * */
/* * or (at your option) any later version. * */
/* * * */
/* * 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 * */
/* * * */
/* * * */
/* $Revision$ * */
/* $State$ * */
/* $Date$ * */
/* $Author$ * */
/* * * */
/* * Contact: * */
/* * Christoph Weidenbach * */
/* * MPI fuer Informatik * */
/* * Stuhlsatzenhausweg 85 * */
/* * 66123 Saarbruecken * */
/* * Email: weidenb@mpi-sb.mpg.de * */
/* * Germany * */
/* * * */
/* ********************************************************** */
/**************************************************************/
/* $RCSfile$ */
#ifndef _HASHARRAY_
#define _HASHARRAY_
/**************************************************************/
/* Includes */
/**************************************************************/
#include "list.h"
/**************************************************************/
/* Structures */
/**************************************************************/
#define hsh__SIZE 29 /* a prime */
/* Each Entry is a list of pairs <key,list of values> */
typedef LIST* HASH;
void hsh_Check(HASH H);
/**************************************************************/
/* Inline Functions */
/**************************************************************/
static __inline__ unsigned long hsh_Index(POINTER Key)
/**************************************************************
INPUT: A pointer
RETURNS: A key for the hasharray
***************************************************************/
{
return (unsigned long)Key % hsh__SIZE;
}
static __inline__ void hsh_Put(HASH H, POINTER Key, POINTER Value)
/**************************************************************
INPUT: A hasharray, a pointer used as key and a pointer to a data item
EFFECT: Add Value to the list of data items associated with the key,
if it isn't a member already
***************************************************************/
{
LIST Scan, Pair;
unsigned long HashKey;
HashKey = hsh_Index(Key);
for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
Pair = list_Car(Scan);
if (list_PairFirst(Pair) == Key) {
if (!list_PointerMember(list_PairSecond(Pair), Value))
list_Rplacd(Pair, list_Cons(Value, list_PairSecond(Pair)));
#ifdef CHECK
hsh_Check(H);
#endif
return;
}
}
H[HashKey] = list_Cons(list_PairCreate(Key, list_List(Value)), H[HashKey]);
#ifdef CHECK
hsh_Check(H);
#endif
}
static __inline__ void hsh_PutList(HASH H, POINTER Key, LIST List)
/**************************************************************
INPUT: A hasharray, a pointer used as key and a list of data items
EFFECT: Add the list to the list of data items associated with the key,
and delete all duplicates.
***************************************************************/
{
LIST Scan, Pair;
unsigned long HashKey;
HashKey = hsh_Index(Key);
for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
Pair = list_Car(Scan);
if (list_PairFirst(Pair) == Key) {
list_Rplacd(Pair, list_Nconc(list_PairSecond(Pair), List));
#ifdef CHECK
hsh_Check(H);
#endif
return;
}
}
H[HashKey] = list_Cons(list_PairCreate(Key, List), H[HashKey]);
#ifdef CHECK
hsh_Check(H);
#endif
}
static __inline__ void hsh_PutListWithCompareFunc(HASH H, POINTER Key,
LIST List,
BOOL (*Test)(POINTER, POINTER),
unsigned long (*HashFunc)(POINTER))
/**************************************************************
INPUT: A hasharray, a pointer used as key, a list of data
items, a test function for key equality and a
hashing function.
EFFECT: Add the list to the list of data items associated
with the key, and delete all duplicates.
***************************************************************/
{
LIST Scan, Pair;
unsigned long HashKey;
HashKey = (unsigned long) HashFunc(Key);
for (Scan = H[HashKey]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
Pair = (LIST) list_Car(Scan);
if (Test(list_PairFirst(Pair), Key)) {
list_Rplacd(Pair, list_Nconc(list_PairSecond(Pair), List));
#ifdef CHECK
hsh_Check(H);
#endif
return;
}
}
H[HashKey] = list_Cons(list_PairCreate(Key, List), H[HashKey]);
#ifdef CHECK
hsh_Check(H);
#endif
}
static __inline__ LIST hsh_Get(HASH H, POINTER Key)
/**************************************************************
INPUT: A hasharray and a pointer used as key
RETURNS: The list of data items associated with the key
***************************************************************/
{
LIST Scan, Pair;
for (Scan = H[hsh_Index(Key)]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
Pair = list_Car(Scan);
if (list_PairFirst(Pair) == Key)
return list_PairSecond(Pair);
}
return NULL;
}
static __inline__ void hsh_DelItem(HASH H, POINTER Key)
/**************************************************************
INPUT: A hasharray and a pointer used as key
RETURNS: The information associated with the key is deleted
***************************************************************/
{
LIST Scan, Pair;
unsigned long k;
k = hsh_Index(Key);
for (Scan = H[k]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
Pair = list_Car(Scan);
if (list_PairFirst(Pair) == Key) {
list_Delete(list_PairSecond(Pair));
list_PairFree(Pair);
H[k] = list_PointerDeleteElement(H[k], Pair);
return;
}
}
}
static __inline__ LIST hsh_GetWithCompareFunc(HASH H, POINTER Key,
BOOL (*Test)(POINTER, POINTER),
unsigned long (*HashFunc)(POINTER))
/**************************************************************
INPUT: A hasharray, a pointer used as key, a compare function
for keys and a hash function for keys.
RETURNS: The list of data items associated with the key
***************************************************************/
{
LIST Scan, Pair;
for (Scan = H[HashFunc(Key)]; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
Pair = list_Car(Scan);
if (Test(list_PairFirst(Pair), Key))
return list_PairSecond(Pair);
}
return NULL;
}
static __inline__ unsigned long hsh_StringHashKey(const char* Label)
{
unsigned long i, s;
s = 0;
for (i = 0; i <= strlen(Label); i++)
s += Label[i];
s = s % hsh__SIZE;
return s;
}
/**************************************************************/
/* Functions */
/**************************************************************/
HASH hsh_Create(void);
void hsh_Reset(HASH H);
void hsh_Delete(HASH H);
LIST hsh_GetAllEntries(HASH H);
#endif