📄 orlhash.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "orllevel.h"
#include "orlhash.h"
#define _HashAlloc( a, b ) a->funcs->alloc( b )
#define _HashFree( a, b ) a->funcs->free( b )
#define _HashCompare( a, b, c ) a->compare( b, c )
int ORLNumberCmp( orl_hash_value n1, orl_hash_value n2 )
{
return( n1 - n2 );
}
static orl_hash_value orlStringEncode( const char *string )
{
const char *p;
orl_hash_value g, h;
h = 0;
for( p = (const char *) string; *p; p++ ) {
h = ( h << 4 ) + *p;
if( (g = h & 0xf0000000) ) {
h = h ^ ( g >> 24 );
h = h ^ g;
}
}
return( h );
}
static orl_hash_value orlHash( orl_hash_table hash_table, orl_hash_value key )
{
return( key % hash_table->size );
}
orl_return ORLHashTableInsert( orl_hash_table hash_table, orl_hash_value key, orl_hash_data data )
{
orl_hash_value hash_value = 0;
orl_hash_struct * hash_ptr;
orl_hash_struct * new_element;
orl_hash_data_struct * last;
orl_hash_data_struct * new_data_element;
new_data_element = (orl_hash_data_struct *) _HashAlloc( hash_table, sizeof( orl_hash_data_struct ) );
if( !new_data_element ) return( ORL_OUT_OF_MEMORY );
new_data_element->data = data;
new_data_element->next = NULL;
switch( hash_table->type ) {
case ORL_HASH_STRING:
hash_value = orlHash( hash_table, orlStringEncode( (char *) key ) );
break;
case ORL_HASH_NUMBER:
hash_value = orlHash( hash_table, key );
break;
}
hash_ptr = hash_table->table[hash_value];
while( hash_ptr != NULL ) {
if( !( _HashCompare( hash_table, hash_ptr->key, key ) ) ) {
last = hash_ptr->data_struct;
while( last->next ) {
last = last->next;
}
last->next = new_data_element;
return( ORL_OKAY );
}
hash_ptr = hash_ptr->next;
}
new_element = (orl_hash_struct *) _HashAlloc( hash_table, sizeof( orl_hash_struct ) );
if( !new_element ) return( ORL_OUT_OF_MEMORY );
new_element->key = key;
new_element->data_struct = new_data_element;
new_element->next = hash_table->table[hash_value];
hash_table->table[hash_value] = new_element;
return( ORL_OKAY );
}
orl_hash_data_struct *ORLHashTableQuery( orl_hash_table hash_table, orl_hash_value key )
{
orl_hash_value hash_value = 0;
orl_hash_struct * hash_ptr;
switch( hash_table->type ) {
case ORL_HASH_STRING:
hash_value = orlHash( hash_table, orlStringEncode( (char *) key ) );
break;
case ORL_HASH_NUMBER:
hash_value = orlHash( hash_table, key );
break;
}
hash_ptr = hash_table->table[hash_value];
while( hash_ptr != NULL ) {
if( !( _HashCompare( hash_table, hash_ptr->key, key ) ) ) return( hash_ptr->data_struct );
hash_ptr = hash_ptr->next;
}
return( NULL );
}
orl_hash_table ORLHashTableCreate( orl_funcs * funcs, orl_hash_table_size size, orl_hash_table_type type, orl_hash_comparison_func compare )
{
orl_hash_table hash_table;
int loop;
hash_table = (orl_hash_table) funcs->alloc( sizeof( orl_hash_table_struct ) );
if( !hash_table) return( NULL );
hash_table->table = (orl_hash_struct **) funcs->alloc( size * sizeof( orl_hash_struct * ) );
if( !(hash_table->table) ) {
funcs->free( hash_table );
return( NULL );
}
hash_table->size = size;
hash_table->type = type;
hash_table->funcs = funcs;
hash_table->compare = compare;
for( loop = 0; loop < size; loop ++ ) {
hash_table->table[loop] = NULL;
}
return( hash_table );
}
void ORLHashTableFree( orl_hash_table hash_table )
{
int loop;
orl_hash_struct * hash_ptr;
orl_hash_struct * last_hash_ptr;
orl_hash_data_struct * data_ptr;
orl_hash_data_struct * last_data_ptr;
for( loop = 0; loop < hash_table->size; loop ++ )
{
hash_ptr = hash_table->table[loop];
while( hash_ptr != NULL ) {
data_ptr = hash_ptr->data_struct;
while( data_ptr != NULL ) {
last_data_ptr = data_ptr;
data_ptr = data_ptr->next;
_HashFree( hash_table, last_data_ptr );
}
last_hash_ptr = hash_ptr;
hash_ptr = hash_ptr->next;
_HashFree( hash_table, last_hash_ptr );
}
}
_HashFree( hash_table, hash_table->table );
_HashFree( hash_table, hash_table );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -