This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/library/lammpi/hash.c
2012-02-03 16:31:49 +00:00

217 lines
5.5 KiB
C

/*
Copyright (C) 2004,2005,2006 (Nuno A. Fonseca) <nuno.fonseca@gmail.com>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Last rev: $Id: hash.c,v 1.2 2006-06-04 19:02:07 nunofonseca Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include "hash.h"
#define BUCKET(table,i) table->buckets[i]
#define HASHSIZE(table) table->size
static int mhash(hashtable,ulong);
static hashnode* hash_lookup(hashtable,ulong);
static hashnode* hash_lookup(hashtable table,ulong key){
table->last_node = BUCKET(table,mhash(table,key)); /* set a pointer to the first bucket */
while ( table->last_node != NULL ) {
if( table->last_node->value==key) return table->last_node;
table->last_node = table->last_node->next;
}
return NULL;
}
__ptr_t get_next_object(hashtable table,ulong key)
{
if(table->last_node==NULL)
return NULL;
table->last_node = table->last_node->next;
while ( table->last_node != NULL ) {
if( table->last_node->value==key) return table->last_node->obj;
table->last_node = table->last_node->next;
}
return NULL;
}
/* removes the element with key 'key' and returns the object stored on it */
__ptr_t delete(hashtable table,ulong key)
{
__ptr_t obj;
hashnode *b,*prev=NULL;
int c=mhash(table,key);
b=BUCKET(table,c); /* set a pointer to the first bucket */
while( b!=NULL) {
if( b->value==key){
obj=b->obj;
if(prev==NULL) /* first element */
BUCKET(table,c)=b->next;
else
prev->next=b->next;
free(b);
table->n_entries--;
return obj;
}
prev = b;
b = b->next;
};
return NULL;
}
__ptr_t replace_object(hashtable table,ulong key,__ptr_t newobj)
{
__ptr_t old;
hashnode *b=hash_lookup(table,key);
if(b==NULL)return NULL;
old=b->obj;
b->obj=newobj;
return old;
}
/* looks a 'bucket' in the hashing table whith 'key' and return the
pointer to the object stored in that bucket or NULL if no bucket is found */
__ptr_t get_object(hashtable table,ulong key){
hashnode *b=hash_lookup(table,key);
if(b==NULL)
return NULL;
return b->obj;
}
/* Allocates space to a new hash table */
hashtable new_hashtable(ulong hashsize) {
hashtable new;
register int i;
if( (new = (hashtable)malloc(sizeof(struct hashtable_s)))==NULL) return NULL;
if( (new->buckets = (hashnode**)malloc(sizeof(hashnode*)*hashsize))==NULL)
return NULL;
new->size=hashsize;
new->last_bucket=0;
new->last_node=NULL;
new->n_entries=0;
for(i=0;i<hashsize;++i) BUCKET(new,i) = NULL;
return new;
}
/* A very simple hashing function */
static int mhash(hashtable table,ulong key)
{
return (int)(key%HASHSIZE(table));
}
/* inserts a new element in the hash table*/
int insere(hashtable table,ulong key,__ptr_t obj)
{
int ind;
hashnode *new;
if((new=(hashnode *)malloc(sizeof(hashnode)))==NULL) return -1;
ind=mhash(table,key);
new->next = BUCKET(table,ind);
new->value=key;
new->obj=obj;
BUCKET(table,ind)=new;
table->n_entries++;
return 1;
}
void free_hashtable(hashtable table)
{
register int i;
hashnode *n,*tmp;
//fprintf(stderr,"free_hashtable\n");fflush(stderr);
if (table==NULL) return;
for(i=0;i<HASHSIZE(table);++i) {
n=BUCKET(table,i);
while(n!=NULL) {
tmp=n;
n=n->next;
free(tmp);
}
}
free(table->buckets);
free(table);
}
/*********************************************************************************/
/*
* Returns all objects stored in a basket by making successive calls
*/
void init_hash_traversal(hashtable table) {
table->last_bucket=0;
table->last_node=NULL;
}
/*
* Returns all objects stored in a basket by making successive calls
*/
__ptr_t next_hash_object(hashtable table)
{
// first time....
if( table->last_bucket>=HASHSIZE(table))
return NULL;
if( table->last_node==NULL ) {
// find bucket
// find next bucket
while ( table->last_node == NULL && table->last_bucket+1<HASHSIZE(table)) {
++table->last_bucket;
table->last_node = BUCKET(table,table->last_bucket);
}
if (table->last_node==NULL)
return NULL;
return table->last_node->obj;
}
// Next in bucket
table->last_node=table->last_node->next;
if (table->last_node==NULL) return next_hash_object(table);
return table->last_node->obj;
}
/*
* Returns all hash nodes stored in a basket by making successive calls
*/
__ptr_t next_hashnode(hashtable table)
{
// first time....
if( table->last_bucket>=HASHSIZE(table))
return NULL;
if( table->last_node==NULL ) {
// find bucket
// find next bucket
while ( table->last_node == NULL && table->last_bucket+1<HASHSIZE(table)) {
++table->last_bucket;
table->last_node = BUCKET(table,table->last_bucket);
}
if (table->last_node==NULL)
return NULL;
return table->last_node;
}
// Next in bucket
table->last_node=table->last_node->next;
if (table->last_node==NULL) return next_hashnode(table);
return table->last_node;
}