thashutil.c 4.5 KB
Newer Older
S
TD-4088  
Shengliang Guan 已提交
1 2
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
H
hzcheng 已提交
3
 *
S
TD-4088  
Shengliang Guan 已提交
4 5 6
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
H
hzcheng 已提交
7
 *
S
TD-4088  
Shengliang Guan 已提交
8 9 10 11 12 13
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
H
hzcheng 已提交
14
 */
S
TD-4088  
Shengliang Guan 已提交
15

S
hash  
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
H
Haojun Liao 已提交
17
#include "thash.h"
S
compare  
Shengliang Guan 已提交
18
#include "tcompare.h"
H
Hongze Cheng 已提交
19
#include "types.h"
H
hzcheng 已提交
20

H
Haojun Liao 已提交
21
#define ROTL32(x, r) ((x) << (r) | (x) >> (32u - (r)))
H
hzcheng 已提交
22

23 24 25
#define DLT (FLT_COMPAR_TOL_FACTOR * FLT_EPSILON)
#define BASE 1000

H
hzcheng 已提交
26 27 28 29 30 31
#define FMIX32(h)      \
  do {                 \
    (h) ^= (h) >> 16;  \
    (h) *= 0x85ebca6b; \
    (h) ^= (h) >> 13;  \
    (h) *= 0xc2b2ae35; \
32
    (h) ^= (h) >> 16; } while (0)
H
Haojun Liao 已提交
33 34
  
uint32_t MurmurHash3_32(const char *key, uint32_t len) {
H
hzcheng 已提交
35
  const uint8_t *data = (const uint8_t *)key;
S
hash  
Shengliang Guan 已提交
36
  const int32_t nblocks = len >> 2u;
H
hzcheng 已提交
37

H
Haojun Liao 已提交
38
  uint32_t h1 = 0x12345678;
H
hzcheng 已提交
39 40 41 42 43 44

  const uint32_t c1 = 0xcc9e2d51;
  const uint32_t c2 = 0x1b873593;

  const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);

S
hash  
Shengliang Guan 已提交
45
  for (int32_t i = -nblocks; i; i++) {
H
hzcheng 已提交
46 47 48
    uint32_t k1 = blocks[i];

    k1 *= c1;
H
Haojun Liao 已提交
49
    k1 = ROTL32(k1, 15u);
H
hzcheng 已提交
50 51 52
    k1 *= c2;

    h1 ^= k1;
H
Haojun Liao 已提交
53
    h1 = ROTL32(h1, 13u);
H
hzcheng 已提交
54 55 56 57 58 59 60
    h1 = h1 * 5 + 0xe6546b64;
  }

  const uint8_t *tail = (data + nblocks * 4);

  uint32_t k1 = 0;

H
Haojun Liao 已提交
61
  switch (len & 3u) {
H
hzcheng 已提交
62 63 64 65 66 67 68
    case 3:
      k1 ^= tail[2] << 16;
    case 2:
      k1 ^= tail[1] << 8;
    case 1:
      k1 ^= tail[0];
      k1 *= c1;
H
Haojun Liao 已提交
69
      k1 = ROTL32(k1, 15u);
H
hzcheng 已提交
70 71 72 73 74 75 76 77
      k1 *= c2;
      h1 ^= k1;
  };

  h1 ^= len;

  FMIX32(h1);

H
Haojun Liao 已提交
78
  return h1;
H
hzcheng 已提交
79
}
80 81

uint32_t taosIntHash_32(const char *key, uint32_t UNUSED_PARAM(len)) { return *(uint32_t *)key; }
H
hjxilinx 已提交
82 83
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; }
84 85 86 87 88
uint32_t taosFloatHash(const char *key, uint32_t UNUSED_PARAM(len)) {
  float f = GET_FLOAT_VAL(key); 
  if (isnan(f)) {
    return 0x7fc00000;
  }
89 90
   
  if (FLT_EQUAL(f, 0.0)) {
91
    return 0;
92
  } 
Y
yihaoDeng 已提交
93
  if (fabs(f) < FLT_MAX/BASE - DLT) {
S
hash  
Shengliang Guan 已提交
94
   int32_t t = (int32_t)(round(BASE * (f + DLT)));
Y
yihaoDeng 已提交
95 96 97
   return (uint32_t)t;
  } else {
   return 0x7fc00000;
98
  }
99 100 101 102 103 104
}
uint32_t taosDoubleHash(const char *key, uint32_t UNUSED_PARAM(len)) {
  double f = GET_DOUBLE_VAL(key);  
  if (isnan(f)) {
    return 0x7fc00000;
  }
105 106

  if (FLT_EQUAL(f, 0.0)) {
107
    return 0;
108
  } 
Y
yihaoDeng 已提交
109
  if (fabs(f) < DBL_MAX/BASE - DLT) {
S
hash  
Shengliang Guan 已提交
110
   int32_t t = (int32_t)(round(BASE * (f + DLT)));
Y
yihaoDeng 已提交
111 112 113 114
   return (uint32_t)t;
  } else {
   return 0x7fc00000;
  } 
115
}
116 117 118 119 120 121
uint32_t taosIntHash_64(const char *key, uint32_t UNUSED_PARAM(len)) {
  uint64_t val = *(uint64_t *)key;

  uint64_t hash = val >> 16U;
  hash += (val & 0xFFFFU);
  
S
TD-1037  
Shengliang Guan 已提交
122
  return (uint32_t)hash;
123 124 125 126 127
}

_hash_fn_t taosGetDefaultHashFunction(int32_t type) {
  _hash_fn_t fn = NULL;
  switch(type) {
H
hjxilinx 已提交
128
    case TSDB_DATA_TYPE_TIMESTAMP:
W
wpan 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
    case TSDB_DATA_TYPE_UBIGINT:
    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_UINT:
    case TSDB_DATA_TYPE_INT:      
      fn = taosIntHash_32; 
      break;
    case TSDB_DATA_TYPE_SMALLINT: 
    case TSDB_DATA_TYPE_USMALLINT:  
      fn = taosIntHash_16; 
      break;
    case TSDB_DATA_TYPE_BOOL:
    case TSDB_DATA_TYPE_UTINYINT:
    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;
161 162 163
  }
  
  return fn;
164 165
}

D
dapan1121 已提交
166 167 168 169 170 171 172
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);
}
173 174 175

_equal_fn_t taosGetDefaultEqualFunction(int32_t type) {
  _equal_fn_t fn = NULL;
D
dapan1121 已提交
176 177 178 179 180
  switch (type) {
    case TSDB_DATA_TYPE_FLOAT:  fn = taosFloatEqual;  break;
    case TSDB_DATA_TYPE_DOUBLE: fn = taosDoubleEqual; break;
    default: fn = memcmp; break;
  }
181 182
  return fn;
}