/* * $Header: /home/barad-dur/vision/forsyth/schenney/sced-0.94/c/RCS/hash.c,v 1.0 1997/05/06 20:30:22 schenney Exp $ * * $Log: hash.c,v $ * Revision 1.0 1997/05/06 20:30:22 schenney * Initial revision * */ #define PATCHLEVEL 0 /* ** ScEd: A Constraint Based Scene Editor. ** Copyright (C) 1994-1998 Stephen Chenney (schenney@cs.berkeley.edu) ** ** 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. */ /* ** sced: A Constraint Based Object Scene Editor ** ** hash.c: Hash table functions for storing pointer mappings. */ #include #include #define HASH_PRIME 197 #define HASH_SIZE ( 197 / 2 + 1 ) #define HASH_INDEX ( ( key % HASH_PRIME ) >> 1 ) HashTable Hash_New_Table() { HashTable new_hash = New(HashEntryPtr, HASH_SIZE); int i; for ( i = 0 ; i < HASH_SIZE ; i++ ) new_hash[i] = NULL; return new_hash; } void Hash_Insert(HashTable table, unsigned long key, void *value) { int index = HASH_INDEX; HashEntryPtr entry = table[index]; HashEntryPtr new_entry; while ( entry ) { if ( entry->key == key ) return; entry = entry->next; } new_entry = New(HashEntry, 1); new_entry->next = table[index]; new_entry->key = key; new_entry->value = value; table[index] = new_entry; } void* Hash_Get_Value(HashTable table, unsigned long key) { HashEntryPtr entry = table[HASH_INDEX]; while ( entry && entry->key != key ) entry = entry->next; if ( entry ) return entry->value; else return (void*)-1; } void Hash_Free_List(HashEntryPtr victim) { if ( victim ) { Hash_Free_List(victim->next); free(victim); } } void Hash_Clear(HashTable table) { int i; for ( i = 0 ; i < HASH_SIZE ; i++ ) if ( table[i] ) Hash_Free_List(table[i]); } void Hash_Free(HashTable table) { Hash_Clear(table); free(table); } void* Hash_Delete(HashTable table, unsigned long key) { HashEntryPtr entry = table[HASH_INDEX]; void *val; if ( ! entry ) return NULL; if ( entry->key == key ) { table[HASH_INDEX] = entry->next; val = entry->value; free(entry); return val; } while ( entry->next && entry->next->key != key ) entry = entry->next; if ( entry->next && entry->next->key == key ) { HashEntryPtr temp = entry->next; val = entry->next->value; entry->next = entry->next->next; free(temp); return val; } return NULL; } void* Hash_Traverse(HashTable table, Boolean starting) { static HashEntryPtr next; static int index; void *result; if ( starting ) { for ( index = 0 ; index < HASH_SIZE && ! table[index] ; index++ ); if ( index < HASH_SIZE ) next = table[index]; else next = NULL; } result = next ? next->value : NULL; if ( next && next->next ) next = next->next; else { for ( index++ ; index < HASH_SIZE && ! table[index] ; index++ ); if ( index < HASH_SIZE ) next = table[index]; else next = NULL; } return result; }