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

taosdata / TDengine / #5058

17 May 2026 01:15AM UTC coverage: 73.387% (-0.02%) from 73.406%
#5058

push

travis-ci

web-flow
feat (TDgpt): Dynamic Model Synchronization Enhancements (#35344)

* refactor: do some internal refactor.

* fix: fix multiprocess sync issue.

* feat: add dynamic anomaly detection and forecasting services

* fix: log error message for undeploying model in exception handling

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: handle undeploy when model exists only on disk

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/286aafa0-c3ce-4c27-b803-2707571e9dc1

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: guard dynamic registry concurrent access

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: tighten service list locking scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: restore prophet support and update tests per review feedback

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: improve test name and move copy inside lock scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* Potential fix for pull request finding

Co-au... (continued)

281656 of 383795 relevant lines covered (73.39%)

135114337.11 hits per line

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

96.79
/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) {
1,892,916✔
67
  uint32_t hash = 5381;
1,892,916✔
68
  for (uint32_t i = 0; i < len; i++) {
17,036,244✔
69
    hash = ((hash << 5) + hash) + (uint8_t)key[i]; /* hash * 33 + c */
15,143,328✔
70
  }
71
  return hash;
1,892,916✔
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,631,120,212✔
146
      h ^= (uint64_t)data[6] << 48; /* fall-thru */
1,631,120,212✔
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; }
5,601,502✔
171

172

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

180
  if (FLT_EQUAL(f, 0.0)) {
2,494,275✔
181
    return 0;
279,564✔
182
  }
183
  if (fabs(f) < FLT_MAX / BASE - DLT) {
2,214,711✔
184
    uint32_t t = (uint32_t)(round(BASE * (f + DLT)));
2,214,711✔
185
    return t;
2,214,711✔
186
  } else {
187
    return 0x7fc00000;
×
188
  }
189
}
190
uint32_t taosDoubleHash(const char *key, uint32_t UNUSED_PARAM(len)) {
489,539,235✔
191
  double f = GET_DOUBLE_VAL(key);
489,539,235✔
192
  if (isnan(f)) {
489,575,667✔
193
    return 0x7fc00000;
×
194
  }
195

196
  if (DBL_EQUAL(f, 0.0)) {
489,575,667✔
197
    return 0;
32,127,699✔
198
  }
199
  if (fabs(f) < DBL_MAX / BASE - DLT) {
457,447,968✔
200
    uint64_t bits;
457,427,940✔
201
    memcpy(&bits, &f, sizeof(double));
457,447,968✔
202
    return (uint32_t)(bits ^ (bits >> 32));
457,447,968✔
203
  } else {
204
    return 0x7fc00000;
828✔
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:
159,678,704✔
235
    case TSDB_DATA_TYPE_USMALLINT:
236
      fn = taosIntHash_16;
159,678,704✔
237
      break;
159,678,704✔
238
    case TSDB_DATA_TYPE_BOOL:
847,200✔
239
    case TSDB_DATA_TYPE_UTINYINT:
240
    case TSDB_DATA_TYPE_TINYINT:
241
      fn = taosIntHash_8;
847,200✔
242
      break;
847,200✔
243
    case TSDB_DATA_TYPE_FLOAT:
1,069,798✔
244
      fn = taosFloatHash;
1,069,798✔
245
      break;
1,069,798✔
246
    case TSDB_DATA_TYPE_DOUBLE:
2,319,821✔
247
      fn = taosDoubleHash;
2,319,821✔
248
      break;
2,319,821✔
249
    default:
557,683✔
250
      fn = taosIntHash_32;
557,683✔
251
      break;
557,683✔
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,816,540✔
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,816,540✔
260
}
261

262
int32_t taosDoubleEqual(const void *a, const void *b, size_t UNUSED_PARAM(sz)) {
237,339,009✔
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);
237,339,009✔
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) {
15,388,321✔
272
  _equal_fn_t fn = NULL;
15,388,321✔
273
  switch (type) {
15,388,321✔
274
    case TSDB_DATA_TYPE_FLOAT:
1,071,030✔
275
      fn = taosFloatEqual;
1,071,030✔
276
      break;
1,071,030✔
277
    case TSDB_DATA_TYPE_DOUBLE:
2,319,821✔
278
      fn = taosDoubleEqual;
2,319,821✔
279
      break;
2,319,821✔
280
    case TSDB_DATA_TYPE_DECIMAL64:
826,512✔
281
    case TSDB_DATA_TYPE_DECIMAL:
282
      fn = memcmp;
826,512✔
283
      break;
826,512✔
284
    default:
11,170,958✔
285
      fn = memcmp;
11,170,958✔
286
      break;
11,170,958✔
287
  }
288
  return fn;
15,388,321✔
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