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

taosdata / TDengine / #4824

27 Oct 2025 05:39AM UTC coverage: 61.409% (+0.2%) from 61.242%
#4824

push

travis-ci

web-flow
Merge pull request #33376 from taosdata/3.0

merge 3.0

156919 of 324854 branches covered (48.3%)

Branch coverage included in aggregate %.

371 of 493 new or added lines in 25 files covered. (75.25%)

2822 existing lines in 108 files now uncovered.

208404 of 270043 relevant lines covered (77.17%)

229356519.53 hits per line

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

52.33
/source/dnode/vnode/src/meta/metaCache.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
#include "meta.h"
16

17
#ifdef TD_ENTERPRISE
18
extern const char* tkLogStb[];
19
extern const char* tkAuditStb[];
20
extern const int   tkLogStbNum;
21
extern const int   tkAuditStbNum;
22
#endif
23

24
#define TAG_FILTER_RES_KEY_LEN  32
25
#define META_CACHE_BASE_BUCKET  1024
26
#define META_CACHE_STATS_BUCKET 16
27

28
// (uid , suid) : child table
29
// (uid,     0) : normal table
30
// (suid, suid) : super table
31
typedef struct SMetaCacheEntry SMetaCacheEntry;
32
struct SMetaCacheEntry {
33
  SMetaCacheEntry* next;
34
  SMetaInfo        info;
35
};
36

37
typedef struct SMetaStbStatsEntry {
38
  struct SMetaStbStatsEntry* next;
39
  SMetaStbStats              info;
40
} SMetaStbStatsEntry;
41

42
typedef struct STagFilterResEntry {
43
  SHashObj *set;    // the set of md5 digest, extracted from the serialized tag query condition
44
  uint32_t hitTimes;  // queried times for current super table
45
} STagFilterResEntry;
46

47
struct SMetaCache {
48
  // child, normal, super, table entry cache
49
  struct SEntryCache {
50
    int32_t           nEntry;
51
    int32_t           nBucket;
52
    SMetaCacheEntry** aBucket;
53
  } sEntryCache;
54

55
  // stable stats cache
56
  struct SStbStatsCache {
57
    int32_t              nEntry;
58
    int32_t              nBucket;
59
    SMetaStbStatsEntry** aBucket;
60
  } sStbStatsCache;
61

62
  // query cache
63
  struct STagFilterResCache {
64
    TdThreadMutex lock;
65
    uint32_t      accTimes;
66
    SHashObj*     pTableEntry;
67
    SLRUCache*    pUidResCache;
68
  } sTagFilterResCache;
69

70
  struct STbGroupResCache {
71
    TdThreadMutex lock;
72
    uint32_t      accTimes;
73
    SHashObj*     pTableEntry;
74
    SLRUCache*    pResCache;
75
  } STbGroupResCache;
76

77
  struct STbFilterCache {
78
    SHashObj* pStb;
79
    SHashObj* pStbName;
80
  } STbFilterCache;
81

82
  struct STbRefDbCache {
83
    TdThreadMutex lock;
84
    SHashObj*     pStbRefs; // key: suid, value: SHashObj<dbName, refTimes>
85
  } STbRefDbCache;
86
};
87

88
static void entryCacheClose(SMeta* pMeta) {
21,686,060✔
89
  if (pMeta->pCache) {
21,686,060✔
90
    // close entry cache
91
    for (int32_t iBucket = 0; iBucket < pMeta->pCache->sEntryCache.nBucket; iBucket++) {
2,147,483,647✔
92
      SMetaCacheEntry* pEntry = pMeta->pCache->sEntryCache.aBucket[iBucket];
2,147,483,647✔
93
      while (pEntry) {
2,147,483,647✔
94
        SMetaCacheEntry* tEntry = pEntry->next;
195,036,577✔
95
        taosMemoryFree(pEntry);
195,036,577!
96
        pEntry = tEntry;
195,040,243✔
97
      }
98
    }
99
    taosMemoryFree(pMeta->pCache->sEntryCache.aBucket);
21,688,416!
100
  }
101
}
21,689,887✔
102

103
static void statsCacheClose(SMeta* pMeta) {
21,688,416✔
104
  if (pMeta->pCache) {
21,688,416!
105
    // close entry cache
106
    for (int32_t iBucket = 0; iBucket < pMeta->pCache->sStbStatsCache.nBucket; iBucket++) {
383,028,826✔
107
      SMetaStbStatsEntry* pEntry = pMeta->pCache->sStbStatsCache.aBucket[iBucket];
361,334,479✔
108
      while (pEntry) {
379,537,678✔
109
        SMetaStbStatsEntry* tEntry = pEntry->next;
18,197,268✔
110
        taosMemoryFree(pEntry);
18,197,268!
111
        pEntry = tEntry;
18,205,408✔
112
      }
113
    }
114
    taosMemoryFree(pMeta->pCache->sStbStatsCache.aBucket);
21,688,416!
115
  }
116
}
21,688,416✔
117

118
static void freeCacheEntryFp(void* param) {
×
119
  STagFilterResEntry** p = param;
×
120
  taosHashCleanup((*p)->set);
×
121
  taosMemoryFreeClear(*p);
×
122
}
×
123

124
static void freeRefDbFp(void* param) {
63,120✔
125
  SHashObj** p = param;
63,120✔
126
  taosHashCleanup(*p);
63,120✔
127
  *p = NULL;
63,120✔
128
}
63,120✔
129

130
int32_t metaCacheOpen(SMeta* pMeta) {
21,668,709✔
131
  int32_t code = 0;
21,668,709✔
132
  int32_t lino;
133

134
  pMeta->pCache = (SMetaCache*)taosMemoryCalloc(1, sizeof(SMetaCache));
21,668,709!
135
  if (pMeta->pCache == NULL) {
21,682,003!
136
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
137
  }
138

139
  // open entry cache
140
  pMeta->pCache->sEntryCache.nEntry = 0;
21,683,657✔
141
  pMeta->pCache->sEntryCache.nBucket = META_CACHE_BASE_BUCKET;
21,684,791✔
142
  pMeta->pCache->sEntryCache.aBucket =
21,692,772✔
143
      (SMetaCacheEntry**)taosMemoryCalloc(pMeta->pCache->sEntryCache.nBucket, sizeof(SMetaCacheEntry*));
21,681,485!
144
  if (pMeta->pCache->sEntryCache.aBucket == NULL) {
21,686,203!
145
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
146
  }
147

148
  // open stats cache
149
  pMeta->pCache->sStbStatsCache.nEntry = 0;
21,686,203✔
150
  pMeta->pCache->sStbStatsCache.nBucket = META_CACHE_STATS_BUCKET;
21,687,128✔
151
  pMeta->pCache->sStbStatsCache.aBucket =
21,693,305✔
152
      (SMetaStbStatsEntry**)taosMemoryCalloc(pMeta->pCache->sStbStatsCache.nBucket, sizeof(SMetaStbStatsEntry*));
21,684,645!
153
  if (pMeta->pCache->sStbStatsCache.aBucket == NULL) {
21,685,777!
154
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
155
  }
156

157
  // open tag filter cache
158
  pMeta->pCache->sTagFilterResCache.pUidResCache = taosLRUCacheInit(5 * 1024 * 1024, -1, 0.5);
21,687,128✔
159
  if (pMeta->pCache->sTagFilterResCache.pUidResCache == NULL) {
21,688,416!
160
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
161
  }
162

163
  pMeta->pCache->sTagFilterResCache.accTimes = 0;
21,688,416✔
164
  pMeta->pCache->sTagFilterResCache.pTableEntry =
43,374,021✔
165
      taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, HASH_NO_LOCK);
43,366,853✔
166
  if (pMeta->pCache->sTagFilterResCache.pTableEntry == NULL) {
21,688,416!
167
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
168
  }
169

170
  taosHashSetFreeFp(pMeta->pCache->sTagFilterResCache.pTableEntry, freeCacheEntryFp);
21,688,416✔
171
  (void)taosThreadMutexInit(&pMeta->pCache->sTagFilterResCache.lock, NULL);
21,688,416✔
172

173
  // open group res cache
174
  pMeta->pCache->STbGroupResCache.pResCache = taosLRUCacheInit(5 * 1024 * 1024, -1, 0.5);
21,688,416✔
175
  if (pMeta->pCache->STbGroupResCache.pResCache == NULL) {
21,687,058!
176
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
177
  }
178

179
  pMeta->pCache->STbGroupResCache.accTimes = 0;
21,688,416✔
180
  pMeta->pCache->STbGroupResCache.pTableEntry =
43,375,474✔
181
      taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, HASH_NO_LOCK);
43,368,306✔
182
  if (pMeta->pCache->STbGroupResCache.pTableEntry == NULL) {
21,687,058!
183
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
184
  }
185

186
  taosHashSetFreeFp(pMeta->pCache->STbGroupResCache.pTableEntry, freeCacheEntryFp);
21,688,416✔
187
  (void)taosThreadMutexInit(&pMeta->pCache->STbGroupResCache.lock, NULL);
21,688,416✔
188

189
  // open filter cache
190
  pMeta->pCache->STbFilterCache.pStb =
43,374,801✔
191
      taosHashInit(0, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
43,366,948✔
192
  if (pMeta->pCache->STbFilterCache.pStb == NULL) {
21,688,416!
193
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
194
  }
195

196
  pMeta->pCache->STbFilterCache.pStbName =
43,376,159✔
197
      taosHashInit(0, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, HASH_NO_LOCK);
43,368,318✔
198
  if (pMeta->pCache->STbFilterCache.pStbName == NULL) {
21,687,743!
199
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
200
  }
201

202
  // open ref db cache
203
  pMeta->pCache->STbRefDbCache.pStbRefs =
43,376,159✔
204
      taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
43,366,237✔
205
  if (pMeta->pCache->STbRefDbCache.pStbRefs == NULL) {
21,688,416!
206
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
207
  }
208

209
  taosHashSetFreeFp(pMeta->pCache->STbRefDbCache.pStbRefs, freeRefDbFp);
21,688,416✔
210
  (void)taosThreadMutexInit(&pMeta->pCache->STbRefDbCache.lock, NULL);
21,688,416✔
211

212

213
_exit:
21,688,416✔
214
  if (code) {
21,688,416!
215
    metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, lino, tstrerror(code));
×
216
    metaCacheClose(pMeta);
×
217
  } else {
218
    metaDebug("vgId:%d, %s success", TD_VID(pMeta->pVnode), __func__);
21,688,416✔
219
  }
220
  return code;
21,688,416✔
221
}
222

223
void metaCacheClose(SMeta* pMeta) {
21,685,620✔
224
  if (pMeta->pCache) {
21,685,620✔
225
    entryCacheClose(pMeta);
21,685,705✔
226
    statsCacheClose(pMeta);
21,688,416✔
227

228
    taosHashClear(pMeta->pCache->sTagFilterResCache.pTableEntry);
21,688,416✔
229
    taosLRUCacheCleanup(pMeta->pCache->sTagFilterResCache.pUidResCache);
21,687,601✔
230
    (void)taosThreadMutexDestroy(&pMeta->pCache->sTagFilterResCache.lock);
21,688,416✔
231
    taosHashCleanup(pMeta->pCache->sTagFilterResCache.pTableEntry);
21,688,416✔
232

233
    taosHashClear(pMeta->pCache->STbGroupResCache.pTableEntry);
21,688,416✔
234
    taosLRUCacheCleanup(pMeta->pCache->STbGroupResCache.pResCache);
21,688,416✔
235
    (void)taosThreadMutexDestroy(&pMeta->pCache->STbGroupResCache.lock);
21,688,416✔
236
    taosHashCleanup(pMeta->pCache->STbGroupResCache.pTableEntry);
21,688,416✔
237

238
    taosHashCleanup(pMeta->pCache->STbFilterCache.pStb);
21,688,416✔
239
    taosHashCleanup(pMeta->pCache->STbFilterCache.pStbName);
21,688,416✔
240

241
    taosHashClear(pMeta->pCache->STbRefDbCache.pStbRefs);
21,688,416✔
242
    (void)taosThreadMutexDestroy(&pMeta->pCache->STbRefDbCache.lock);
21,688,416✔
243
    taosHashCleanup(pMeta->pCache->STbRefDbCache.pStbRefs);
21,688,416✔
244

245
    taosMemoryFree(pMeta->pCache);
21,688,416!
246
    pMeta->pCache = NULL;
21,688,416✔
247
  }
248
}
21,689,176✔
249

250
static void metaRehashCache(SMetaCache* pCache, int8_t expand) {
46,481✔
251
  int32_t code = 0;
46,481✔
252
  int32_t nBucket;
253

254
  if (expand) {
46,481!
255
    nBucket = pCache->sEntryCache.nBucket * 2;
46,481✔
256
  } else {
257
    nBucket = pCache->sEntryCache.nBucket / 2;
×
258
  }
259

260
  SMetaCacheEntry** aBucket = (SMetaCacheEntry**)taosMemoryCalloc(nBucket, sizeof(SMetaCacheEntry*));
46,481!
261
  if (aBucket == NULL) {
46,481!
262
    return;
×
263
  }
264

265
  // rehash
266
  for (int32_t iBucket = 0; iBucket < pCache->sEntryCache.nBucket; iBucket++) {
127,976,849✔
267
    SMetaCacheEntry* pEntry = pCache->sEntryCache.aBucket[iBucket];
127,930,368✔
268

269
    while (pEntry) {
255,860,736✔
270
      SMetaCacheEntry* pTEntry = pEntry->next;
127,930,368✔
271

272
      pEntry->next = aBucket[TABS(pEntry->info.uid) % nBucket];
127,930,368!
273
      aBucket[TABS(pEntry->info.uid) % nBucket] = pEntry;
127,930,368!
274

275
      pEntry = pTEntry;
127,930,368✔
276
    }
277
  }
278

279
  // final set
280
  taosMemoryFree(pCache->sEntryCache.aBucket);
46,481!
281
  pCache->sEntryCache.nBucket = nBucket;
46,481✔
282
  pCache->sEntryCache.aBucket = aBucket;
46,481✔
283
  return;
46,481✔
284
}
285

286
int32_t metaCacheUpsert(SMeta* pMeta, SMetaInfo* pInfo) {
254,636,011✔
287
  int32_t code = 0;
254,636,011✔
288

289
  // meta is wlocked for calling this func.
290

291
  // search
292
  SMetaCache*       pCache = pMeta->pCache;
254,636,011✔
293
  int32_t           iBucket = TABS(pInfo->uid) % pCache->sEntryCache.nBucket;
254,717,836!
294
  SMetaCacheEntry** ppEntry = &pCache->sEntryCache.aBucket[iBucket];
254,718,749✔
295
  while (*ppEntry && (*ppEntry)->info.uid != pInfo->uid) {
292,607,890✔
296
    ppEntry = &(*ppEntry)->next;
37,887,617✔
297
  }
298

299
  if (*ppEntry) {  // update
254,655,016✔
300
    if (pInfo->suid != (*ppEntry)->info.suid) {
35,451,977!
301
      metaError("meta/cache: suid should be same as the one in cache.");
×
302
      return TSDB_CODE_INVALID_PARA;
×
303
    }
304
    if (pInfo->version > (*ppEntry)->info.version) {
35,424,087✔
305
      (*ppEntry)->info.version = pInfo->version;
35,464,890✔
306
      (*ppEntry)->info.skmVer = pInfo->skmVer;
35,409,315✔
307
    }
308
  } else {  // insert
309
    if (pCache->sEntryCache.nEntry >= pCache->sEntryCache.nBucket) {
219,236,126✔
310
      metaRehashCache(pCache, 1);
46,481✔
311

312
      iBucket = TABS(pInfo->uid) % pCache->sEntryCache.nBucket;
46,481!
313
    }
314

315
    SMetaCacheEntry* pEntryNew = (SMetaCacheEntry*)taosMemoryMalloc(sizeof(*pEntryNew));
219,272,555✔
316
    if (pEntryNew == NULL) {
219,219,286!
317
      code = terrno;
×
318
      goto _exit;
×
319
    }
320

321
    pEntryNew->info = *pInfo;
219,219,286✔
322
    pEntryNew->next = pCache->sEntryCache.aBucket[iBucket];
219,223,637✔
323
    pCache->sEntryCache.aBucket[iBucket] = pEntryNew;
219,166,052✔
324
    pCache->sEntryCache.nEntry++;
219,253,423✔
325
  }
326

327
_exit:
254,639,018✔
328
  return code;
254,639,018✔
329
}
330

331
int32_t metaCacheDrop(SMeta* pMeta, int64_t uid) {
24,472,037✔
332
  int32_t code = 0;
24,472,037✔
333

334
  SMetaCache*       pCache = pMeta->pCache;
24,472,037✔
335
  int32_t           iBucket = TABS(uid) % pCache->sEntryCache.nBucket;
24,475,159!
336
  SMetaCacheEntry** ppEntry = &pCache->sEntryCache.aBucket[iBucket];
24,472,518✔
337
  while (*ppEntry && (*ppEntry)->info.uid != uid) {
24,528,503✔
338
    ppEntry = &(*ppEntry)->next;
57,136✔
339
  }
340

341
  SMetaCacheEntry* pEntry = *ppEntry;
24,474,372✔
342
  if (pEntry) {
24,474,259✔
343
    *ppEntry = pEntry->next;
24,284,000✔
344
    taosMemoryFree(pEntry);
24,284,172!
345
    pCache->sEntryCache.nEntry--;
24,284,000✔
346
    if (pCache->sEntryCache.nEntry < pCache->sEntryCache.nBucket / 4 &&
24,282,585✔
347
        pCache->sEntryCache.nBucket > META_CACHE_BASE_BUCKET) {
23,751,122!
348
      metaRehashCache(pCache, 0);
×
349
    }
350
  } else {
351
    code = TSDB_CODE_NOT_FOUND;
190,259✔
352
  }
353

354
_exit:
24,475,305✔
355
  return code;
24,475,305✔
356
}
357

358
int32_t metaCacheGet(SMeta* pMeta, int64_t uid, SMetaInfo* pInfo) {
2,147,483,647✔
359
  int32_t code = 0;
2,147,483,647✔
360

361
  SMetaCache*      pCache = pMeta->pCache;
2,147,483,647✔
362
  int32_t          iBucket = TABS(uid) % pCache->sEntryCache.nBucket;
2,147,483,647!
363
  SMetaCacheEntry* pEntry = pCache->sEntryCache.aBucket[iBucket];
2,147,483,647✔
364

365
  while (pEntry && pEntry->info.uid != uid) {
2,147,483,647✔
366
    pEntry = pEntry->next;
147,533,773✔
367
  }
368

369
  if (pEntry) {
2,147,483,647✔
370
    if (pInfo) {
2,147,483,647✔
371
      *pInfo = pEntry->info;
2,147,483,647✔
372
    }
373
  } else {
374
    code = TSDB_CODE_NOT_FOUND;
277,750,580✔
375
  }
376

377
  return code;
2,147,483,647✔
378
}
379

380
static int32_t metaRehashStatsCache(SMetaCache* pCache, int8_t expand) {
313,066✔
381
  int32_t code = 0;
313,066✔
382
  int32_t nBucket;
383

384
  if (expand) {
313,066✔
385
    nBucket = pCache->sStbStatsCache.nBucket * 2;
291,259✔
386
  } else {
387
    nBucket = pCache->sStbStatsCache.nBucket / 2;
21,807✔
388
  }
389

390
  SMetaStbStatsEntry** aBucket = (SMetaStbStatsEntry**)taosMemoryCalloc(nBucket, sizeof(SMetaStbStatsEntry*));
313,066!
391
  if (aBucket == NULL) {
313,066!
392
    code = terrno;
×
393
    goto _exit;
×
394
  }
395

396
  // rehash
397
  for (int32_t iBucket = 0; iBucket < pCache->sStbStatsCache.nBucket; iBucket++) {
16,141,482✔
398
    SMetaStbStatsEntry* pEntry = pCache->sStbStatsCache.aBucket[iBucket];
15,828,416✔
399

400
    while (pEntry) {
30,899,281✔
401
      SMetaStbStatsEntry* pTEntry = pEntry->next;
15,070,865✔
402

403
      pEntry->next = aBucket[TABS(pEntry->info.uid) % nBucket];
15,070,865!
404
      aBucket[TABS(pEntry->info.uid) % nBucket] = pEntry;
15,070,865!
405

406
      pEntry = pTEntry;
15,070,865✔
407
    }
408
  }
409

410
  // final set
411
  taosMemoryFree(pCache->sStbStatsCache.aBucket);
313,066!
412
  pCache->sStbStatsCache.nBucket = nBucket;
313,066✔
413
  pCache->sStbStatsCache.aBucket = aBucket;
313,066✔
414

415
_exit:
313,066✔
416
  return code;
313,066✔
417
}
418

419
int32_t metaStatsCacheUpsert(SMeta* pMeta, SMetaStbStats* pInfo) {
213,901,898✔
420
  int32_t code = 0;
213,901,898✔
421

422
  // meta is wlocked for calling this func.
423

424
  // search
425
  SMetaCache*          pCache = pMeta->pCache;
213,901,898✔
426
  int32_t              iBucket = TABS(pInfo->uid) % pCache->sStbStatsCache.nBucket;
213,930,786!
427
  SMetaStbStatsEntry** ppEntry = &pCache->sStbStatsCache.aBucket[iBucket];
213,929,279✔
428
  while (*ppEntry && (*ppEntry)->info.uid != pInfo->uid) {
226,148,474✔
429
    ppEntry = &(*ppEntry)->next;
12,250,917✔
430
  }
431

432
  if (*ppEntry) {  // update
213,868,276✔
433
    (*ppEntry)->info.ctbNum = pInfo->ctbNum;
194,089,907✔
434
    (*ppEntry)->info.colNum = pInfo->colNum;
194,100,095✔
435
    (*ppEntry)->info.flags = pInfo->flags;
194,127,444✔
436
    (*ppEntry)->info.keep = pInfo->keep;
194,088,443✔
437
  } else {  // insert
438
    if (pCache->sStbStatsCache.nEntry >= pCache->sStbStatsCache.nBucket) {
19,800,583✔
439
      TAOS_UNUSED(metaRehashStatsCache(pCache, 1));
291,259✔
440
      iBucket = TABS(pInfo->uid) % pCache->sStbStatsCache.nBucket;
291,259!
441
    }
442

443
    SMetaStbStatsEntry* pEntryNew = (SMetaStbStatsEntry*)taosMemoryMalloc(sizeof(*pEntryNew));
19,796,344!
444
    if (pEntryNew == NULL) {
19,798,063!
445
      code = terrno;
×
446
      goto _exit;
×
447
    }
448

449
    pEntryNew->info = *pInfo;
19,798,063✔
450
    pEntryNew->next = pCache->sStbStatsCache.aBucket[iBucket];
19,797,055✔
451
    pCache->sStbStatsCache.aBucket[iBucket] = pEntryNew;
19,793,368✔
452
    pCache->sStbStatsCache.nEntry++;
19,796,969✔
453
  }
454

455
_exit:
213,883,827✔
456
  return code;
213,883,827✔
457
}
458

459
int32_t metaStatsCacheDrop(SMeta* pMeta, int64_t uid) {
2,423,819✔
460
  int32_t code = 0;
2,423,819✔
461

462
  SMetaCache*          pCache = pMeta->pCache;
2,423,819✔
463
  int32_t              iBucket = TABS(uid) % pCache->sStbStatsCache.nBucket;
2,425,169!
464
  SMetaStbStatsEntry** ppEntry = &pCache->sStbStatsCache.aBucket[iBucket];
2,426,584✔
465
  while (*ppEntry && (*ppEntry)->info.uid != uid) {
2,731,564✔
466
    ppEntry = &(*ppEntry)->next;
307,745✔
467
  }
468

469
  SMetaStbStatsEntry* pEntry = *ppEntry;
2,422,915✔
470
  if (pEntry) {
2,425,692✔
471
    *ppEntry = pEntry->next;
1,590,974✔
472
    taosMemoryFree(pEntry);
1,590,974!
473
    pCache->sStbStatsCache.nEntry--;
1,591,866✔
474
    if (pCache->sStbStatsCache.nEntry < pCache->sStbStatsCache.nBucket / 4 &&
1,590,974✔
475
        pCache->sStbStatsCache.nBucket > META_CACHE_STATS_BUCKET) {
1,005,997✔
476
      TAOS_UNUSED(metaRehashStatsCache(pCache, 0));
21,807✔
477
    }
478
  } else {
479
    code = TSDB_CODE_NOT_FOUND;
834,718✔
480
  }
481

482
_exit:
2,425,232✔
483
  return code;
2,425,232✔
484
}
485

486
int32_t metaStatsCacheGet(SMeta* pMeta, int64_t uid, SMetaStbStats* pInfo) {
688,431,501✔
487
  int32_t code = TSDB_CODE_SUCCESS;
688,431,501✔
488

489
  SMetaCache*         pCache = pMeta->pCache;
688,431,501✔
490
  int32_t             iBucket = TABS(uid) % pCache->sStbStatsCache.nBucket;
688,513,893!
491
  SMetaStbStatsEntry* pEntry = pCache->sStbStatsCache.aBucket[iBucket];
688,424,319✔
492

493
  while (pEntry && pEntry->info.uid != uid) {
776,003,355✔
494
    pEntry = pEntry->next;
87,464,045✔
495
  }
496

497
  if (pEntry) {
688,534,845✔
498
    if (pInfo) {
651,773,379✔
499
      *pInfo = pEntry->info;
651,771,063✔
500
    }
501
  } else {
502
    code = TSDB_CODE_NOT_FOUND;
36,761,466✔
503
  }
504

505
  return code;
688,532,499✔
506
}
507

508
static FORCE_INLINE void setMD5DigestInKey(uint64_t* pBuf, const char* key, int32_t keyLen) {
509
  memcpy(&pBuf[2], key, keyLen);
414,723,365!
510
}
414,708,965✔
511

512
// the format of key:
513
// hash table address(8bytes) + suid(8bytes) + MD5 digest(16bytes)
514
static void initCacheKey(uint64_t* buf, const SHashObj* pHashMap, uint64_t suid, const char* key, int32_t keyLen) {
414,698,740✔
515
  buf[0] = (uint64_t)pHashMap;
414,698,740✔
516
  buf[1] = suid;
414,711,210✔
517
  setMD5DigestInKey(buf, key, keyLen);
518
}
414,723,365✔
519

520
int32_t metaGetCachedTableUidList(void* pVnode, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray* pList1,
×
521
                                  bool* acquireRes) {
522
  SMeta*  pMeta = ((SVnode*)pVnode)->pMeta;
×
523
  int32_t vgId = TD_VID(pMeta->pVnode);
×
524

525
  // generate the composed key for LRU cache
526
  SLRUCache*     pCache = pMeta->pCache->sTagFilterResCache.pUidResCache;
×
527
  SHashObj*      pTableMap = pMeta->pCache->sTagFilterResCache.pTableEntry;
×
528
  TdThreadMutex* pLock = &pMeta->pCache->sTagFilterResCache.lock;
×
529

530
  *acquireRes = 0;
×
531
  uint64_t key[4];
×
532
  initCacheKey(key, pTableMap, suid, (const char*)pKey, keyLen);
×
533

534
  (void)taosThreadMutexLock(pLock);
×
535
  pMeta->pCache->sTagFilterResCache.accTimes += 1;
×
536

537
  LRUHandle* pHandle = taosLRUCacheLookup(pCache, key, TAG_FILTER_RES_KEY_LEN);
×
538
  if (pHandle == NULL) {
×
539
    (void)taosThreadMutexUnlock(pLock);
×
540
    return TSDB_CODE_SUCCESS;
×
541
  }
542

543
  // do some book mark work after acquiring the filter result from cache
544
  STagFilterResEntry** pEntry = taosHashGet(pTableMap, &suid, sizeof(uint64_t));
×
545
  if (NULL == pEntry) {
×
546
    metaError("meta/cache: pEntry should not be NULL.");
×
547
    return TSDB_CODE_NOT_FOUND;
×
548
  }
549

550
  *acquireRes = 1;
×
551

552
  const char* p = taosLRUCacheValue(pCache, pHandle);
×
553
  int32_t     size = *(int32_t*)p;
×
554

555
  // set the result into the buffer
556
  if (taosArrayAddBatch(pList1, p + sizeof(int32_t), size) == NULL) {
×
557
    return terrno;
×
558
  }
559

560
  (*pEntry)->hitTimes += 1;
×
561

562
  uint32_t acc = pMeta->pCache->sTagFilterResCache.accTimes;
×
563
  if ((*pEntry)->hitTimes % 5000 == 0 && (*pEntry)->hitTimes > 0) {
×
564
    metaInfo("vgId:%d cache hit:%d, total acc:%d, rate:%.2f", vgId, (*pEntry)->hitTimes, acc,
×
565
             ((double)(*pEntry)->hitTimes) / acc);
566
  }
567

568
  bool ret = taosLRUCacheRelease(pCache, pHandle, false);
×
569

570
  // unlock meta
571
  (void)taosThreadMutexUnlock(pLock);
×
572
  return TSDB_CODE_SUCCESS;
×
573
}
574

575
static void freeUidCachePayload(const void* key, size_t keyLen, void* value, void* ud) {
×
576
  (void)ud;
577
  if (value == NULL) {
×
578
    return;
×
579
  }
580

581
  const uint64_t* p = key;
×
582
  if (keyLen != sizeof(int64_t) * 4) {
×
583
    metaError("key length is invalid, length:%d, expect:%d", (int32_t)keyLen, (int32_t)sizeof(uint64_t) * 2);
×
584
    return;
×
585
  }
586

587
  SHashObj* pHashObj = (SHashObj*)p[0];
×
588

589
  STagFilterResEntry** pEntry = taosHashGet(pHashObj, &p[1], sizeof(uint64_t));
×
590

591
  if (pEntry != NULL && (*pEntry) != NULL) {
×
592
    int64_t st = taosGetTimestampUs();
×
593
    int32_t code = taosHashRemove((*pEntry)->set, &p[2], sizeof(uint64_t) * 2);
×
594
    if (code == TSDB_CODE_SUCCESS) {
×
595
      double el = (taosGetTimestampUs() - st) / 1000.0;
×
596
      metaInfo("clear items in meta-cache, remain cached item:%d, elapsed time:%.2fms", taosHashGetSize((*pEntry)->set),
×
597
               el);
598
    }
599
  }
600

601
  taosMemoryFree(value);
×
602
}
603

604
static int32_t addNewEntry(SHashObj* pTableEntry, const void* pKey, int32_t keyLen, uint64_t suid) {
×
605
  int32_t             code = TSDB_CODE_SUCCESS;
×
606
  int32_t             lino = 0;
×
607
  STagFilterResEntry* p = taosMemoryMalloc(sizeof(STagFilterResEntry));
×
608
  TSDB_CHECK_NULL(p, code, lino, _end, terrno);
×
609

610
  p->hitTimes = 0;
×
611
  p->set = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
×
612
  TSDB_CHECK_NULL(p->set, code, lino, _end, terrno);
×
613
  code = taosHashPut(p->set, pKey, keyLen, NULL, 0);
×
614
  TSDB_CHECK_CODE(code, lino, _end);
×
615
  code = taosHashPut(pTableEntry, &suid, sizeof(uint64_t), &p, POINTER_BYTES);
×
616
  TSDB_CHECK_CODE(code, lino, _end);
×
617

618
_end:
×
619
  if (code != TSDB_CODE_SUCCESS) {
×
620
    metaError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
621
    if (p != NULL) {
×
622
      if (p->set != NULL) {
×
623
        taosHashCleanup(p->set);
×
624
      }
625
      taosMemoryFree(p);
×
626
    }
627
  }
628
  return code;
×
629
}
630

631
// check both the payload size and selectivity ratio
632
int32_t metaUidFilterCachePut(void* pVnode, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload,
×
633
                              int32_t payloadLen, double selectivityRatio) {
634
  int32_t code = 0;
×
635
  SMeta*  pMeta = ((SVnode*)pVnode)->pMeta;
×
636
  int32_t vgId = TD_VID(pMeta->pVnode);
×
637

638
  if (selectivityRatio > tsSelectivityRatio) {
×
639
    metaDebug("vgId:%d, suid:%" PRIu64
×
640
              " failed to add to uid list cache, due to selectivity ratio %.2f less than threshold %.2f",
641
              vgId, suid, selectivityRatio, tsSelectivityRatio);
642
    taosMemoryFree(pPayload);
×
643
    return TSDB_CODE_SUCCESS;
×
644
  }
645

646
  if (payloadLen > tsTagFilterResCacheSize) {
×
647
    metaDebug("vgId:%d, suid:%" PRIu64
×
648
              " failed to add to uid list cache, due to payload length %d greater than threshold %d",
649
              vgId, suid, payloadLen, tsTagFilterResCacheSize);
650
    taosMemoryFree(pPayload);
×
651
    return TSDB_CODE_SUCCESS;
×
652
  }
653

654
  SLRUCache*     pCache = pMeta->pCache->sTagFilterResCache.pUidResCache;
×
655
  SHashObj*      pTableEntry = pMeta->pCache->sTagFilterResCache.pTableEntry;
×
656
  TdThreadMutex* pLock = &pMeta->pCache->sTagFilterResCache.lock;
×
657

658
  uint64_t key[4] = {0};
×
659
  initCacheKey(key, pTableEntry, suid, pKey, keyLen);
×
660

661
  (void)taosThreadMutexLock(pLock);
×
662
  STagFilterResEntry** pEntry = taosHashGet(pTableEntry, &suid, sizeof(uint64_t));
×
663
  if (pEntry == NULL) {
×
664
    code = addNewEntry(pTableEntry, pKey, keyLen, suid);
×
665
    if (code != TSDB_CODE_SUCCESS) {
×
666
      goto _end;
×
667
    }
668
  } else {  // check if it exists or not
669
    code = taosHashPut((*pEntry)->set, pKey, keyLen, NULL, 0);
×
670
    if (code == TSDB_CODE_DUP_KEY) {
×
671
      // we have already found the existed items, no need to added to cache anymore.
672
      (void)taosThreadMutexUnlock(pLock);
×
673
      return TSDB_CODE_SUCCESS;
×
674
    }
675
    if (code != TSDB_CODE_SUCCESS) {
×
676
      goto _end;
×
677
    }
678
  }
679

680
  // add to cache.
681
  (void)taosLRUCacheInsert(pCache, key, TAG_FILTER_RES_KEY_LEN, pPayload, payloadLen, freeUidCachePayload, NULL, NULL,
×
682
                           TAOS_LRU_PRIORITY_LOW, NULL);
683
_end:
×
684
  (void)taosThreadMutexUnlock(pLock);
×
685
  metaDebug("vgId:%d, suid:%" PRIu64 " list cache added into cache, total:%d, tables:%d", vgId, suid,
×
686
            (int32_t)taosLRUCacheGetUsage(pCache), taosHashGetSize(pTableEntry));
687

688
  return code;
×
689
}
690

691
void metaCacheClear(SMeta* pMeta) {
10,839,494✔
692
  metaWLock(pMeta);
10,839,494✔
693
  metaCacheClose(pMeta);
10,841,873✔
694
  metaCacheOpen(pMeta);
10,841,873✔
695
  metaULock(pMeta);
10,841,873✔
696
}
10,841,873✔
697

698
// remove the lru cache that are expired due to the tags value update, or creating, or dropping, of child tables
699
int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) {
207,336,229✔
700
  uint64_t  p[4] = {0};
207,336,229✔
701
  int32_t   vgId = TD_VID(pMeta->pVnode);
207,361,566✔
702
  SHashObj* pEntryHashMap = pMeta->pCache->sTagFilterResCache.pTableEntry;
207,356,224✔
703

704
  uint64_t dummy[2] = {0};
207,351,237✔
705
  initCacheKey(p, pEntryHashMap, suid, (char*)&dummy[0], 16);
207,363,636✔
706

707
  TdThreadMutex* pLock = &pMeta->pCache->sTagFilterResCache.lock;
207,340,825✔
708
  (void)taosThreadMutexLock(pLock);
207,365,669✔
709

710
  STagFilterResEntry** pEntry = taosHashGet(pEntryHashMap, &suid, sizeof(uint64_t));
207,388,589✔
711
  if (pEntry == NULL || taosHashGetSize((*pEntry)->set) == 0) {
207,370,379!
712
    (void)taosThreadMutexUnlock(pLock);
207,370,379✔
713
    return TSDB_CODE_SUCCESS;
207,360,233✔
714
  }
715

716
  (*pEntry)->hitTimes = 0;
×
717

718
  char *iter = taosHashIterate((*pEntry)->set, NULL);
×
719
  while (iter != NULL) {
×
720
    setMD5DigestInKey(p, iter, 2 * sizeof(uint64_t));
721
    taosLRUCacheErase(pMeta->pCache->sTagFilterResCache.pUidResCache, p, TAG_FILTER_RES_KEY_LEN);
×
722
    iter = taosHashIterate((*pEntry)->set, iter);
×
723
  }
724
  taosHashClear((*pEntry)->set);
×
725
  (void)taosThreadMutexUnlock(pLock);
×
726

727
  metaDebug("vgId:%d suid:%" PRId64 " cached related tag filter uid list cleared", vgId, suid);
×
728
  return TSDB_CODE_SUCCESS;
×
729
}
730

731
int32_t metaGetCachedTbGroup(void* pVnode, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray** pList) {
×
732
  SMeta*  pMeta = ((SVnode*)pVnode)->pMeta;
×
733
  int32_t vgId = TD_VID(pMeta->pVnode);
×
734

735
  // generate the composed key for LRU cache
736
  SLRUCache*     pCache = pMeta->pCache->STbGroupResCache.pResCache;
×
737
  SHashObj*      pTableMap = pMeta->pCache->STbGroupResCache.pTableEntry;
×
738
  TdThreadMutex* pLock = &pMeta->pCache->STbGroupResCache.lock;
×
739

740
  *pList = NULL;
×
741
  uint64_t key[4];
×
742
  initCacheKey(key, pTableMap, suid, (const char*)pKey, keyLen);
×
743

744
  (void)taosThreadMutexLock(pLock);
×
745
  pMeta->pCache->STbGroupResCache.accTimes += 1;
×
746

747
  LRUHandle* pHandle = taosLRUCacheLookup(pCache, key, TAG_FILTER_RES_KEY_LEN);
×
748
  if (pHandle == NULL) {
×
749
    (void)taosThreadMutexUnlock(pLock);
×
750
    return TSDB_CODE_SUCCESS;
×
751
  }
752

753
  STagFilterResEntry** pEntry = taosHashGet(pTableMap, &suid, sizeof(uint64_t));
×
754
  if (NULL == pEntry) {
×
755
    metaDebug("suid %" PRIu64 " not in tb group cache", suid);
×
756
    return TSDB_CODE_NOT_FOUND;
×
757
  }
758

759
  *pList = taosArrayDup(taosLRUCacheValue(pCache, pHandle), NULL);
×
760

761
  (*pEntry)->hitTimes += 1;
×
762

763
  uint32_t acc = pMeta->pCache->STbGroupResCache.accTimes;
×
764
  if ((*pEntry)->hitTimes % 5000 == 0 && (*pEntry)->hitTimes > 0) {
×
765
    metaInfo("vgId:%d tb group cache hit:%d, total acc:%d, rate:%.2f", vgId, (*pEntry)->hitTimes, acc,
×
766
             ((double)(*pEntry)->hitTimes) / acc);
767
  }
768

769
  bool ret = taosLRUCacheRelease(pCache, pHandle, false);
×
770

771
  // unlock meta
772
  (void)taosThreadMutexUnlock(pLock);
×
773
  return TSDB_CODE_SUCCESS;
×
774
}
775

776
static void freeTbGroupCachePayload(const void* key, size_t keyLen, void* value, void* ud) {
×
777
  (void)ud;
778
  if (value == NULL) {
×
779
    return;
×
780
  }
781

782
  const uint64_t* p = key;
×
783
  if (keyLen != sizeof(int64_t) * 4) {
×
784
    metaError("tb group key length is invalid, length:%d, expect:%d", (int32_t)keyLen, (int32_t)sizeof(uint64_t) * 2);
×
785
    return;
×
786
  }
787

788
  SHashObj* pHashObj = (SHashObj*)p[0];
×
789

790
  STagFilterResEntry** pEntry = taosHashGet(pHashObj, &p[1], sizeof(uint64_t));
×
791

792
  if (pEntry != NULL && (*pEntry) != NULL) {
×
793
    int64_t st = taosGetTimestampUs();
×
794
    int32_t code = taosHashRemove((*pEntry)->set, &p[2], sizeof(uint64_t) * 2);
×
795
    if (code == TSDB_CODE_SUCCESS) {
×
796
      double el = (taosGetTimestampUs() - st) / 1000.0;
×
797
      metaDebug("clear one item in tb group cache, remain cached item:%d, elapsed time:%.2fms",
×
798
                taosHashGetSize((*pEntry)->set), el);
799
    }
800
  }
801

802
  taosArrayDestroy((SArray*)value);
×
803
}
804

805
int32_t metaPutTbGroupToCache(void* pVnode, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload,
×
806
                              int32_t payloadLen) {
807
  int32_t code = 0;
×
808
  SMeta*  pMeta = ((SVnode*)pVnode)->pMeta;
×
809
  int32_t vgId = TD_VID(pMeta->pVnode);
×
810

811
  if (payloadLen > tsTagFilterResCacheSize) {
×
812
    metaDebug("vgId:%d, suid:%" PRIu64
×
813
              " ignore to add to tb group cache, due to payload length %d greater than threshold %d",
814
              vgId, suid, payloadLen, tsTagFilterResCacheSize);
815
    taosArrayDestroy((SArray*)pPayload);
×
816
    return TSDB_CODE_SUCCESS;
×
817
  }
818

819
  SLRUCache*     pCache = pMeta->pCache->STbGroupResCache.pResCache;
×
820
  SHashObj*      pTableEntry = pMeta->pCache->STbGroupResCache.pTableEntry;
×
821
  TdThreadMutex* pLock = &pMeta->pCache->STbGroupResCache.lock;
×
822

823
  uint64_t key[4] = {0};
×
824
  initCacheKey(key, pTableEntry, suid, pKey, keyLen);
×
825

826
  (void)taosThreadMutexLock(pLock);
×
827
  STagFilterResEntry** pEntry = taosHashGet(pTableEntry, &suid, sizeof(uint64_t));
×
828
  if (pEntry == NULL) {
×
829
    code = addNewEntry(pTableEntry, pKey, keyLen, suid);
×
830
    if (code != TSDB_CODE_SUCCESS) {
×
831
      goto _end;
×
832
    }
833
  } else {  // check if it exists or not
834
    code = taosHashPut((*pEntry)->set, pKey, keyLen, NULL, 0);
×
835
    if (code == TSDB_CODE_DUP_KEY) {
×
836
      // we have already found the existed items, no need to added to cache anymore.
837
      (void)taosThreadMutexUnlock(pLock);
×
838
      return TSDB_CODE_SUCCESS;
×
839
    }
840
    if (code != TSDB_CODE_SUCCESS) {
×
841
      goto _end;
×
842
    }
843
  }
844

845
  // add to cache.
846
  (void)taosLRUCacheInsert(pCache, key, TAG_FILTER_RES_KEY_LEN, pPayload, payloadLen, freeTbGroupCachePayload, NULL, NULL,
×
847
                           TAOS_LRU_PRIORITY_LOW, NULL);
848
_end:
×
849
  (void)taosThreadMutexUnlock(pLock);
×
850
  metaDebug("vgId:%d, suid:%" PRIu64 " tb group added into cache, total:%d, tables:%d", vgId, suid,
×
851
            (int32_t)taosLRUCacheGetUsage(pCache), taosHashGetSize(pTableEntry));
852

853
  return code;
×
854
}
855

856
// remove the lru cache that are expired due to the tags value update, or creating, or dropping, of child tables
857
int32_t metaTbGroupCacheClear(SMeta* pMeta, uint64_t suid) {
207,331,615✔
858
  uint64_t  p[4] = {0};
207,331,615✔
859
  int32_t   vgId = TD_VID(pMeta->pVnode);
207,341,441✔
860
  SHashObj* pEntryHashMap = pMeta->pCache->STbGroupResCache.pTableEntry;
207,334,974✔
861

862
  uint64_t dummy[2] = {0};
207,350,788✔
863
  initCacheKey(p, pEntryHashMap, suid, (char*)&dummy[0], 16);
207,361,071✔
864

865
  TdThreadMutex* pLock = &pMeta->pCache->STbGroupResCache.lock;
207,367,094✔
866
  (void)taosThreadMutexLock(pLock);
207,371,812✔
867

868
  STagFilterResEntry** pEntry = taosHashGet(pEntryHashMap, &suid, sizeof(uint64_t));
207,342,098✔
869
  if (pEntry == NULL || taosHashGetSize((*pEntry)->set) == 0) {
207,385,374!
870
    (void)taosThreadMutexUnlock(pLock);
207,385,374✔
871
    return TSDB_CODE_SUCCESS;
207,395,931✔
872
  }
873

874
  (*pEntry)->hitTimes = 0;
×
875

876
  char *iter = taosHashIterate((*pEntry)->set, NULL);
×
877
  while (iter != NULL) {
×
878
    setMD5DigestInKey(p, iter, 2 * sizeof(uint64_t));
879
    taosLRUCacheErase(pMeta->pCache->STbGroupResCache.pResCache, p, TAG_FILTER_RES_KEY_LEN);
×
880
    iter = taosHashIterate((*pEntry)->set, iter);
×
881
  }
882
  taosHashClear((*pEntry)->set);
×
883
  (void)taosThreadMutexUnlock(pLock);
×
884

885
  metaDebug("vgId:%d suid:%" PRId64 " cached related tb group cleared", vgId, suid);
×
886
  return TSDB_CODE_SUCCESS;
×
887
}
888

889
bool metaTbInFilterCache(SMeta* pMeta, const void* key, int8_t type) {
372,013,129✔
890
  if (type == 0 && taosHashGet(pMeta->pCache->STbFilterCache.pStb, key, sizeof(tb_uid_t))) {
372,013,129!
UNCOV
891
    return true;
×
892
  }
893

894
  if (type == 1 && taosHashGet(pMeta->pCache->STbFilterCache.pStbName, key, strlen(key))) {
372,013,129!
895
    return true;
×
896
  }
897

898
  return false;
372,087,357✔
899
}
900

UNCOV
901
int32_t metaPutTbToFilterCache(SMeta* pMeta, const void* key, int8_t type) {
×
UNCOV
902
  if (type == 0) {
×
UNCOV
903
    return taosHashPut(pMeta->pCache->STbFilterCache.pStb, key, sizeof(tb_uid_t), NULL, 0);
×
904
  }
905

UNCOV
906
  if (type == 1) {
×
UNCOV
907
    return taosHashPut(pMeta->pCache->STbFilterCache.pStbName, key, strlen(key), NULL, 0);
×
908
  }
909

910
  return 0;
×
911
}
912

UNCOV
913
int32_t metaSizeOfTbFilterCache(SMeta* pMeta, int8_t type) {
×
UNCOV
914
  if (type == 0) {
×
UNCOV
915
    return taosHashGetSize(pMeta->pCache->STbFilterCache.pStb);
×
916
  }
917
  return 0;
×
918
}
919

920
int32_t metaInitTbFilterCache(SMeta* pMeta) {
10,841,339✔
921
#ifdef TD_ENTERPRISE
922
  int32_t      tbNum = 0;
10,841,339✔
923
  const char** pTbArr = NULL;
10,841,339✔
924
  const char*  dbName = NULL;
10,841,339✔
925

926
  if (!(dbName = strchr(pMeta->pVnode->config.dbname, '.'))) return 0;
10,841,339!
927
  if (0 == strncmp(++dbName, "log", TSDB_DB_NAME_LEN)) {
10,843,359!
UNCOV
928
    tbNum = tkLogStbNum;
×
UNCOV
929
    pTbArr = (const char**)&tkLogStb;
×
930
  } else if (0 == strncmp(dbName, "audit", TSDB_DB_NAME_LEN)) {
10,843,359!
931
    tbNum = tkAuditStbNum;
×
932
    pTbArr = (const char**)&tkAuditStb;
×
933
  }
934
  if (tbNum && pTbArr) {
10,843,359!
UNCOV
935
    for (int32_t i = 0; i < tbNum; ++i) {
×
UNCOV
936
      TAOS_CHECK_RETURN(metaPutTbToFilterCache(pMeta, pTbArr[i], 1));
×
937
    }
938
  }
939
#else
940
#endif
941
  return 0;
10,843,359✔
942
}
943

944
int64_t metaGetStbKeep(SMeta* pMeta, int64_t uid) {
296,384✔
945
  SMetaStbStats stats = {0};
296,384✔
946

947
  if (metaStatsCacheGet(pMeta, uid, &stats) == TSDB_CODE_SUCCESS) {
296,384✔
948
    return stats.keep;
243,869✔
949
  }
950

951
  SMetaEntry* pEntry = NULL;
52,515✔
952
  if (metaFetchEntryByUid(pMeta, uid, &pEntry) == TSDB_CODE_SUCCESS) {
52,515!
953
    int64_t keep = -1;
52,515✔
954
    if (pEntry->type == TSDB_SUPER_TABLE) {
52,515!
955
      keep = pEntry->stbEntry.keep;
52,515✔
956
    }
957
    metaFetchEntryFree(&pEntry);
52,515✔
958
    return keep;
52,515✔
959
  }
960
  
961
  return -1;
×
962
}
963

964
int32_t metaRefDbsCacheClear(SMeta* pMeta, uint64_t suid) {
739,671✔
965
  int32_t        code = TSDB_CODE_SUCCESS;
739,671✔
966
  int32_t        vgId = TD_VID(pMeta->pVnode);
739,671✔
967
  SHashObj*      pEntryHashMap = pMeta->pCache->STbRefDbCache.pStbRefs;
739,671✔
968
  TdThreadMutex* pLock = &pMeta->pCache->STbRefDbCache.lock;
739,671✔
969

970
  (void)taosThreadMutexLock(pLock);
739,671✔
971

972
  SHashObj** pEntry = taosHashGet(pEntryHashMap, &suid, sizeof(uint64_t));
739,671✔
973
  if (pEntry == NULL) {
739,671✔
974
    goto _return;
732,284✔
975
  }
976

977
  taosHashRemove(pEntryHashMap, &suid, sizeof(uint64_t));
7,387✔
978

979
  metaDebug("vgId:%d suid:%" PRId64 " cached virtual stable ref db cleared", vgId, suid);
7,387✔
980

981
_return:
5,073✔
982
  (void)taosThreadMutexUnlock(pLock);
739,671✔
983
  return code;
739,671✔
984
}
985

986
int32_t metaGetCachedRefDbs(void* pVnode, tb_uid_t suid, SArray* pList) {
4,984,985✔
987
  int32_t        code = TSDB_CODE_SUCCESS;
4,984,985✔
988
  int32_t        line = 0;
4,984,985✔
989
  SMeta*         pMeta = ((SVnode*)pVnode)->pMeta;
4,984,985✔
990
  SHashObj*      pTableMap = pMeta->pCache->STbRefDbCache.pStbRefs;
4,984,984✔
991
  TdThreadMutex* pLock = &pMeta->pCache->STbRefDbCache.lock;
4,984,977✔
992

993
  (void)taosThreadMutexLock(pLock);
4,989,093✔
994

995
  SHashObj** pEntry = taosHashGet(pTableMap, &suid, sizeof(uint64_t));
4,989,093✔
996
  if (pEntry) {
4,984,995✔
997
    void *iter = taosHashIterate(*pEntry, NULL);
4,921,875✔
998
    while (iter != NULL) {
17,147,165✔
999
      size_t   dbNameLen = 0;
12,221,192✔
1000
      char*    name = NULL;
12,218,458✔
1001
      char*    dbName = NULL;
12,218,458✔
1002
      name = taosHashGetKey(iter, &dbNameLen);
12,221,191✔
1003
      TSDB_CHECK_NULL(name, code, line, _return, terrno);
12,212,985!
1004
      dbName = taosMemoryMalloc(dbNameLen + 1);
12,212,985!
1005
      TSDB_CHECK_NULL(dbName, code, line, _return, terrno);
12,217,087!
1006
      tstrncpy(dbName, name, dbNameLen + 1);
12,217,087!
1007
      TSDB_CHECK_NULL(taosArrayPush(pList, &dbName), code, line, _return, terrno);
12,221,191!
1008
      iter = taosHashIterate(*pEntry, iter);
12,221,191✔
1009
    }
1010
  }
1011

1012
_return:
4,989,093✔
1013
  if (code) {
4,986,358!
1014
    metaError("%s failed at line %d since %s", __func__, line, tstrerror(code));
×
1015
  }
1016
  (void)taosThreadMutexUnlock(pLock);
4,986,358✔
1017
  return code;
4,989,093✔
1018
}
1019

1020
static int32_t addRefDbsCacheNewEntry(SHashObj* pRefDbs, uint64_t suid, SHashObj **pEntry) {
63,120✔
1021
  int32_t      code = TSDB_CODE_SUCCESS;
63,120✔
1022
  int32_t      lino = 0;
63,120✔
1023
  SHashObj*    p = NULL;
63,120✔
1024

1025
  p = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
63,120✔
1026
  TSDB_CHECK_NULL(p, code, lino, _end, terrno);
63,120!
1027

1028
  code = taosHashPut(pRefDbs, &suid, sizeof(uint64_t), &p, POINTER_BYTES);
63,120✔
1029
  TSDB_CHECK_CODE(code, lino, _end);
63,120!
1030

1031
  *pEntry = p;
63,120✔
1032

1033
_end:
63,120✔
1034
  if (code != TSDB_CODE_SUCCESS) {
63,120!
1035
    metaError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
1036
  }
1037
  return code;
63,120✔
1038
}
1039

1040
int32_t metaPutRefDbsToCache(void* pVnode, tb_uid_t suid, SArray* pList) {
70,015✔
1041
  int32_t        code = 0;
70,015✔
1042
  int32_t        line = 0;
70,015✔
1043
  SMeta*         pMeta = ((SVnode*)pVnode)->pMeta;
70,015✔
1044
  SHashObj*      pStbRefs = pMeta->pCache->STbRefDbCache.pStbRefs;
70,015✔
1045
  TdThreadMutex* pLock = &pMeta->pCache->STbRefDbCache.lock;
70,015✔
1046

1047
  (void)taosThreadMutexLock(pLock);
70,015✔
1048

1049
  SHashObj*  pEntry = NULL;
70,015✔
1050
  SHashObj** find = taosHashGet(pStbRefs, &suid, sizeof(uint64_t));
70,015✔
1051
  if (find == NULL) {
70,015✔
1052
    code = addRefDbsCacheNewEntry(pStbRefs, suid, &pEntry);
63,120✔
1053
    TSDB_CHECK_CODE(code, line, _return);
63,120!
1054
  } else {  // check if it exists or not
1055
    pEntry = *find;
6,895✔
1056
  }
1057

1058
  for (int32_t i = 0; i < taosArrayGetSize(pList); i++) {
160,387✔
1059
    char* dbName = taosArrayGetP(pList, i);
90,372✔
1060
    void* pItem = taosHashGet(pEntry, dbName, strlen(dbName));
90,372!
1061
    if (pItem == NULL) {
90,372!
1062
      code = taosHashPut(pEntry, dbName, strlen(dbName), NULL, 0);
90,372!
1063
      TSDB_CHECK_CODE(code, line, _return);
90,372!
1064
    }
1065
  }
1066

1067
_return:
70,015✔
1068
  if (code) {
70,015!
1069
    metaError("%s failed at line %d since %s", __func__, line, tstrerror(code));
×
1070
  }
1071
  (void)taosThreadMutexUnlock(pLock);
70,015✔
1072

1073
  return code;
70,015✔
1074
}
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