150 lines
5.1 KiB
C
150 lines
5.1 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2001, 2010 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
#ifndef HASHTAB_COMMON_H
|
||
|
#define HASHTAB_COMMON_H
|
||
|
|
||
|
#define HASHTAB_COMPACT FALSE
|
||
|
#define HASHTAB_NO_COMPACT TRUE
|
||
|
|
||
|
#define HASHTAB_SPARE_TABLE FALSE
|
||
|
#define HASHTAB_NO_SPARE_TABLE TRUE
|
||
|
|
||
|
#define HT_VALUE_DUMMY ((void *) 1L)
|
||
|
/* It is required not to have 0 or -1 for this macro.
|
||
|
* This is passed when hashtable callers want to use hash table just for the keys.
|
||
|
* Say, database code wants to create a list of blocks being read for a transactions.
|
||
|
* There is no corresponding value associated. For that case HT_VALUE_DUMMY will be passed as "value". */
|
||
|
#define HT_DELETED_ENTRY ((void *) -1L)
|
||
|
/* Note: We may need to change the above during 64-bit port */
|
||
|
#define HTENT_MARK_DELETED(tabent) (HT_DELETED_ENTRY == (tabent)->value)
|
||
|
#define HT_LOAD_FACTOR 50
|
||
|
#define HT_REHASH_FACTOR (HT_LOAD_FACTOR/2)
|
||
|
#define HT_REHASH_TABLE_SIZE(table) MIN(table->size, table->count * 4)
|
||
|
#define INSERT_HTENT(table, tabent, hkey, value) \
|
||
|
{ \
|
||
|
if (HT_DELETED_ENTRY == (tabent)->value) \
|
||
|
(table)->del_count--; \
|
||
|
(tabent)->key = *hkey; \
|
||
|
(tabent)->value = value; \
|
||
|
(table)->count++; \
|
||
|
}
|
||
|
|
||
|
#define COMPACT_NEEDED(table) ((!(table)->dont_compact) && (((table)->del_count > (table)->cmp_trigger_size) || \
|
||
|
(((table)->initial_size < (table)->size ) && ((table)->count < ((table)->cmp_trigger_size / 2)))))
|
||
|
|
||
|
/*
|
||
|
* This macro is used by callers outside of the hash table implementation to indicate
|
||
|
* whether they will request the free of the hash table base at a later point in time or
|
||
|
* if it should be released by the hash table implementation during an expansion/compaction.
|
||
|
* They must call FREE_BASE_HASHTAB() later to release the base otherwise the memory
|
||
|
* will be leaked.
|
||
|
*/
|
||
|
#define DEFER_BASE_REL_HASHTAB(table, deferit) \
|
||
|
{ \
|
||
|
(table)->defer_base_release = deferit; \
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This macro is used by callers outside of the hash table implementation to indicate
|
||
|
* that they are no longer using the hash table base. This function only provides a "hint" to the
|
||
|
* hash table implementation, i.e., the base can now be freed when appropriate. This can
|
||
|
* mean when this function is called if we are not keeping spare bases or at a potentially
|
||
|
* much later time if we are using a spare base.
|
||
|
*/
|
||
|
#define FREE_BASE_HASHTAB(table, base) \
|
||
|
{ \
|
||
|
if ((table)->dont_keep_spare_table) \
|
||
|
free(base); \
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Different Hash Computation Macros for Strings:
|
||
|
All these were experminted and result is given in the design document of V5.0-000 longname project.
|
||
|
For now we decided to use ELF_HASH.
|
||
|
Do not remove the commented out section below which has all the hash functions.
|
||
|
We can remove them when we are certain that ELF_HASH is the best choice for us.
|
||
|
*/
|
||
|
|
||
|
#define STR_HASH ELF_HASH
|
||
|
#define ELF_HASH(sptr, len, hash, init_hashval) \
|
||
|
{ \
|
||
|
uint4 tempint; \
|
||
|
char *curr, *top; \
|
||
|
uint4 hcode; \
|
||
|
for (hcode = init_hashval, curr = sptr, top = sptr + len; curr < top; curr++) \
|
||
|
{ \
|
||
|
hcode = (hcode << 4) + *curr; \
|
||
|
if (tempint = (hcode & 0xF0000000)) \
|
||
|
hcode ^= tempint >> 24; \
|
||
|
hcode &= ~tempint; \
|
||
|
} \
|
||
|
hash = hcode; \
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
#define CHAR_BITS 8
|
||
|
#define BITS_IN_int (SIZEOF(int) * CHAR_BITS)
|
||
|
#define THREE_QUARTERS (BITS_IN_int * 3 / 4)
|
||
|
#define ONE_EIGHTH (BITS_IN_int / 8)
|
||
|
#define HIGH_BITS (~((unsigned int)(~0) >> ONE_EIGHTH ))
|
||
|
#define PJW_HASH(sptr, len, hash, init_hashval) \
|
||
|
{ \
|
||
|
uint4 tempint; \
|
||
|
char *curr, *top; \
|
||
|
hash = init_hashval; \
|
||
|
for (curr = sptr, top = sptr + len; curr < top; curr++) \
|
||
|
{ \
|
||
|
hash = ( hash << ONE_EIGHTH ) + *curr; \
|
||
|
if ((tempint = hash & HIGH_BITS ) != 0 ) \
|
||
|
hash = ( hash ^ ( tempint >> THREE_QUARTERS )) & ~HIGH_BITS;\
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
|
||
|
#define MISC1_HASH(sptr, len, hash, init_hashval) \
|
||
|
{ \
|
||
|
char *curr; \
|
||
|
curr = sptr; \
|
||
|
int indx; \
|
||
|
hash = init_hashval; \
|
||
|
for (indx = 0; indx < len; indx++, curr++) \
|
||
|
hash += (*curr * (len - indx)); \
|
||
|
}
|
||
|
#define MISC2_HASH(sptr, len, hash, init_hashval) \
|
||
|
|
||
|
{ \
|
||
|
char *curr; \
|
||
|
curr = sptr; \
|
||
|
int indx; \
|
||
|
hash = init_hashval; \
|
||
|
for (indx = 0; indx < len; indx++, curr++) \
|
||
|
hash = hash*31 + *curr; \
|
||
|
}
|
||
|
|
||
|
#define CURR_HASH(sptr, len, hash, init_hashval) \
|
||
|
{ \
|
||
|
char *ptr, tchar[MAXLEN]; \
|
||
|
int indx; \
|
||
|
uint4 temp1 = 0; \
|
||
|
uint4 temp2 = 0; \
|
||
|
memset(tchar, 0, MAXLEN); \
|
||
|
memcpy(tchar, sptr, len); \
|
||
|
ptr = &tchar[0]; \
|
||
|
for ( indx = 0; indx < 4; indx++, ptr++) \
|
||
|
temp1 = temp1 * 256 + *ptr ; \
|
||
|
for ( ; indx < 8; indx++, ptr++) \
|
||
|
temp2 = temp2 * 256 + *ptr ; \
|
||
|
hash = (temp1 << 1) ^ (temp2) ; \
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
#endif
|