• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #5044

06 May 2026 02:35AM UTC coverage: 73.169% (+0.06%) from 73.107%
#5044

push

travis-ci

web-flow
feat: [6659794715] cpu limit (#35153)

244 of 275 new or added lines in 23 files covered. (88.73%)

526 existing lines in 141 files now uncovered.

277745 of 379596 relevant lines covered (73.17%)

133740972.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

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

16
#define _DEFAULT_SOURCE
17
#include "tcompare.h"
18
#include "tutil.h"
19
#include "thash.h"
20
#include "types.h"
21
#include "xxhash.h"
22

23
#ifndef __has_attribute
24
#define __has_attribute(x) 0
25
#endif
26

27
#if defined(WINDOWS)
28
#define TAOS_NO_SANITIZE_ADDR_UB
29
#elif defined(__clang__) && __has_attribute(no_sanitize)
30
#define TAOS_NO_SANITIZE_ADDR_UB __attribute__((no_sanitize("address", "undefined")))
31
#elif defined(__GNUC__) && !defined(__clang__)
32
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))
33
#define TAOS_NO_SANITIZE_ADDR_UB __attribute__((no_sanitize_address, no_sanitize_undefined))
34
#elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
35
#define TAOS_NO_SANITIZE_ADDR_UB __attribute__((no_sanitize_address))
36
#else
37
#define TAOS_NO_SANITIZE_ADDR_UB
38
#endif
39
#else
40
#define TAOS_NO_SANITIZE_ADDR_UB
41
#endif
42

43
#define ROTL32(x, r) ((x) << (r) | (x) >> (32u - (r)))
44

45
#define DLT  (FLT_COMPAR_TOL_FACTOR * FLT_EPSILON)
46
#define BASE 1000
47

48
#define FMIX32(h)      \
49
  do {                 \
50
    (h) ^= (h) >> 16;  \
51
    (h) *= 0x85ebca6b; \
52
    (h) ^= (h) >> 13;  \
53
    (h) *= 0xc2b2ae35; \
54
    (h) ^= (h) >> 16;  \
55
  } while (0)
56

57
uint32_t taosFastHash(const char *key, uint32_t len) {
2,147,483,647✔
58
  uint32_t result = 0x55555555;
2,147,483,647✔
59
  for (uint32_t i = 0; i < len; i++) {
2,147,483,647✔
60
    result ^= (uint8_t)key[i];
2,147,483,647✔
61
    result = ROTL32(result, 5);
2,147,483,647✔
62
  }
63
  return result;
2,147,483,647✔
64
}
65

66
uint32_t taosDJB2Hash(const char *key, uint32_t len) {
983,574✔
67
  uint32_t hash = 5381;
983,574✔
68
  for (uint32_t i = 0; i < len; i++) {
8,852,166✔
69
    hash = ((hash << 5) + hash) + (uint8_t)key[i]; /* hash * 33 + c */
7,868,592✔
70
  }
71
  return hash;
983,574✔
72
}
73

74
uint32_t MurmurHash3_32(const char *key, uint32_t len) {
2,147,483,647✔
75
  const uint8_t *data = (const uint8_t *)key;
2,147,483,647✔
76
  const int32_t  nblocks = len >> 2u;
2,147,483,647✔
77

78
  uint32_t h1 = 0x12345678;
2,147,483,647✔
79

80
  const uint32_t c1 = 0xcc9e2d51;
2,147,483,647✔
81
  const uint32_t c2 = 0x1b873593;
2,147,483,647✔
82

83
  const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);
2,147,483,647✔
84

85
  for (int32_t i = -nblocks; i; i++) {
2,147,483,647✔
86
    uint32_t k1 = blocks[i];
2,147,483,647✔
87

88
    k1 *= c1;
2,147,483,647✔
89
    k1 = ROTL32(k1, 15u);
2,147,483,647✔
90
    k1 *= c2;
2,147,483,647✔
91

92
    h1 ^= k1;
2,147,483,647✔
93
    h1 = ROTL32(h1, 13u);
2,147,483,647✔
94
    h1 = h1 * 5 + 0xe6546b64;
2,147,483,647✔
95
  }
96

97
  const uint8_t *tail = (data + nblocks * 4);
2,147,483,647✔
98

99
  uint32_t k1 = 0;
2,147,483,647✔
100

101
  switch (len & 3u) {
2,147,483,647✔
102
    case 3:
2,147,483,647✔
103
      k1 ^= tail[2] << 16;
2,147,483,647✔
104
    case 2:
2,147,483,647✔
105
      k1 ^= tail[1] << 8;
2,147,483,647✔
106
    case 1:
2,147,483,647✔
107
      k1 ^= tail[0];
2,147,483,647✔
108
      k1 *= c1;
2,147,483,647✔
109
      k1 = ROTL32(k1, 15u);
2,147,483,647✔
110
      k1 *= c2;
2,147,483,647✔
111
      h1 ^= k1;
2,147,483,647✔
112
  };
113

114
  h1 ^= len;
2,147,483,647✔
115

116
  FMIX32(h1);
2,147,483,647✔
117

118
  return h1;
2,147,483,647✔
119
}
120

121
uint64_t MurmurHash3_64(const char *key, uint32_t len) {
2,147,483,647✔
122
  const uint64_t m = 0x87c37b91114253d5;
2,147,483,647✔
123
  const int      r = 47;
2,147,483,647✔
124
  uint32_t       seed = 0x12345678;
2,147,483,647✔
125
  uint64_t       h = seed ^ (len * m);
2,147,483,647✔
126
  const uint8_t *data = (const uint8_t *)key;
2,147,483,647✔
127
  const uint8_t *end = data + (len - (len & 7));
2,147,483,647✔
128

129
  while (data != end) {
2,147,483,647✔
130
#ifndef NO_UNALIGNED_ACCESS
131
    uint64_t k = *((uint64_t *)data);
2,147,483,647✔
132
#else
133
    uint64_t k = 0;
134
    memcpy(&k, data, sizeof(uint64_t));
135
#endif
136
    k *= m;
2,147,483,647✔
137
    k ^= k >> r;
2,147,483,647✔
138
    k *= m;
2,147,483,647✔
139
    h ^= k;
2,147,483,647✔
140
    h *= m;
2,147,483,647✔
141
    data += 8;
2,147,483,647✔
142
  }
143

144
  switch (len & 7) {
2,147,483,647✔
145
    case 7:
1,522,113,821✔
146
      h ^= (uint64_t)data[6] << 48; /* fall-thru */
1,522,113,821✔
147
    case 6:
2,147,483,647✔
148
      h ^= (uint64_t)data[5] << 40; /* fall-thru */
2,147,483,647✔
149
    case 5:
2,147,483,647✔
150
      h ^= (uint64_t)data[4] << 32; /* fall-thru */
2,147,483,647✔
151
    case 4:
2,147,483,647✔
152
      h ^= (uint64_t)data[3] << 24; /* fall-thru */
2,147,483,647✔
153
    case 3:
2,147,483,647✔
154
      h ^= (uint64_t)data[2] << 16; /* fall-thru */
2,147,483,647✔
155
    case 2:
2,147,483,647✔
156
      h ^= (uint64_t)data[1] << 8; /* fall-thru */
2,147,483,647✔
157
    case 1:
2,147,483,647✔
158
      h ^= (uint64_t)data[0];
2,147,483,647✔
159
      h *= m; /* fall-thru */
2,147,483,647✔
160
  };
161

162
  h ^= h >> r;
2,147,483,647✔
163
  h *= m;
2,147,483,647✔
164
  h ^= h >> r;
2,147,483,647✔
165
  return h;
2,147,483,647✔
166
}
167

168
uint32_t taosIntHash_32(const char *key, uint32_t UNUSED_PARAM(len)) { return *(uint32_t *)key; }
2,147,483,647✔
169
uint32_t taosIntHash_16(const char *key, uint32_t UNUSED_PARAM(len)) { return *(uint16_t *)key; }
2,147,483,647✔
170
uint32_t taosIntHash_8(const char *key, uint32_t UNUSED_PARAM(len)) { return *(uint8_t *)key; }
3,774,239✔
171

172

173
TAOS_NO_SANITIZE_ADDR_UB
174
uint32_t taosFloatHash(const char *key, uint32_t UNUSED_PARAM(len)) {
2,336,446✔
175
  float f = GET_FLOAT_VAL(key);
2,336,446✔
176
  if (isnan(f)) {
2,336,446✔
177
    return 0x7fc00000;
×
178
  }
179

180
  if (FLT_EQUAL(f, 0.0)) {
2,336,446✔
181
    return 0;
261,564✔
182
  }
183
  if (fabs(f) < FLT_MAX / BASE - DLT) {
2,074,882✔
184
    uint32_t t = (uint32_t)(round(BASE * (f + DLT)));
2,074,882✔
185
    return t;
2,074,882✔
186
  } else {
187
    return 0x7fc00000;
×
188
  }
189
}
190
uint32_t taosDoubleHash(const char *key, uint32_t UNUSED_PARAM(len)) {
567,756,133✔
191
  double f = GET_DOUBLE_VAL(key);
567,756,133✔
192
  if (isnan(f)) {
568,181,541✔
193
    return 0x7fc00000;
×
194
  }
195

196
  if (DBL_EQUAL(f, 0.0)) {
568,181,541✔
197
    return 0;
36,381,877✔
198
  }
199
  if (fabs(f) < DBL_MAX / BASE - DLT) {
531,799,664✔
200
    uint64_t bits;
531,782,028✔
201
    memcpy(&bits, &f, sizeof(double));
531,804,356✔
202
    return (uint32_t)(bits ^ (bits >> 32));
531,804,356✔
203
  } else {
UNCOV
204
    return 0x7fc00000;
×
205
  }
206
}
207
uint32_t taosIntHash_64(const char *key, uint32_t UNUSED_PARAM(len)) {
2,147,483,647✔
208
  uint64_t val = taosGetUInt64Aligned((uint64_t *)key);
2,147,483,647✔
209

210
  uint64_t hash = val >> 16U;
2,147,483,647✔
211
  hash += (val & 0xFFFFU);
2,147,483,647✔
212

213
  return (uint32_t)hash;
2,147,483,647✔
214
}
215

216
_hash_fn_t taosGetDefaultHashFunction(int32_t type) {
2,147,483,647✔
217
  _hash_fn_t fn = NULL;
2,147,483,647✔
218
  switch (type) {
2,147,483,647✔
219
    case TSDB_DATA_TYPE_TIMESTAMP:
2,147,483,647✔
220
    case TSDB_DATA_TYPE_UBIGINT:
221
    case TSDB_DATA_TYPE_BIGINT:
222
      fn = taosIntHash_64;
2,147,483,647✔
223
      break;
2,147,483,647✔
224
    case TSDB_DATA_TYPE_BINARY:
2,147,483,647✔
225
    case TSDB_DATA_TYPE_VARBINARY:
226
    case TSDB_DATA_TYPE_NCHAR:
227
    case TSDB_DATA_TYPE_GEOMETRY:
228
      fn = MurmurHash3_32;
2,147,483,647✔
229
      break;
2,147,483,647✔
230
    case TSDB_DATA_TYPE_UINT:
2,147,483,647✔
231
    case TSDB_DATA_TYPE_INT:
232
      fn = taosIntHash_32;
2,147,483,647✔
233
      break;
2,147,483,647✔
234
    case TSDB_DATA_TYPE_SMALLINT:
148,925,820✔
235
    case TSDB_DATA_TYPE_USMALLINT:
236
      fn = taosIntHash_16;
148,925,820✔
237
      break;
148,925,820✔
238
    case TSDB_DATA_TYPE_BOOL:
731,876✔
239
    case TSDB_DATA_TYPE_UTINYINT:
240
    case TSDB_DATA_TYPE_TINYINT:
241
      fn = taosIntHash_8;
731,876✔
242
      break;
731,876✔
243
    case TSDB_DATA_TYPE_FLOAT:
1,001,828✔
244
      fn = taosFloatHash;
1,001,828✔
245
      break;
1,001,828✔
246
    case TSDB_DATA_TYPE_DOUBLE:
2,296,168✔
247
      fn = taosDoubleHash;
2,296,168✔
248
      break;
2,296,168✔
249
    default:
854,881✔
250
      fn = taosIntHash_32;
854,881✔
251
      break;
854,881✔
252
  }
253

254
  return fn;
2,147,483,647✔
255
}
256

257
int32_t taosFloatEqual(const void *a, const void *b, size_t UNUSED_PARAM(sz)) {
1,700,862✔
258
  // getComparFunc(TSDB_DATA_TYPE_FLOAT, -1) will always get function compareFloatVal, which will never be NULL.
259
  return getComparFunc(TSDB_DATA_TYPE_FLOAT, -1)(a, b);
1,700,862✔
260
}
261

262
int32_t taosDoubleEqual(const void *a, const void *b, size_t UNUSED_PARAM(sz)) {
253,992,003✔
263
  // getComparFunc(TSDB_DATA_TYPE_DOUBLE, -1) will always get function compareDoubleVal, which will never be NULL.
264
  return getComparFunc(TSDB_DATA_TYPE_DOUBLE, -1)(a, b);
253,992,003✔
265
}
266

267
int32_t taosDecimalEqual(const void* a, const void* b, size_t UNUSED_PARAM(sz)) {
×
268
  return 0;
×
269
}
270

271
_equal_fn_t taosGetDefaultEqualFunction(int32_t type) {
14,289,434✔
272
  _equal_fn_t fn = NULL;
14,289,434✔
273
  switch (type) {
14,289,434✔
274
    case TSDB_DATA_TYPE_FLOAT:
1,002,992✔
275
      fn = taosFloatEqual;
1,002,992✔
276
      break;
1,002,992✔
277
    case TSDB_DATA_TYPE_DOUBLE:
2,295,486✔
278
      fn = taosDoubleEqual;
2,295,486✔
279
      break;
2,295,486✔
280
    case TSDB_DATA_TYPE_DECIMAL64:
669,484✔
281
    case TSDB_DATA_TYPE_DECIMAL:
282
      fn = memcmp;
669,484✔
283
      break;
669,484✔
284
    default:
10,321,472✔
285
      fn = memcmp;
10,321,472✔
286
      break;
10,321,472✔
287
  }
288
  return fn;
14,289,434✔
289
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc