SIS
Symmetric Index Structures
/Users/dbr/ma/src/bas/lml/hash.c
Go to the documentation of this file.
00001 #include "base.h"
00002 
00003 #define hashStep (107)
00004 
00005 Hash * HashInit( void * set,
00006                  UINT (*GetIndexOfNewObject)( void *, const void * ),
00007                  UINT (*GetFirstIndex)( void * ),
00008                  UINT (*GetNextIndex)( void *, UINT ),
00009                  boolean (*Equals)( void *, const void *, UINT ),
00010                  UINT (*HashCode)( void *, const void *, UINT ),
00011                  UINT (*HashCode2)( void *, UINT, UINT ) ){
00012     Hash * hash;
00013     UINT i;
00014 
00015     hash = (Hash *)Malloc( 1, sizeof(Hash) );
00016     hash->hashSize = 63;
00017     hash->hash = (UINT *)Malloc( hash->hashSize, sizeof(UINT) );
00018     for( i = 0; i < hash->hashSize; i++ ){
00019         hash->hash[i] = NO;
00020     }
00021     hash->objectsStored = 0;
00022     hash->set = set;
00023     hash->GetIndexOfNewObject = GetIndexOfNewObject;
00024     hash->GetFirstIndex = GetFirstIndex;
00025     hash->GetNextIndex = GetNextIndex;
00026     hash->Equals = Equals;
00027     hash->HashCode = HashCode;
00028     hash->HashCode2 = HashCode2;
00029     return hash;
00030 }
00031 
00032 UINT HashAdd( Hash * hash, const void * object ){
00033     UINT i, ret;
00034 
00035     for( i = hash->HashCode(hash->set, object, hash->hashSize); hash->hash[i] != NO; i = (i + hashStep) % hash->hashSize ){
00036         if( hash->Equals( hash->set, object, hash->hash[i] ) ){
00037             return hash->hash[i];
00038         }
00039     }
00040     hash->hash[i] = ret = hash->GetIndexOfNewObject( hash->set, object );
00041     hash->objectsStored++;
00042     if( ((U64)(10))*((U64)(hash->objectsStored)) > ((U64)(9))*((U64)(hash->hashSize)) ){
00043         UINT index;
00044 
00045         hash->hashSize = 2*hash->hashSize + 1;
00046 
00047         hash->hash = Realloc( hash->hash, hash->hashSize, sizeof(UINT) );
00048 
00049         for( i = 0; i < hash->hashSize; i++ ){
00050             hash->hash[i] = NO;
00051         }
00052         for( index = hash->GetFirstIndex( hash->set ); index != NO; index = hash->GetNextIndex( hash->set, index ) ){
00053             for( i = hash->HashCode2(hash->set, index, hash->hashSize); hash->hash[i] != NO; i = (i + hashStep) % hash->hashSize );
00054             hash->hash[i] = index;
00055         }
00056     }
00057     return ret;
00058 }
00059 
00060 UINT HashGetIndex( Hash * hash, const void * object ){
00061     UINT i;
00062     i = hash->HashCode(hash->set, object, hash->hashSize);
00063     for( ; hash->hash[i] != NO; i = (i + hashStep) % hash->hashSize ){
00064         if( hash->Equals( hash->set, object, hash->hash[i] ) ){
00065             return hash->hash[i];
00066         }
00067     }
00068     return NO;
00069 }
00070 
00071 void HashFree( Hash * hash ){
00072     Free( hash->hash );
00073     Free( hash );
00074 }
00075 
00076 void HashReset( Hash * hash ){
00077     UINT i;
00078 
00079     for( i = 0; i < hash->hashSize; i++ ){
00080         hash->hash[i] = NO;
00081     }
00082     hash->objectsStored = 0;
00083 }