[TD-4614]<feature> add equal func to hashTable
This commit is contained in:
parent
934265ffac
commit
01f52f01fa
|
@ -153,9 +153,9 @@ bool serializeExprListToVariant(SArray* pList, tVariant **dst, int16_t colType)
|
|||
if (!pList || pList->size <= 0) {
|
||||
return ret;
|
||||
}
|
||||
if (colType == TSDB_DATA_TYPE_DOUBLE || colType == TSDB_DATA_TYPE_FLOAT) {
|
||||
return ret;
|
||||
}
|
||||
//if (colType == TSDB_DATA_TYPE_DOUBLE || colType == TSDB_DATA_TYPE_FLOAT) {
|
||||
// return ret;
|
||||
//}
|
||||
|
||||
tSqlExprItem* item = (tSqlExprItem *)taosArrayGet(pList, 0);
|
||||
int32_t firstTokenType = item->pNode->token.type;
|
||||
|
|
|
@ -470,6 +470,9 @@ void buildFilterSetFromBinary(void **q, const char *buf, int32_t len) {
|
|||
SBufferReader br = tbufInitReader(buf, len, false);
|
||||
uint32_t type = tbufReadUint32(&br);
|
||||
SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(type), true, false);
|
||||
|
||||
taosHashSetEqualFp(pObj, taosGetDefaultEqualFunction(type));
|
||||
|
||||
int dummy = -1;
|
||||
int32_t sz = tbufReadInt32(&br);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
|
|
|
@ -262,7 +262,7 @@ bool inOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxv
|
|||
return NULL != taosHashGet((SHashObj *)pFilter->q, (char *)&minv, sizeof(minv));
|
||||
}
|
||||
return true;
|
||||
} else if (type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_DOUBLE) {
|
||||
} else if (type == TSDB_DATA_TYPE_DOUBLE || type == TSDB_DATA_TYPE_FLOAT) {
|
||||
double v;
|
||||
GET_TYPED_DATA(v, double, type, minval);
|
||||
return NULL != taosHashGet((SHashObj *)pFilter->q, (char *)&v, sizeof(v));
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef struct SHashObj {
|
|||
size_t size; // number of elements in hash table
|
||||
_hash_fn_t hashFp; // hash function
|
||||
_hash_free_fn_t freeFp; // hash node free callback function
|
||||
_equal_fn_t equalFp; // equal function
|
||||
|
||||
SRWLatch lock; // read-write spin lock
|
||||
SHashLockTypeE type; // lock type
|
||||
|
@ -78,6 +79,15 @@ typedef struct SHashObj {
|
|||
*/
|
||||
SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTypeE type);
|
||||
|
||||
|
||||
/**
|
||||
* set equal func of the hash table
|
||||
* @param pHashObj
|
||||
* @param equalFp
|
||||
* @return
|
||||
*/
|
||||
void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp);
|
||||
|
||||
/**
|
||||
* return the size of hash table
|
||||
* @param pHashObj
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
typedef uint32_t (*_hash_fn_t)(const char *, uint32_t);
|
||||
|
||||
typedef int32_t (*_equal_fn_t)(const void *a, const void *b, size_t sz);
|
||||
|
||||
/**
|
||||
* murmur hash algorithm
|
||||
* @key usually string
|
||||
|
@ -36,9 +38,14 @@ uint32_t MurmurHash3_32(const char *key, uint32_t len);
|
|||
* @return
|
||||
*/
|
||||
uint32_t taosIntHash_32(const char *key, uint32_t len);
|
||||
|
||||
uint32_t taosIntHash_64(const char *key, uint32_t len);
|
||||
|
||||
|
||||
int32_t taosFloatEqual(const void *a, const void *b, size_t sz);
|
||||
int32_t taosDoubleEqual(const void *a,const void *b, size_t sz);
|
||||
|
||||
_hash_fn_t taosGetDefaultHashFunction(int32_t type);
|
||||
|
||||
_equal_fn_t taosGetDefaultEqualFunction(int32_t type);
|
||||
|
||||
#endif //TDENGINE_HASHUTIL_H
|
||||
|
|
|
@ -73,10 +73,10 @@ static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
|
|||
return i;
|
||||
}
|
||||
|
||||
static FORCE_INLINE SHashNode *doSearchInEntryList(SHashEntry *pe, const void *key, size_t keyLen, uint32_t hashVal) {
|
||||
static FORCE_INLINE SHashNode *doSearchInEntryList(SHashObj *pHashObj, SHashEntry *pe, const void *key, size_t keyLen, uint32_t hashVal) {
|
||||
SHashNode *pNode = pe->next;
|
||||
while (pNode) {
|
||||
if ((pNode->keyLen == keyLen) && (memcmp(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && pNode->removed == 0) {
|
||||
if ((pNode->keyLen == keyLen) && ((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && pNode->removed == 0) {
|
||||
assert(pNode->hashVal == hashVal);
|
||||
break;
|
||||
}
|
||||
|
@ -165,8 +165,8 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTyp
|
|||
// the max slots is not defined by user
|
||||
pHashObj->capacity = taosHashCapacity((int32_t)capacity);
|
||||
assert((pHashObj->capacity & (pHashObj->capacity - 1)) == 0);
|
||||
|
||||
pHashObj->hashFp = fn;
|
||||
pHashObj->equalFp = memcmp;
|
||||
pHashObj->hashFp = fn;
|
||||
pHashObj->type = type;
|
||||
pHashObj->enableUpdate = update;
|
||||
|
||||
|
@ -189,6 +189,12 @@ SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTyp
|
|||
return pHashObj;
|
||||
}
|
||||
|
||||
void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp) {
|
||||
if (pHashObj != NULL && fp != NULL) {
|
||||
pHashObj->equalFp = fp;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t taosHashGetSize(const SHashObj *pHashObj) { return (int32_t)((pHashObj == NULL) ? 0 : pHashObj->size); }
|
||||
|
||||
int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *data, size_t size) {
|
||||
|
@ -223,7 +229,7 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
|
|||
|
||||
SHashNode* prev = NULL;
|
||||
while (pNode) {
|
||||
if ((pNode->keyLen == keyLen) && (memcmp(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && pNode->removed == 0) {
|
||||
if ((pNode->keyLen == keyLen) && ((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && pNode->removed == 0) {
|
||||
assert(pNode->hashVal == hashVal);
|
||||
break;
|
||||
}
|
||||
|
@ -306,7 +312,7 @@ void* taosHashGetClone(SHashObj *pHashObj, const void *key, size_t keyLen, void
|
|||
assert(pe->next == NULL);
|
||||
}
|
||||
|
||||
SHashNode *pNode = doSearchInEntryList(pe, key, keyLen, hashVal);
|
||||
SHashNode *pNode = doSearchInEntryList(pHashObj, pe, key, keyLen, hashVal);
|
||||
if (pNode != NULL) {
|
||||
if (fp != NULL) {
|
||||
fp(GET_HASH_NODE_DATA(pNode));
|
||||
|
@ -362,7 +368,7 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
|
|||
SHashNode *prevNode = NULL;
|
||||
|
||||
while (pNode) {
|
||||
if ((pNode->keyLen == keyLen) && (memcmp(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && pNode->removed == 0)
|
||||
if ((pNode->keyLen == keyLen) && ((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && pNode->removed == 0)
|
||||
break;
|
||||
|
||||
prevNode = pNode;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "os.h"
|
||||
#include "hashfunc.h"
|
||||
#include "tutil.h"
|
||||
#include "tcompare.h"
|
||||
|
||||
#define ROTL32(x, r) ((x) << (r) | (x) >> (32u - (r)))
|
||||
|
||||
|
@ -78,7 +79,28 @@ uint32_t MurmurHash3_32(const char *key, uint32_t len) {
|
|||
uint32_t taosIntHash_32(const char *key, uint32_t UNUSED_PARAM(len)) { return *(uint32_t *)key; }
|
||||
uint32_t taosIntHash_16(const char *key, uint32_t UNUSED_PARAM(len)) { return *(uint16_t *)key; }
|
||||
uint32_t taosIntHash_8(const char *key, uint32_t UNUSED_PARAM(len)) { return *(uint8_t *)key; }
|
||||
|
||||
uint32_t taosFloatHash(const char *key, uint32_t UNUSED_PARAM(len)) {
|
||||
float f = GET_FLOAT_VAL(key);
|
||||
if (isnan(f)) {
|
||||
return 0x7fc00000;
|
||||
}
|
||||
if (fabs(f - 0.0) < FLT_EPSILON) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *(uint32_t *)(key);
|
||||
}
|
||||
uint32_t taosDoubleHash(const char *key, uint32_t UNUSED_PARAM(len)) {
|
||||
double f = GET_DOUBLE_VAL(key);
|
||||
if (isnan(f)) {
|
||||
return 0x7fc00000;
|
||||
}
|
||||
if (fabs(f - 0.0) < FLT_EPSILON) {
|
||||
return 0;
|
||||
}
|
||||
return *(uint32_t *)(key);
|
||||
|
||||
}
|
||||
uint32_t taosIntHash_64(const char *key, uint32_t UNUSED_PARAM(len)) {
|
||||
uint64_t val = *(uint64_t *)key;
|
||||
|
||||
|
@ -92,13 +114,35 @@ _hash_fn_t taosGetDefaultHashFunction(int32_t type) {
|
|||
_hash_fn_t fn = NULL;
|
||||
switch(type) {
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_BIGINT: fn = taosIntHash_64;break;
|
||||
case TSDB_DATA_TYPE_BINARY: fn = MurmurHash3_32;break;
|
||||
case TSDB_DATA_TYPE_INT: fn = taosIntHash_32; break;
|
||||
case TSDB_DATA_TYPE_BIGINT: fn = taosIntHash_64;break;
|
||||
case TSDB_DATA_TYPE_BINARY: fn = MurmurHash3_32;break;
|
||||
case TSDB_DATA_TYPE_NCHAR: fn = MurmurHash3_32;break;
|
||||
case TSDB_DATA_TYPE_INT: fn = taosIntHash_32; break;
|
||||
case TSDB_DATA_TYPE_SMALLINT: fn = taosIntHash_16; break;
|
||||
case TSDB_DATA_TYPE_TINYINT: fn = taosIntHash_8; break;
|
||||
case TSDB_DATA_TYPE_TINYINT: fn = taosIntHash_8; break;
|
||||
case TSDB_DATA_TYPE_FLOAT: fn = taosFloatHash; break;
|
||||
case TSDB_DATA_TYPE_DOUBLE: fn = taosDoubleHash; break;
|
||||
default: fn = taosIntHash_32;break;
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t taosFloatEqual(const void *a, const void *b, size_t UNUSED_PARAM(sz)) {
|
||||
return getComparFunc(TSDB_DATA_TYPE_FLOAT, -1)(a, b);
|
||||
}
|
||||
|
||||
int32_t taosDoubleEqual(const void *a, const void *b, size_t UNUSED_PARAM(sz)) {
|
||||
return getComparFunc(TSDB_DATA_TYPE_DOUBLE, -1)(a, b);
|
||||
}
|
||||
|
||||
_equal_fn_t taosGetDefaultEqualFunction(int32_t type) {
|
||||
_equal_fn_t fn = NULL;
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_FLOAT: fn = taosFloatEqual; break;
|
||||
case TSDB_DATA_TYPE_DOUBLE: fn = taosDoubleEqual; break;
|
||||
default: fn = memcmp; break;
|
||||
}
|
||||
return fn;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue