109 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			109 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*  $Id$
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Part of SWI-Prolog
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Author:        Jan Wielemaker
							 | 
						||
| 
								 | 
							
								    E-mail:        wielemak@science.uva.nl
							 | 
						||
| 
								 | 
							
								    WWW:           http://www.swi-prolog.org
							 | 
						||
| 
								 | 
							
								    Copyright (C): 1985-2007, University of Amsterdam
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    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 library; if not, write to the Free Software
							 | 
						||
| 
								 | 
							
								    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    As a special exception, if you link this library with other files,
							 | 
						||
| 
								 | 
							
								    compiled with a Free Software compiler, to produce an executable, this
							 | 
						||
| 
								 | 
							
								    library does not by itself cause the resulting executable to be covered
							 | 
						||
| 
								 | 
							
								    by the GNU General Public License. This exception does not however
							 | 
						||
| 
								 | 
							
								    invalidate any other reasons why the executable file might be covered by
							 | 
						||
| 
								 | 
							
								    the GNU General Public License.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "hash.h"
							 | 
						||
| 
								 | 
							
								#include <SWI-Prolog.h>
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define HASHKEY(hash, ptr)	((((intptr_t)ptr)>>(hash->shift)) % (hash)->entries)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ptr_hash *
							 | 
						||
| 
								 | 
							
								new_ptr_hash(int entries, int shift)
							 | 
						||
| 
								 | 
							
								{ ptr_hash *hash = PL_malloc(sizeof(*hash));
							 | 
						||
| 
								 | 
							
								  size_t size = sizeof(*hash->chains)*entries;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  memset(hash, 0, sizeof(*hash));
							 | 
						||
| 
								 | 
							
								  hash->entries = entries;
							 | 
						||
| 
								 | 
							
								  hash->shift   = shift;
							 | 
						||
| 
								 | 
							
								  hash->chains  = PL_malloc(size);
							 | 
						||
| 
								 | 
							
								  memset(hash->chains, 0, size);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return hash;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int
							 | 
						||
| 
								 | 
							
								destroy_node(ptr_hash_node *node, void *closure)
							 | 
						||
| 
								 | 
							
								{ PL_free(node);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								destroy_ptr_hash(ptr_hash *hash)
							 | 
						||
| 
								 | 
							
								{ for_ptr_hash(hash, destroy_node, NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  PL_free(hash->chains);
							 | 
						||
| 
								 | 
							
								  PL_free(hash);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int
							 | 
						||
| 
								 | 
							
								add_ptr_hash(ptr_hash *hash, void *value)
							 | 
						||
| 
								 | 
							
								{ int key = HASHKEY(hash, value);
							 | 
						||
| 
								 | 
							
								  ptr_hash_node *node;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for(node = hash->chains[key]; node; node = node->next)
							 | 
						||
| 
								 | 
							
								  { if ( node->value == value )
							 | 
						||
| 
								 | 
							
								      return FALSE;			/* already in hash */
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  node = PL_malloc(sizeof(*node));
							 | 
						||
| 
								 | 
							
								  node->value = value;
							 | 
						||
| 
								 | 
							
								  node->next = hash->chains[key];
							 | 
						||
| 
								 | 
							
								  hash->chains[key] = node;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int
							 | 
						||
| 
								 | 
							
								for_ptr_hash(ptr_hash *hash,
							 | 
						||
| 
								 | 
							
									     int (*func)(ptr_hash_node *node, void *closure),
							 | 
						||
| 
								 | 
							
									     void *closure)
							 | 
						||
| 
								 | 
							
								{ int key;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for(key=0; key < hash->entries; key++)
							 | 
						||
| 
								 | 
							
								  { ptr_hash_node *node;
							 | 
						||
| 
								 | 
							
								    ptr_hash_node *next;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for(node=hash->chains[key]; node; node = next)
							 | 
						||
| 
								 | 
							
								    { next = node->next;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if ( !func(node, closure) )
							 | 
						||
| 
								 | 
							
									return FALSE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return TRUE;
							 | 
						||
| 
								 | 
							
								}
							 |