placed basic hash macros in qse/hash.h

This commit is contained in:
hyung-hwan 2019-03-05 08:21:01 +00:00
parent 1aea9f4492
commit bda9213f86
7 changed files with 131 additions and 84 deletions

View File

@ -31,6 +31,7 @@
/// Privides the Hashable interface class. /// Privides the Hashable interface class.
#include <qse/Types.hpp> #include <qse/Types.hpp>
#include <qse/hash.h>
///////////////////////////////// /////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
@ -51,13 +52,7 @@ public:
static qse_size_t getHashCode (qse_size_t init, const qse_mchar_t* str) static qse_size_t getHashCode (qse_size_t init, const qse_mchar_t* str)
{ {
qse_size_t n = init; qse_size_t n = init;
QSE_HASH_MORE_MBS(n, str);
while (*str != QSE_MT('\0'))
{
n = n * 31 + *((qse_uint8_t*)str);
str++;
}
return n; return n;
} }
@ -69,15 +64,7 @@ public:
static qse_size_t getHashCode (qse_size_t init, const qse_wchar_t* str) static qse_size_t getHashCode (qse_size_t init, const qse_wchar_t* str)
{ {
qse_size_t n = init; qse_size_t n = init;
QSE_HASH_MORE_WCS(n, str);
while (*str != QSE_WT('\0'))
{
const qse_uint8_t* p = (const qse_uint8_t*)str;
for (qse_size_t i = 0; i < QSE_SIZEOF(*str); i++)
n = n * 31 + *p++;
str++;
}
return n; return n;
} }
@ -89,26 +76,7 @@ public:
static qse_size_t getHashCode (qse_size_t init, const void* data, qse_size_t size) static qse_size_t getHashCode (qse_size_t init, const void* data, qse_size_t size)
{ {
qse_size_t n = init; qse_size_t n = init;
const qse_uint8_t* p = (const qse_uint8_t*)data; QSE_HASH_BYTES (n, data, size);
/*
for (qse_size_t i = 0; i < size; i++) {
n <<= 1;
n += *p++;
}
*/
for (qse_size_t i = 0; i < size; i++) n = n * 31 + *p++;
/*
for (qse_size_t i = 0; i < size; i++) {
n = (n << 4) + *p++;
//qse_size_t g = n & 0xF0000000U;
qse_size_t g = n & ((qse_size_t)0xF << (qse_sizeof(qse_size_t) * 8 - 4));
n &= ~g;
}
*/
return n; return n;
} }

112
qse/include/qse/hash.h Normal file
View File

@ -0,0 +1,112 @@
/*
* $Id: types.h 560 2011-09-06 14:18:36Z hyunghwan.chung $
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_HASH_H_
#define _QSE_HASH_H_
#include <qse/types.h>
#include <qse/macros.h>
#if MOO_SIZEOF_SIZE_T == 4
# define QSE_HASH_FNV_MAGIC_INIT (0x811c9dc5)
# define QSE_HASH_FNV_MAGIC_PRIME (0x01000193)
#elif MOO_SIZEOF_SIZE_T == 8
# define QSE_HASH_FNV_MAGIC_INIT (0xCBF29CE484222325)
# define QSE_HASH_FNV_MAGIC_PRIME (0x100000001B3)
#elif MOO_SIZEOF_SIZE_T == 16
# define QSE_HASH_FNV_MAGIC_INIT (0x6C62272E07BB014262B821756295C58D)
# define QSE_HASH_FNV_MAGIC_PRIME (0x1000000000000000000013B)
#endif
#if defined(QSE_HASH_FNV_MAGIC_INIT)
/* FNV-1 hash */
# define QSE_HASH_VALUE(hv,v) (((hv) ^ (v)) * QSE_HASH_FNV_MAGIC_PRIME)
# define QSE_HASH_VALUES(hv, ptr, len, type) do { \
hv = QSE_HASH_FNV_MAGIC_INIT; \
QSE_HASH_MORE_VALUES (hv, ptr, len, type); \
} while(0)
# define QSE_HASH_MORE_VALUES(hv, ptr, len, type) do { \
type* p = (type*)(ptr); \
type* q = (type*)p + (len); \
while (p < q) { hv = QSE_HASH_VALUE(hv, *p); p++; } \
} while(0)
# define QSE_HASH_VS(hv, ptr, type) do { \
hv = QSE_HASH_FNV_MAGIC_INIT; \
QSE_HASH_MORE_VALUES (hv, ptr, type); \
} while(0)
# define QSE_HASH_MORE_VS(hv, ptr, type) do { \
type* p = (type*)(ptr); \
while (*p) { hv = QSE_HASH_VALUE(hv, *p); p++; } \
} while(0)
#else
/* SDBM hash */
# define QSE_HASH_VALUE(hv,v) (((hv) << 6) + ((hv) << 16) - (hv) + (v))
# define QSE_HASH_VALUES(hv, ptr, len, type) do { \
hv = 0; \
QSE_HASH_MORE_VALUES (hv, ptr, len, type); \
} while(0)
# define QSE_HASH_MORE_VALUES(hv, ptr, len, type) do { \
type* p = (type*)(ptr); \
type* q = (type*)p + (len); \
while (p < q) { hv = QSE_HASH_VALUE(hv, *p); p++; } \
} while(0)
# define QSE_HASH_VS(hv, ptr, type) do { \
hv = 0; \
QSE_HASH_MORE_VS (hv, ptr, type); \
} while(0)
# define QSE_HASH_MORE_VS(hv, ptr, type) do { \
type* p = (type*)(ptr); \
while (*p) { hv = QSE_HASH_VALUE(hv, *p); p++; } \
} while(0)
#endif
#define QSE_HASH_BYTES(hv, ptr, len) QSE_HASH_VALUES(hv, ptr, len, const qse_uint8_t)
#define QSE_HASH_MORE_BYTES(hv, ptr, len) QSE_HASH_MORE_VALUES(hv, ptr, len, const qse_uint8_t)
#define QSE_HASH_MCHARS(hv, ptr, len) QSE_HASH_VALUES(hv, ptr, len, const qse_mchar_t)
#define QSE_HASH_MORE_MCHARS(hv, ptr, len) QSE_HASH_MORE_VALUES(hv, ptr, len, const qse_mchar_t)
#define QSE_HASH_WCHARS(hv, ptr, len) QSE_HASH_VALUES(hv, ptr, len, const qse_wchar_t)
#define QSE_HASH_MORE_WCHARS(hv, ptr, len) QSE_HASH_MORE_VALUES(hv, ptr, len, const qse_wchar_t)
#define QSE_HASH_MBS(hv, ptr) QSE_HASH_VS(hv, ptr, const qse_mchar_t)
#define QSE_HASH_MORE_MBS(hv, ptr) QSE_HASH_MORE_VS(hv, ptr, const qse_mchar_t)
#define QSE_HASH_WCS(hv, ptr) QSE_HASH_VS(hv, ptr, const qse_wchar_t)
#define QSE_HASH_MORE_WCS(hv, ptr) QSE_HASH_MORE_VS(hv, ptr, const qse_wchar_t)
#endif

View File

@ -26,6 +26,7 @@
#include "awk-prv.h" #include "awk-prv.h"
#include <qse/cmn/mbwc.h> #include <qse/cmn/mbwc.h>
#include <qse/hash.h>
#ifdef DEBUG_VAL #ifdef DEBUG_VAL
#include <qse/cmn/sio.h> #include <qse/cmn/sio.h>
@ -1696,17 +1697,10 @@ int qse_awk_rtx_strtonum (
return 0; /* int */ return 0; /* int */
} }
static qse_awk_uint_t hash (qse_uint8_t* ptr, qse_size_t len) static QSE_INLINE qse_awk_uint_t hash (qse_uint8_t* ptr, qse_size_t len)
{ {
/* qse_awk_uint_t h;
qse_awk_uint_t h = 5381; QSE_HASH_BYTES (h, ptr, len);
while (len > 0) h = ((h << 5) + h) + ptr[--len];
return h;
*/
/* SDBM hash */
qse_awk_uint_t h = 0;
while (len > 0) h = (h << 6) + (h << 16) - h + ptr[--len];
return h; return h;
} }
@ -1725,18 +1719,18 @@ qse_awk_int_t qse_awk_rtx_hashval (qse_awk_rtx_t* rtx, qse_awk_val_t* v)
{ {
qse_awk_int_t tmp = QSE_AWK_RTX_GETINTFROMVAL (rtx, v); qse_awk_int_t tmp = QSE_AWK_RTX_GETINTFROMVAL (rtx, v);
/*hv = ((qse_awk_val_int_t*)v)->val;*/ /*hv = ((qse_awk_val_int_t*)v)->val;*/
hv = (qse_awk_int_t)hash ((qse_uint8_t*)&tmp, QSE_SIZEOF(tmp)); hv = (qse_awk_int_t)hash((qse_uint8_t*)&tmp, QSE_SIZEOF(tmp));
break; break;
} }
case QSE_AWK_VAL_FLT: case QSE_AWK_VAL_FLT:
hv = (qse_awk_int_t)hash ( hv = (qse_awk_int_t)hash(
(qse_uint8_t*)&((qse_awk_val_flt_t*)v)->val, (qse_uint8_t*)&((qse_awk_val_flt_t*)v)->val,
QSE_SIZEOF(((qse_awk_val_flt_t*)v)->val)); QSE_SIZEOF(((qse_awk_val_flt_t*)v)->val));
break; break;
case QSE_AWK_VAL_STR: case QSE_AWK_VAL_STR:
hv = (qse_awk_int_t)hash ( hv = (qse_awk_int_t)hash(
(qse_uint8_t*)((qse_awk_val_str_t*)v)->val.ptr, (qse_uint8_t*)((qse_awk_val_str_t*)v)->val.ptr,
((qse_awk_val_str_t*)v)->val.len * QSE_SIZEOF(qse_char_t)); ((qse_awk_val_str_t*)v)->val.len * QSE_SIZEOF(qse_char_t));
break; break;

View File

@ -25,6 +25,7 @@
*/ */
#include <qse/cmn/htb.h> #include <qse/cmn/htb.h>
#include <qse/hash.h>
#include "mem-prv.h" #include "mem-prv.h"
@ -735,25 +736,8 @@ pair_t* qse_htb_getnextpair (htb_t* htb, pair_t* pair, size_t* buckno)
size_t qse_htb_dflhash (const htb_t* htb, const void* kptr, size_t klen) size_t qse_htb_dflhash (const htb_t* htb, const void* kptr, size_t klen)
{ {
const byte_t* p = (const byte_t*)kptr; size_t h;
const byte_t* bound = p + klen; QSE_HASH_BYTES (h, kptr, klen);
#if 0
/*size_t h = 2166136261;*/
/*size_t h = 0;*/
size_t h = 5381;
while (p < bound)
{
/*h = (h * 16777619) ^ *p++;*/
/*h = h * 31 + *p++;*/
h = ((h << 5) + h) + *p++;
}
#else
/* SDBM hash */
size_t h = 0;
while (p < bound) h = (h << 6) + (h << 16) - h + *p++;
#endif
return h ; return h ;
} }

View File

@ -281,10 +281,10 @@ qse_htl_t* qse_htl_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, int keysize)
{ {
qse_htl_t* htl; qse_htl_t* htl;
htl = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_htl_t) + xtnsize); htl = QSE_MMGR_ALLOC(mmgr, QSE_SIZEOF(qse_htl_t) + xtnsize);
if (htl == QSE_NULL) return QSE_NULL; if (htl == QSE_NULL) return QSE_NULL;
if (qse_htl_init (htl, mmgr, keysize) <= -1) if (qse_htl_init(htl, mmgr, keysize) <= -1)
{ {
QSE_MMGR_FREE (mmgr, htl); QSE_MMGR_FREE (mmgr, htl);
return QSE_NULL; return QSE_NULL;

View File

@ -1,4 +1,5 @@
#include <qse/cmn/oht.h> #include <qse/cmn/oht.h>
#include <qse/hash.h>
#include "mem-prv.h" #include "mem-prv.h"
#define DATA_PTR(oht,index) \ #define DATA_PTR(oht,index) \
@ -6,19 +7,8 @@
static QSE_INLINE_ALWAYS qse_size_t default_hasher (qse_oht_t* oht, const void* data) static QSE_INLINE_ALWAYS qse_size_t default_hasher (qse_oht_t* oht, const void* data)
{ {
const qse_byte_t* p = (const qse_byte_t*)data; qse_size_t h;
const qse_byte_t* bound = p + oht->scale; QSE_HASH_BYTES (h, data, oht->scale);
#if 0
// DJB2 hash
qse_size_t h = 5381;
while (p < bound) h = ((h << 5) + h) + *p++;
#else
// SDBM hash
qse_size_t h = 0;
while (p < bound) h = (h << 6) + (h << 16) - h + *p++;
#endif
return h ; return h ;
} }

View File

@ -254,7 +254,6 @@ static qse_uint32_t dict_attr_value_hash (qse_htl_t* htl, const void* data)
{ {
const qse_raddic_attr_t* v = (const qse_raddic_attr_t*)data; const qse_raddic_attr_t* v = (const qse_raddic_attr_t*)data;
qse_uint32_t hv; qse_uint32_t hv;
hv = qse_genhash32(&v->vendor, QSE_SIZEOF(v->vendor)); hv = qse_genhash32(&v->vendor, QSE_SIZEOF(v->vendor));
return qse_genhash32_update(&v->attr, QSE_SIZEOF(v->attr), hv); return qse_genhash32_update(&v->attr, QSE_SIZEOF(v->attr), hv);
} }