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

taosdata / TDengine / #4848

12 Nov 2025 01:06AM UTC coverage: 63.27% (+0.6%) from 62.651%
#4848

push

travis-ci

web-flow
Merge f12882a7a into e27395247

33 of 36 new or added lines in 4 files covered. (91.67%)

2652 existing lines in 104 files now uncovered.

138980 of 219661 relevant lines covered (63.27%)

110230098.27 hits per line

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

77.76
/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) {
7,984,315✔
89
  if (pMeta->pCache) {
7,984,315✔
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;
73,591,291✔
95
        taosMemoryFree(pEntry);
73,591,291✔
96
        pEntry = tEntry;
73,591,291✔
97
      }
98
    }
99
    taosMemoryFree(pMeta->pCache->sEntryCache.aBucket);
7,984,330✔
100
  }
101
}
7,984,345✔
102

103
static void statsCacheClose(SMeta* pMeta) {
7,984,330✔
104
  if (pMeta->pCache) {
7,984,330✔
105
    // close entry cache
106
    for (int32_t iBucket = 0; iBucket < pMeta->pCache->sStbStatsCache.nBucket; iBucket++) {
141,035,915✔
107
      SMetaStbStatsEntry* pEntry = pMeta->pCache->sStbStatsCache.aBucket[iBucket];
133,051,498✔
108
      while (pEntry) {
139,161,520✔
109
        SMetaStbStatsEntry* tEntry = pEntry->next;
6,109,935✔
110
        taosMemoryFree(pEntry);
6,109,935✔
111
        pEntry = tEntry;
6,109,935✔
112
      }
113
    }
114
    taosMemoryFree(pMeta->pCache->sStbStatsCache.aBucket);
7,984,330✔
115
  }
116
}
7,984,330✔
117

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

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

130
int32_t metaCacheOpen(SMeta* pMeta) {
7,973,397✔
131
  int32_t code = 0;
7,973,397✔
132
  int32_t lino;
133

134
  pMeta->pCache = (SMetaCache*)taosMemoryCalloc(1, sizeof(SMetaCache));
7,973,397✔
135
  if (pMeta->pCache == NULL) {
7,983,554✔
136
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
137
  }
138

139
  // open entry cache
140
  pMeta->pCache->sEntryCache.nEntry = 0;
7,983,652✔
141
  pMeta->pCache->sEntryCache.nBucket = META_CACHE_BASE_BUCKET;
7,984,330✔
142
  pMeta->pCache->sEntryCache.aBucket =
7,995,021✔
143
      (SMetaCacheEntry**)taosMemoryCalloc(pMeta->pCache->sEntryCache.nBucket, sizeof(SMetaCacheEntry*));
7,983,652✔
144
  if (pMeta->pCache->sEntryCache.aBucket == NULL) {
7,983,901✔
145
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
146
  }
147

148
  // open stats cache
149
  pMeta->pCache->sStbStatsCache.nEntry = 0;
7,984,330✔
150
  pMeta->pCache->sStbStatsCache.nBucket = META_CACHE_STATS_BUCKET;
7,983,901✔
151
  pMeta->pCache->sStbStatsCache.aBucket =
7,995,021✔
152
      (SMetaStbStatsEntry**)taosMemoryCalloc(pMeta->pCache->sStbStatsCache.nBucket, sizeof(SMetaStbStatsEntry*));
7,984,330✔
153
  if (pMeta->pCache->sStbStatsCache.aBucket == NULL) {
7,984,330✔
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);
7,983,731✔
159
  if (pMeta->pCache->sTagFilterResCache.pUidResCache == NULL) {
7,984,330✔
160
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
161
  }
162

163
  pMeta->pCache->sTagFilterResCache.accTimes = 0;
7,984,330✔
164
  pMeta->pCache->sTagFilterResCache.pTableEntry =
15,968,660✔
165
      taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, HASH_NO_LOCK);
15,957,370✔
166
  if (pMeta->pCache->sTagFilterResCache.pTableEntry == NULL) {
7,984,330✔
167
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
168
  }
169

170
  taosHashSetFreeFp(pMeta->pCache->sTagFilterResCache.pTableEntry, freeCacheEntryFp);
7,984,330✔
171
  (void)taosThreadMutexInit(&pMeta->pCache->sTagFilterResCache.lock, NULL);
7,984,330✔
172

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

179
  pMeta->pCache->STbGroupResCache.accTimes = 0;
7,984,330✔
180
  pMeta->pCache->STbGroupResCache.pTableEntry =
15,968,660✔
181
      taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, HASH_NO_LOCK);
15,957,370✔
182
  if (pMeta->pCache->STbGroupResCache.pTableEntry == NULL) {
7,984,330✔
183
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
184
  }
185

186
  taosHashSetFreeFp(pMeta->pCache->STbGroupResCache.pTableEntry, freeCacheEntryFp);
7,984,330✔
187
  (void)taosThreadMutexInit(&pMeta->pCache->STbGroupResCache.lock, NULL);
7,984,330✔
188

189
  // open filter cache
190
  pMeta->pCache->STbFilterCache.pStb =
15,968,660✔
191
      taosHashInit(0, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
15,957,370✔
192
  if (pMeta->pCache->STbFilterCache.pStb == NULL) {
7,984,330✔
193
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
194
  }
195

196
  pMeta->pCache->STbFilterCache.pStbName =
15,968,660✔
197
      taosHashInit(0, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, HASH_NO_LOCK);
15,957,370✔
198
  if (pMeta->pCache->STbFilterCache.pStbName == NULL) {
7,984,330✔
199
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
200
  }
201

202
  // open ref db cache
203
  pMeta->pCache->STbRefDbCache.pStbRefs =
15,968,660✔
204
      taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
15,957,370✔
205
  if (pMeta->pCache->STbRefDbCache.pStbRefs == NULL) {
7,984,330✔
206
    TSDB_CHECK_CODE(code = terrno, lino, _exit);
×
207
  }
208

209
  taosHashSetFreeFp(pMeta->pCache->STbRefDbCache.pStbRefs, freeRefDbFp);
7,984,330✔
210
  (void)taosThreadMutexInit(&pMeta->pCache->STbRefDbCache.lock, NULL);
7,984,330✔
211

212

213
_exit:
7,984,330✔
214
  if (code) {
7,984,330✔
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__);
7,984,330✔
219
  }
220
  return code;
7,984,330✔
221
}
222

223
void metaCacheClose(SMeta* pMeta) {
7,984,315✔
224
  if (pMeta->pCache) {
7,984,315✔
225
    entryCacheClose(pMeta);
7,984,330✔
226
    statsCacheClose(pMeta);
7,984,330✔
227

228
    taosHashClear(pMeta->pCache->sTagFilterResCache.pTableEntry);
7,984,330✔
229
    taosLRUCacheCleanup(pMeta->pCache->sTagFilterResCache.pUidResCache);
7,984,330✔
230
    (void)taosThreadMutexDestroy(&pMeta->pCache->sTagFilterResCache.lock);
7,984,330✔
231
    taosHashCleanup(pMeta->pCache->sTagFilterResCache.pTableEntry);
7,984,330✔
232

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

238
    taosHashCleanup(pMeta->pCache->STbFilterCache.pStb);
7,984,330✔
239
    taosHashCleanup(pMeta->pCache->STbFilterCache.pStbName);
7,984,330✔
240

241
    taosHashClear(pMeta->pCache->STbRefDbCache.pStbRefs);
7,984,330✔
242
    (void)taosThreadMutexDestroy(&pMeta->pCache->STbRefDbCache.lock);
7,984,046✔
243
    taosHashCleanup(pMeta->pCache->STbRefDbCache.pStbRefs);
7,984,330✔
244

245
    taosMemoryFree(pMeta->pCache);
7,984,330✔
246
    pMeta->pCache = NULL;
7,984,330✔
247
  }
248
}
7,984,330✔
249

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

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

260
  SMetaCacheEntry** aBucket = (SMetaCacheEntry**)taosMemoryCalloc(nBucket, sizeof(SMetaCacheEntry*));
21,892✔
261
  if (aBucket == NULL) {
21,892✔
262
    return;
×
263
  }
264

265
  // rehash
266
  for (int32_t iBucket = 0; iBucket < pCache->sEntryCache.nBucket; iBucket++) {
65,359,236✔
267
    SMetaCacheEntry* pEntry = pCache->sEntryCache.aBucket[iBucket];
65,337,344✔
268

269
    while (pEntry) {
130,674,688✔
270
      SMetaCacheEntry* pTEntry = pEntry->next;
65,337,344✔
271

272
      pEntry->next = aBucket[TABS(pEntry->info.uid) % nBucket];
65,337,344✔
273
      aBucket[TABS(pEntry->info.uid) % nBucket] = pEntry;
65,337,344✔
274

275
      pEntry = pTEntry;
65,337,344✔
276
    }
277
  }
278

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

286
int32_t metaCacheUpsert(SMeta* pMeta, SMetaInfo* pInfo) {
95,854,470✔
287
  int32_t code = 0;
95,854,470✔
288

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

291
  // search
292
  SMetaCache*       pCache = pMeta->pCache;
95,854,470✔
293
  int32_t           iBucket = TABS(pInfo->uid) % pCache->sEntryCache.nBucket;
95,869,347✔
294
  SMetaCacheEntry** ppEntry = &pCache->sEntryCache.aBucket[iBucket];
95,858,634✔
295
  while (*ppEntry && (*ppEntry)->info.uid != pInfo->uid) {
109,600,218✔
296
    ppEntry = &(*ppEntry)->next;
13,734,582✔
297
  }
298

299
  if (*ppEntry) {  // update
95,835,361✔
300
    if (pInfo->suid != (*ppEntry)->info.suid) {
19,716,906✔
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) {
19,704,237✔
305
      (*ppEntry)->info.version = pInfo->version;
19,725,622✔
306
      (*ppEntry)->info.skmVer = pInfo->skmVer;
19,716,655✔
307
    }
308
  } else {  // insert
309
    if (pCache->sEntryCache.nEntry >= pCache->sEntryCache.nBucket) {
76,139,337✔
310
      metaRehashCache(pCache, 1);
21,892✔
311

312
      iBucket = TABS(pInfo->uid) % pCache->sEntryCache.nBucket;
21,892✔
313
    }
314

315
    SMetaCacheEntry* pEntryNew = (SMetaCacheEntry*)taosMemoryMalloc(sizeof(*pEntryNew));
76,142,648✔
316
    if (pEntryNew == NULL) {
76,134,335✔
317
      code = terrno;
×
318
      goto _exit;
×
319
    }
320

321
    pEntryNew->info = *pInfo;
76,134,335✔
322
    pEntryNew->next = pCache->sEntryCache.aBucket[iBucket];
76,138,042✔
323
    pCache->sEntryCache.aBucket[iBucket] = pEntryNew;
76,113,379✔
324
    pCache->sEntryCache.nEntry++;
76,136,336✔
325
  }
326

327
_exit:
95,851,933✔
328
  return code;
95,851,933✔
329
}
330

331
int32_t metaCacheDrop(SMeta* pMeta, int64_t uid) {
2,586,372✔
332
  int32_t code = 0;
2,586,372✔
333

334
  SMetaCache*       pCache = pMeta->pCache;
2,586,372✔
335
  int32_t           iBucket = TABS(uid) % pCache->sEntryCache.nBucket;
2,586,372✔
336
  SMetaCacheEntry** ppEntry = &pCache->sEntryCache.aBucket[iBucket];
2,587,029✔
337
  while (*ppEntry && (*ppEntry)->info.uid != uid) {
2,600,727✔
338
    ppEntry = &(*ppEntry)->next;
14,355✔
339
  }
340

341
  SMetaCacheEntry* pEntry = *ppEntry;
2,585,715✔
342
  if (pEntry) {
2,586,977✔
343
    *ppEntry = pEntry->next;
2,562,497✔
344
    taosMemoryFree(pEntry);
2,561,721✔
345
    pCache->sEntryCache.nEntry--;
2,561,892✔
346
    if (pCache->sEntryCache.nEntry < pCache->sEntryCache.nBucket / 4 &&
2,561,892✔
347
        pCache->sEntryCache.nBucket > META_CACHE_BASE_BUCKET) {
2,503,595✔
348
      metaRehashCache(pCache, 0);
×
349
    }
350
  } else {
351
    code = TSDB_CODE_NOT_FOUND;
24,480✔
352
  }
353

354
_exit:
2,586,318✔
355
  return code;
2,586,318✔
356
}
357

358
int32_t metaCacheGet(SMeta* pMeta, int64_t uid, SMetaInfo* pInfo) {
1,552,346,373✔
359
  int32_t code = 0;
1,552,346,373✔
360

361
  SMetaCache*      pCache = pMeta->pCache;
1,552,346,373✔
362
  int32_t          iBucket = TABS(uid) % pCache->sEntryCache.nBucket;
1,552,478,890✔
363
  SMetaCacheEntry* pEntry = pCache->sEntryCache.aBucket[iBucket];
1,552,492,437✔
364

365
  while (pEntry && pEntry->info.uid != uid) {
1,605,085,577✔
366
    pEntry = pEntry->next;
52,595,921✔
367
  }
368

369
  if (pEntry) {
1,552,492,740✔
370
    if (pInfo) {
1,467,882,990✔
371
      *pInfo = pEntry->info;
1,467,884,614✔
372
    }
373
  } else {
374
    code = TSDB_CODE_NOT_FOUND;
84,609,750✔
375
  }
376

377
  return code;
1,552,503,142✔
378
}
379

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

384
  if (expand) {
119,694✔
385
    nBucket = pCache->sStbStatsCache.nBucket * 2;
111,722✔
386
  } else {
387
    nBucket = pCache->sStbStatsCache.nBucket / 2;
7,972✔
388
  }
389

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

396
  // rehash
397
  for (int32_t iBucket = 0; iBucket < pCache->sStbStatsCache.nBucket; iBucket++) {
6,013,374✔
398
    SMetaStbStatsEntry* pEntry = pCache->sStbStatsCache.aBucket[iBucket];
5,893,680✔
399

400
    while (pEntry) {
11,483,708✔
401
      SMetaStbStatsEntry* pTEntry = pEntry->next;
5,590,028✔
402

403
      pEntry->next = aBucket[TABS(pEntry->info.uid) % nBucket];
5,590,028✔
404
      aBucket[TABS(pEntry->info.uid) % nBucket] = pEntry;
5,590,028✔
405

406
      pEntry = pTEntry;
5,590,028✔
407
    }
408
  }
409

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

415
_exit:
119,694✔
416
  return code;
119,694✔
417
}
418

419
int32_t metaStatsCacheUpsert(SMeta* pMeta, SMetaStbStats* pInfo) {
63,688,887✔
420
  int32_t code = 0;
63,688,887✔
421

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

424
  // search
425
  SMetaCache*          pCache = pMeta->pCache;
63,688,887✔
426
  int32_t              iBucket = TABS(pInfo->uid) % pCache->sStbStatsCache.nBucket;
63,693,291✔
427
  SMetaStbStatsEntry** ppEntry = &pCache->sStbStatsCache.aBucket[iBucket];
63,691,012✔
428
  while (*ppEntry && (*ppEntry)->info.uid != pInfo->uid) {
67,216,574✔
429
    ppEntry = &(*ppEntry)->next;
3,528,687✔
430
  }
431

432
  if (*ppEntry) {  // update
63,684,901✔
433
    (*ppEntry)->info.ctbNum = pInfo->ctbNum;
56,958,720✔
434
    (*ppEntry)->info.colNum = pInfo->colNum;
56,955,918✔
435
    (*ppEntry)->info.flags = pInfo->flags;
56,963,338✔
436
    (*ppEntry)->info.keep = pInfo->keep;
56,948,021✔
437
  } else {  // insert
438
    if (pCache->sStbStatsCache.nEntry >= pCache->sStbStatsCache.nBucket) {
6,734,939✔
439
      TAOS_UNUSED(metaRehashStatsCache(pCache, 1));
111,722✔
440
      iBucket = TABS(pInfo->uid) % pCache->sStbStatsCache.nBucket;
111,722✔
441
    }
442

443
    SMetaStbStatsEntry* pEntryNew = (SMetaStbStatsEntry*)taosMemoryMalloc(sizeof(*pEntryNew));
6,726,581✔
444
    if (pEntryNew == NULL) {
6,725,930✔
445
      code = terrno;
×
446
      goto _exit;
×
447
    }
448

449
    pEntryNew->info = *pInfo;
6,725,930✔
450
    pEntryNew->next = pCache->sStbStatsCache.aBucket[iBucket];
6,726,605✔
451
    pCache->sStbStatsCache.aBucket[iBucket] = pEntryNew;
6,726,311✔
452
    pCache->sStbStatsCache.nEntry++;
6,726,525✔
453
  }
454

455
_exit:
63,682,977✔
456
  return code;
63,682,977✔
457
}
458

459
int32_t metaStatsCacheDrop(SMeta* pMeta, int64_t uid) {
967,791✔
460
  int32_t code = 0;
967,791✔
461

462
  SMetaCache*          pCache = pMeta->pCache;
967,791✔
463
  int32_t              iBucket = TABS(uid) % pCache->sStbStatsCache.nBucket;
968,448✔
464
  SMetaStbStatsEntry** ppEntry = &pCache->sStbStatsCache.aBucket[iBucket];
967,791✔
465
  while (*ppEntry && (*ppEntry)->info.uid != uid) {
1,099,991✔
466
    ppEntry = &(*ppEntry)->next;
132,200✔
467
  }
468

469
  SMetaStbStatsEntry* pEntry = *ppEntry;
967,791✔
470
  if (pEntry) {
967,791✔
471
    *ppEntry = pEntry->next;
616,694✔
472
    taosMemoryFree(pEntry);
616,694✔
473
    pCache->sStbStatsCache.nEntry--;
616,694✔
474
    if (pCache->sStbStatsCache.nEntry < pCache->sStbStatsCache.nBucket / 4 &&
616,694✔
475
        pCache->sStbStatsCache.nBucket > META_CACHE_STATS_BUCKET) {
403,892✔
476
      TAOS_UNUSED(metaRehashStatsCache(pCache, 0));
7,972✔
477
    }
478
  } else {
479
    code = TSDB_CODE_NOT_FOUND;
351,097✔
480
  }
481

482
_exit:
968,448✔
483
  return code;
968,448✔
484
}
485

486
int32_t metaStatsCacheGet(SMeta* pMeta, int64_t uid, SMetaStbStats* pInfo) {
252,832,691✔
487
  int32_t code = TSDB_CODE_SUCCESS;
252,832,691✔
488

489
  SMetaCache*         pCache = pMeta->pCache;
252,832,691✔
490
  int32_t             iBucket = TABS(uid) % pCache->sStbStatsCache.nBucket;
252,846,465✔
491
  SMetaStbStatsEntry* pEntry = pCache->sStbStatsCache.aBucket[iBucket];
252,841,081✔
492

493
  while (pEntry && pEntry->info.uid != uid) {
290,092,522✔
494
    pEntry = pEntry->next;
37,239,678✔
495
  }
496

497
  if (pEntry) {
252,852,632✔
498
    if (pInfo) {
235,677,230✔
499
      *pInfo = pEntry->info;
235,677,849✔
500
    }
501
  } else {
502
    code = TSDB_CODE_NOT_FOUND;
17,175,402✔
503
  }
504

505
  return code;
252,849,088✔
506
}
507

508
static FORCE_INLINE void setMD5DigestInKey(uint64_t* pBuf, const char* key, int32_t keyLen) {
509
  memcpy(&pBuf[2], key, keyLen);
133,632,467✔
510
}
133,597,947✔
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) {
133,627,395✔
515
  buf[0] = (uint64_t)pHashMap;
133,627,395✔
516
  buf[1] = suid;
133,628,528✔
517
  setMD5DigestInKey(buf, key, keyLen);
518
}
133,631,647✔
519

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

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

530
  *acquireRes = 0;
7,790✔
531
  uint64_t key[4];
7,790✔
532
  initCacheKey(key, pTableMap, suid, (const char*)pKey, keyLen);
7,790✔
533
  
534
  // void* tmp = NULL;
535
  // uint32_t len = 0;
536
  // (void)taosAscii2Hex((const char*)key, 32, &tmp, &len);
537
  // qDebug("metaGetCachedTableUidList %p %"PRId64" key: %s", pTableMap, suid, tmp);
538
  // taosMemoryFree(tmp);
539

540
  (void)taosThreadMutexLock(pLock);
7,790✔
541
  pMeta->pCache->sTagFilterResCache.accTimes += 1;
7,790✔
542

543
  LRUHandle* pHandle = taosLRUCacheLookup(pCache, key, TAG_FILTER_RES_KEY_LEN);
7,790✔
544
  if (pHandle == NULL) {
7,790✔
545
    (void)taosThreadMutexUnlock(pLock);
3,690✔
546
    return TSDB_CODE_SUCCESS;
3,690✔
547
  }
548

549
  // do some book mark work after acquiring the filter result from cache
550
  STagFilterResEntry** pEntry = taosHashGet(pTableMap, &suid, sizeof(uint64_t));
4,100✔
551
  if (NULL == pEntry) {
4,100✔
552
    metaError("meta/cache: pEntry should not be NULL.");
×
553
    return TSDB_CODE_NOT_FOUND;
×
554
  }
555

556
  *acquireRes = 1;
4,100✔
557

558
  const char* p = taosLRUCacheValue(pCache, pHandle);
4,100✔
559
  int32_t     size = *(int32_t*)p;
4,100✔
560

561
  // set the result into the buffer
562
  if (taosArrayAddBatch(pList1, p + sizeof(int32_t), size) == NULL) {
4,100✔
563
    return terrno;
×
564
  }
565

566
  (*pEntry)->hitTimes += 1;
4,100✔
567

568
  uint32_t acc = pMeta->pCache->sTagFilterResCache.accTimes;
4,100✔
569
  if ((*pEntry)->hitTimes % 5000 == 0 && (*pEntry)->hitTimes > 0) {
4,100✔
570
    metaInfo("vgId:%d cache hit:%d, total acc:%d, rate:%.2f", vgId, (*pEntry)->hitTimes, acc,
×
571
             ((double)(*pEntry)->hitTimes) / acc);
572
  }
573

574
  bool ret = taosLRUCacheRelease(pCache, pHandle, false);
4,100✔
575

576
  // unlock meta
577
  (void)taosThreadMutexUnlock(pLock);
4,100✔
578
  return TSDB_CODE_SUCCESS;
4,100✔
579
}
580

581
static void freeUidCachePayload(const void* key, size_t keyLen, void* value, void* ud) {
3,690✔
582
  (void)ud;
583
  if (value == NULL) {
3,690✔
584
    return;
×
585
  }
586

587
  const uint64_t* p = key;
3,690✔
588
  if (keyLen != sizeof(int64_t) * 4) {
3,690✔
589
    metaError("key length is invalid, length:%d, expect:%d", (int32_t)keyLen, (int32_t)sizeof(uint64_t) * 2);
×
590
    return;
×
591
  }
592

593
  SHashObj* pHashObj = (SHashObj*)p[0];
3,690✔
594

595
  STagFilterResEntry** pEntry = taosHashGet(pHashObj, &p[1], sizeof(uint64_t));
3,690✔
596

597
  if (pEntry != NULL && (*pEntry) != NULL) {
3,690✔
598
    int64_t st = taosGetTimestampUs();
820✔
599
    int32_t code = taosHashRemove((*pEntry)->set, &p[2], sizeof(uint64_t) * 2);
820✔
600
    if (code == TSDB_CODE_SUCCESS) {
820✔
601
      double el = (taosGetTimestampUs() - st) / 1000.0;
820✔
602
      metaInfo("clear items in meta-cache, remain cached item:%d, elapsed time:%.2fms", taosHashGetSize((*pEntry)->set),
820✔
603
               el);
604
    }
605
  }
606

607
  taosMemoryFree(value);
3,690✔
608
}
609

610
static int32_t addNewEntry(SHashObj* pTableEntry, const void* pKey, int32_t keyLen, uint64_t suid) {
1,230✔
611
  int32_t             code = TSDB_CODE_SUCCESS;
1,230✔
612
  int32_t             lino = 0;
1,230✔
613
  STagFilterResEntry* p = taosMemoryMalloc(sizeof(STagFilterResEntry));
1,230✔
614
  TSDB_CHECK_NULL(p, code, lino, _end, terrno);
1,230✔
615

616
  p->hitTimes = 0;
1,230✔
617
  p->set = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
1,230✔
618
  TSDB_CHECK_NULL(p->set, code, lino, _end, terrno);
1,230✔
619
  code = taosHashPut(p->set, pKey, keyLen, NULL, 0);
1,230✔
620
  TSDB_CHECK_CODE(code, lino, _end);
1,230✔
621
  code = taosHashPut(pTableEntry, &suid, sizeof(uint64_t), &p, POINTER_BYTES);
1,230✔
622
  TSDB_CHECK_CODE(code, lino, _end);
1,230✔
623

624
_end:
1,230✔
625
  if (code != TSDB_CODE_SUCCESS) {
1,230✔
626
    metaError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
×
627
    if (p != NULL) {
×
628
      if (p->set != NULL) {
×
629
        taosHashCleanup(p->set);
×
630
      }
631
      taosMemoryFree(p);
×
632
    }
633
  }
634
  return code;
1,230✔
635
}
636

637
// check both the payload size and selectivity ratio
638
int32_t metaUidFilterCachePut(void* pVnode, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload,
3,690✔
639
                              int32_t payloadLen, double selectivityRatio) {
640
  int32_t code = 0;
3,690✔
641
  SMeta*  pMeta = ((SVnode*)pVnode)->pMeta;
3,690✔
642
  int32_t vgId = TD_VID(pMeta->pVnode);
3,690✔
643

644
  if (selectivityRatio > tsSelectivityRatio) {
3,690✔
645
    metaDebug("vgId:%d, suid:%" PRIu64
×
646
              " failed to add to uid list cache, due to selectivity ratio %.2f less than threshold %.2f",
647
              vgId, suid, selectivityRatio, tsSelectivityRatio);
648
    taosMemoryFree(pPayload);
×
649
    return TSDB_CODE_SUCCESS;
×
650
  }
651

652
  if (payloadLen > tsTagFilterResCacheSize) {
3,690✔
653
    metaDebug("vgId:%d, suid:%" PRIu64
×
654
              " failed to add to uid list cache, due to payload length %d greater than threshold %d",
655
              vgId, suid, payloadLen, tsTagFilterResCacheSize);
656
    taosMemoryFree(pPayload);
×
657
    return TSDB_CODE_SUCCESS;
×
658
  }
659

660
  SLRUCache*     pCache = pMeta->pCache->sTagFilterResCache.pUidResCache;
3,690✔
661
  SHashObj*      pTableEntry = pMeta->pCache->sTagFilterResCache.pTableEntry;
3,690✔
662
  TdThreadMutex* pLock = &pMeta->pCache->sTagFilterResCache.lock;
3,690✔
663

664
  uint64_t key[4] = {0};
3,690✔
665
  initCacheKey(key, pTableEntry, suid, pKey, keyLen);
3,690✔
666

667
  // void* tmp = NULL;
668
  // uint32_t len = 0;
669
  // (void)taosAscii2Hex((const char*)key, 32, &tmp, &len);
670
  // qDebug("metaUidFilterCachePut %p %"PRId64" key: %s", pTableEntry, suid, tmp);
671
  // taosMemoryFree(tmp);
672

673
  (void)taosThreadMutexLock(pLock);
3,690✔
674
  STagFilterResEntry** pEntry = taosHashGet(pTableEntry, &suid, sizeof(uint64_t));
3,690✔
675
  if (pEntry == NULL) {
3,690✔
676
    code = addNewEntry(pTableEntry, pKey, keyLen, suid);
1,230✔
677
    if (code != TSDB_CODE_SUCCESS) {
1,230✔
678
      goto _end;
×
679
    }
680
  } else {  // check if it exists or not
681
    code = taosHashPut((*pEntry)->set, pKey, keyLen, NULL, 0);
2,460✔
682
    if (code == TSDB_CODE_DUP_KEY) {
2,460✔
683
      // we have already found the existed items, no need to added to cache anymore.
684
      (void)taosThreadMutexUnlock(pLock);
×
685
      return TSDB_CODE_SUCCESS;
×
686
    }
687
    if (code != TSDB_CODE_SUCCESS) {
2,460✔
688
      goto _end;
×
689
    }
690
  }
691

692
  // add to cache.
693
  (void)taosLRUCacheInsert(pCache, key, TAG_FILTER_RES_KEY_LEN, pPayload, payloadLen, freeUidCachePayload, NULL, NULL,
3,690✔
694
                           TAOS_LRU_PRIORITY_LOW, NULL);
695
_end:
3,690✔
696
  (void)taosThreadMutexUnlock(pLock);
3,690✔
697
  metaDebug("vgId:%d, suid:%" PRIu64 " list cache added into cache, total:%d, tables:%d", vgId, suid,
3,690✔
698
            (int32_t)taosLRUCacheGetUsage(pCache), taosHashGetSize(pTableEntry));
699

700
  return code;
3,690✔
701
}
702

703
void metaCacheClear(SMeta* pMeta) {
3,990,833✔
704
  metaWLock(pMeta);
3,990,833✔
705
  metaCacheClose(pMeta);
3,990,833✔
706
  (void)metaCacheOpen(pMeta);
3,990,833✔
707
  metaULock(pMeta);
3,990,833✔
708
}
3,990,818✔
709

710
// remove the lru cache that are expired due to the tags value update, or creating, or dropping, of child tables
711
int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) {
66,807,721✔
712
  uint64_t  p[4] = {0};
66,807,721✔
713
  int32_t   vgId = TD_VID(pMeta->pVnode);
66,809,972✔
714
  SHashObj* pEntryHashMap = pMeta->pCache->sTagFilterResCache.pTableEntry;
66,809,349✔
715

716
  uint64_t dummy[2] = {0};
66,811,305✔
717
  initCacheKey(p, pEntryHashMap, suid, (char*)&dummy[0], 16);
66,811,624✔
718

719
  TdThreadMutex* pLock = &pMeta->pCache->sTagFilterResCache.lock;
66,808,904✔
720
  (void)taosThreadMutexLock(pLock);
66,809,794✔
721

722
  STagFilterResEntry** pEntry = taosHashGet(pEntryHashMap, &suid, sizeof(uint64_t));
66,814,980✔
723
  if (pEntry == NULL || taosHashGetSize((*pEntry)->set) == 0) {
66,812,297✔
724
    (void)taosThreadMutexUnlock(pLock);
66,811,477✔
725
    return TSDB_CODE_SUCCESS;
66,812,779✔
726
  }
727

728
  (*pEntry)->hitTimes = 0;
820✔
729

730
  char *iter = taosHashIterate((*pEntry)->set, NULL);
820✔
731
  while (iter != NULL) {
1,640✔
732
    setMD5DigestInKey(p, iter, 2 * sizeof(uint64_t));
733
    taosLRUCacheErase(pMeta->pCache->sTagFilterResCache.pUidResCache, p, TAG_FILTER_RES_KEY_LEN);
820✔
734
    iter = taosHashIterate((*pEntry)->set, iter);
820✔
735
  }
736
  taosHashClear((*pEntry)->set);
820✔
737
  (void)taosThreadMutexUnlock(pLock);
820✔
738

739
  metaDebug("vgId:%d suid:%" PRId64 " cached related tag filter uid list cleared", vgId, suid);
820✔
740
  return TSDB_CODE_SUCCESS;
820✔
741
}
742

743
int32_t metaGetCachedTbGroup(void* pVnode, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray** pList) {
×
744
  SMeta*  pMeta = ((SVnode*)pVnode)->pMeta;
×
745
  int32_t vgId = TD_VID(pMeta->pVnode);
×
746

747
  // generate the composed key for LRU cache
748
  SLRUCache*     pCache = pMeta->pCache->STbGroupResCache.pResCache;
×
749
  SHashObj*      pTableMap = pMeta->pCache->STbGroupResCache.pTableEntry;
×
750
  TdThreadMutex* pLock = &pMeta->pCache->STbGroupResCache.lock;
×
751

752
  *pList = NULL;
×
753
  uint64_t key[4];
×
754
  initCacheKey(key, pTableMap, suid, (const char*)pKey, keyLen);
×
755

756
  (void)taosThreadMutexLock(pLock);
×
757
  pMeta->pCache->STbGroupResCache.accTimes += 1;
×
758

759
  LRUHandle* pHandle = taosLRUCacheLookup(pCache, key, TAG_FILTER_RES_KEY_LEN);
×
760
  if (pHandle == NULL) {
×
761
    (void)taosThreadMutexUnlock(pLock);
×
762
    return TSDB_CODE_SUCCESS;
×
763
  }
764

765
  STagFilterResEntry** pEntry = taosHashGet(pTableMap, &suid, sizeof(uint64_t));
×
766
  if (NULL == pEntry) {
×
767
    metaDebug("suid %" PRIu64 " not in tb group cache", suid);
×
768
    return TSDB_CODE_NOT_FOUND;
×
769
  }
770

771
  *pList = taosArrayDup(taosLRUCacheValue(pCache, pHandle), NULL);
×
772

773
  (*pEntry)->hitTimes += 1;
×
774

775
  uint32_t acc = pMeta->pCache->STbGroupResCache.accTimes;
×
776
  if ((*pEntry)->hitTimes % 5000 == 0 && (*pEntry)->hitTimes > 0) {
×
777
    metaInfo("vgId:%d tb group cache hit:%d, total acc:%d, rate:%.2f", vgId, (*pEntry)->hitTimes, acc,
×
778
             ((double)(*pEntry)->hitTimes) / acc);
779
  }
780

781
  bool ret = taosLRUCacheRelease(pCache, pHandle, false);
×
782

783
  // unlock meta
784
  (void)taosThreadMutexUnlock(pLock);
×
785
  return TSDB_CODE_SUCCESS;
×
786
}
787

788
static void freeTbGroupCachePayload(const void* key, size_t keyLen, void* value, void* ud) {
×
789
  (void)ud;
790
  if (value == NULL) {
×
791
    return;
×
792
  }
793

794
  const uint64_t* p = key;
×
795
  if (keyLen != sizeof(int64_t) * 4) {
×
796
    metaError("tb group key length is invalid, length:%d, expect:%d", (int32_t)keyLen, (int32_t)sizeof(uint64_t) * 2);
×
797
    return;
×
798
  }
799

800
  SHashObj* pHashObj = (SHashObj*)p[0];
×
801

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

804
  if (pEntry != NULL && (*pEntry) != NULL) {
×
805
    int64_t st = taosGetTimestampUs();
×
806
    int32_t code = taosHashRemove((*pEntry)->set, &p[2], sizeof(uint64_t) * 2);
×
807
    if (code == TSDB_CODE_SUCCESS) {
×
808
      double el = (taosGetTimestampUs() - st) / 1000.0;
×
809
      metaDebug("clear one item in tb group cache, remain cached item:%d, elapsed time:%.2fms",
×
810
                taosHashGetSize((*pEntry)->set), el);
811
    }
812
  }
813

814
  taosArrayDestroy((SArray*)value);
×
815
}
816

817
int32_t metaPutTbGroupToCache(void* pVnode, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload,
×
818
                              int32_t payloadLen) {
819
  int32_t code = 0;
×
820
  SMeta*  pMeta = ((SVnode*)pVnode)->pMeta;
×
821
  int32_t vgId = TD_VID(pMeta->pVnode);
×
822

823
  if (payloadLen > tsTagFilterResCacheSize) {
×
824
    metaDebug("vgId:%d, suid:%" PRIu64
×
825
              " ignore to add to tb group cache, due to payload length %d greater than threshold %d",
826
              vgId, suid, payloadLen, tsTagFilterResCacheSize);
827
    taosArrayDestroy((SArray*)pPayload);
×
828
    return TSDB_CODE_SUCCESS;
×
829
  }
830

831
  SLRUCache*     pCache = pMeta->pCache->STbGroupResCache.pResCache;
×
832
  SHashObj*      pTableEntry = pMeta->pCache->STbGroupResCache.pTableEntry;
×
833
  TdThreadMutex* pLock = &pMeta->pCache->STbGroupResCache.lock;
×
834

835
  uint64_t key[4] = {0};
×
836
  initCacheKey(key, pTableEntry, suid, pKey, keyLen);
×
837

838
  (void)taosThreadMutexLock(pLock);
×
839
  STagFilterResEntry** pEntry = taosHashGet(pTableEntry, &suid, sizeof(uint64_t));
×
840
  if (pEntry == NULL) {
×
841
    code = addNewEntry(pTableEntry, pKey, keyLen, suid);
×
842
    if (code != TSDB_CODE_SUCCESS) {
×
843
      goto _end;
×
844
    }
845
  } else {  // check if it exists or not
846
    code = taosHashPut((*pEntry)->set, pKey, keyLen, NULL, 0);
×
847
    if (code == TSDB_CODE_DUP_KEY) {
×
848
      // we have already found the existed items, no need to added to cache anymore.
849
      (void)taosThreadMutexUnlock(pLock);
×
850
      return TSDB_CODE_SUCCESS;
×
851
    }
852
    if (code != TSDB_CODE_SUCCESS) {
×
853
      goto _end;
×
854
    }
855
  }
856

857
  // add to cache.
858
  (void)taosLRUCacheInsert(pCache, key, TAG_FILTER_RES_KEY_LEN, pPayload, payloadLen, freeTbGroupCachePayload, NULL, NULL,
×
859
                           TAOS_LRU_PRIORITY_LOW, NULL);
860
_end:
×
861
  (void)taosThreadMutexUnlock(pLock);
×
862
  metaDebug("vgId:%d, suid:%" PRIu64 " tb group added into cache, total:%d, tables:%d", vgId, suid,
×
863
            (int32_t)taosLRUCacheGetUsage(pCache), taosHashGetSize(pTableEntry));
864

865
  return code;
×
866
}
867

868
// remove the lru cache that are expired due to the tags value update, or creating, or dropping, of child tables
869
int32_t metaTbGroupCacheClear(SMeta* pMeta, uint64_t suid) {
66,807,340✔
870
  uint64_t  p[4] = {0};
66,807,340✔
871
  int32_t   vgId = TD_VID(pMeta->pVnode);
66,809,889✔
872
  SHashObj* pEntryHashMap = pMeta->pCache->STbGroupResCache.pTableEntry;
66,810,051✔
873

874
  uint64_t dummy[2] = {0};
66,809,432✔
875
  initCacheKey(p, pEntryHashMap, suid, (char*)&dummy[0], 16);
66,811,165✔
876

877
  TdThreadMutex* pLock = &pMeta->pCache->STbGroupResCache.lock;
66,810,570✔
878
  (void)taosThreadMutexLock(pLock);
66,811,222✔
879

880
  STagFilterResEntry** pEntry = taosHashGet(pEntryHashMap, &suid, sizeof(uint64_t));
66,810,930✔
881
  if (pEntry == NULL || taosHashGetSize((*pEntry)->set) == 0) {
66,813,539✔
882
    (void)taosThreadMutexUnlock(pLock);
66,813,539✔
883
    return TSDB_CODE_SUCCESS;
66,815,691✔
884
  }
885

886
  (*pEntry)->hitTimes = 0;
×
887

888
  char *iter = taosHashIterate((*pEntry)->set, NULL);
×
889
  while (iter != NULL) {
×
890
    setMD5DigestInKey(p, iter, 2 * sizeof(uint64_t));
891
    taosLRUCacheErase(pMeta->pCache->STbGroupResCache.pResCache, p, TAG_FILTER_RES_KEY_LEN);
×
892
    iter = taosHashIterate((*pEntry)->set, iter);
×
893
  }
894
  taosHashClear((*pEntry)->set);
×
895
  (void)taosThreadMutexUnlock(pLock);
×
896

897
  metaDebug("vgId:%d suid:%" PRId64 " cached related tb group cleared", vgId, suid);
×
898
  return TSDB_CODE_SUCCESS;
×
899
}
900

901
bool metaTbInFilterCache(SMeta* pMeta, const void* key, int8_t type) {
114,988,290✔
902
  if (type == 0 && taosHashGet(pMeta->pCache->STbFilterCache.pStb, key, sizeof(tb_uid_t))) {
114,988,290✔
903
    return true;
1,040✔
904
  }
905

906
  if (type == 1 && taosHashGet(pMeta->pCache->STbFilterCache.pStbName, key, strlen(key))) {
114,987,250✔
907
    return true;
×
908
  }
909

910
  return false;
114,991,638✔
911
}
912

913
int32_t metaPutTbToFilterCache(SMeta* pMeta, const void* key, int8_t type) {
6,240✔
914
  if (type == 0) {
6,240✔
915
    return taosHashPut(pMeta->pCache->STbFilterCache.pStb, key, sizeof(tb_uid_t), NULL, 0);
2,288✔
916
  }
917

918
  if (type == 1) {
3,952✔
919
    return taosHashPut(pMeta->pCache->STbFilterCache.pStbName, key, strlen(key), NULL, 0);
3,952✔
920
  }
921

922
  return 0;
×
923
}
924

925
int32_t metaSizeOfTbFilterCache(SMeta* pMeta, int8_t type) {
3,744✔
926
  if (type == 0) {
3,744✔
927
    return taosHashGetSize(pMeta->pCache->STbFilterCache.pStb);
3,744✔
928
  }
929
  return 0;
×
930
}
931

932
int32_t metaInitTbFilterCache(SMeta* pMeta) {
3,993,137✔
933
#ifdef TD_ENTERPRISE
934
  int32_t      tbNum = 0;
3,993,137✔
935
  const char** pTbArr = NULL;
3,993,137✔
936
  const char*  dbName = NULL;
3,993,137✔
937

938
  if (!(dbName = strchr(pMeta->pVnode->config.dbname, '.'))) return 0;
3,993,137✔
939
  if (0 == strncmp(++dbName, "log", TSDB_DB_NAME_LEN)) {
3,992,245✔
940
    tbNum = tkLogStbNum;
208✔
941
    pTbArr = (const char**)&tkLogStb;
208✔
942
  } else if (0 == strncmp(dbName, "audit", TSDB_DB_NAME_LEN)) {
3,992,037✔
943
    tbNum = tkAuditStbNum;
×
944
    pTbArr = (const char**)&tkAuditStb;
×
945
  }
946
  if (tbNum && pTbArr) {
3,992,245✔
947
    for (int32_t i = 0; i < tbNum; ++i) {
4,160✔
948
      TAOS_CHECK_RETURN(metaPutTbToFilterCache(pMeta, pTbArr[i], 1));
3,952✔
949
    }
950
  }
951
#else
952
#endif
953
  return 0;
3,992,245✔
954
}
955

956
int64_t metaGetStbKeep(SMeta* pMeta, int64_t uid) {
172,159✔
957
  SMetaStbStats stats = {0};
172,159✔
958

959
  if (metaStatsCacheGet(pMeta, uid, &stats) == TSDB_CODE_SUCCESS) {
172,159✔
960
    return stats.keep;
152,645✔
961
  }
962

963
  SMetaEntry* pEntry = NULL;
18,248✔
964
  if (metaFetchEntryByUid(pMeta, uid, &pEntry) == TSDB_CODE_SUCCESS) {
18,248✔
965
    int64_t keep = -1;
17,633✔
966
    if (pEntry->type == TSDB_SUPER_TABLE) {
17,633✔
967
      keep = pEntry->stbEntry.keep;
17,633✔
968
    }
969
    metaFetchEntryFree(&pEntry);
17,633✔
970
    return keep;
17,633✔
971
  }
972
  
973
  return -1;
615✔
974
}
975

976
int32_t metaRefDbsCacheClear(SMeta* pMeta, uint64_t suid) {
293,700✔
977
  int32_t        code = TSDB_CODE_SUCCESS;
293,700✔
978
  int32_t        vgId = TD_VID(pMeta->pVnode);
293,700✔
979
  SHashObj*      pEntryHashMap = pMeta->pCache->STbRefDbCache.pStbRefs;
293,700✔
980
  TdThreadMutex* pLock = &pMeta->pCache->STbRefDbCache.lock;
293,700✔
981

982
  (void)taosThreadMutexLock(pLock);
293,700✔
983

984
  SHashObj** pEntry = taosHashGet(pEntryHashMap, &suid, sizeof(uint64_t));
293,700✔
985
  if (pEntry == NULL) {
293,700✔
986
    goto _return;
290,943✔
987
  }
988

989
  code = taosHashRemove(pEntryHashMap, &suid, sizeof(uint64_t));
2,757✔
990

991
  metaDebug("vgId:%d suid:%" PRId64 " cached virtual stable ref db cleared", vgId, suid);
2,757✔
992

993
_return:
1,989✔
994
  (void)taosThreadMutexUnlock(pLock);
293,700✔
995
  return code;
293,700✔
996
}
997

998
int32_t metaGetVirtualSupertableVersion(void *pVnode, tb_uid_t suid, int32_t *version) {
2,109,832✔
999
  int32_t        code = TSDB_CODE_SUCCESS;
2,109,832✔
1000
  SVnode*        vnode = (SVnode*)pVnode;
2,109,832✔
1001

2,109,832✔
1002
  (void)taosThreadRwlockRdlock(&vnode->versionLock);
2,109,832✔
1003
  int32_t* ver = taosHashGet(vnode->pVtableVersion, &suid, sizeof(tb_uid_t));
2,109,828✔
1004
  if (ver != NULL) {
1005
    *version = (*ver);
2,108,645✔
1006
  } else {
1007
    *version = 0;
2,110,394✔
1008
  }
2,109,832✔
1009
  (void)taosThreadRwlockUnlock(&vnode->versionLock);
2,089,314✔
1010
  return code;
7,249,298✔
1011
}
5,159,422✔
1012

5,158,251✔
1013
int32_t metaGetVirtualNormalChildtableVersion(void *pVnode, tb_uid_t uid, int32_t *version) {
5,158,251✔
1014
  int         code = TSDB_CODE_SUCCESS;
5,158,251✔
1015
  int32_t     lino = 0;
5,157,736✔
1016
  SMetaReader mr = {0};
5,157,736✔
1017
  metaReaderDoInit(&mr, ((SVnode *)pVnode)->pMeta, META_READER_LOCK);
5,156,561✔
1018
  code = metaReaderGetTableEntryByUid(&mr, uid);
5,156,561✔
1019
  TSDB_CHECK_CODE(code, lino, _return);
5,159,422✔
1020

5,159,422✔
1021
  *version = mr.me.colRef.version;
1022

1023
_return:
1024
  if (code != TSDB_CODE_SUCCESS) {
2,110,394✔
1025
    metaError("%s failed since %s, line %d", __func__, tstrerror(code), lino);
2,110,394✔
NEW
1026
  }
×
1027
  metaReaderClear(&mr);
1028
  return code;
2,110,394✔
1029
}
2,110,394✔
1030

1031
int32_t metaGetCachedRefDbs(void* pVnode, tb_uid_t suid, SArray* pList) {
1032
  int32_t        code = TSDB_CODE_SUCCESS;
20,518✔
1033
  int32_t        line = 0;
20,518✔
1034
  SMeta*         pMeta = ((SVnode*)pVnode)->pMeta;
20,518✔
1035
  SHashObj*      pTableMap = pMeta->pCache->STbRefDbCache.pStbRefs;
20,518✔
1036
  TdThreadMutex* pLock = &pMeta->pCache->STbRefDbCache.lock;
1037

20,518✔
1038
  (void)taosThreadMutexLock(pLock);
20,518✔
1039

1040
  SHashObj** pEntry = taosHashGet(pTableMap, &suid, sizeof(uint64_t));
20,518✔
1041
  if (pEntry) {
20,518✔
1042
    void *iter = taosHashIterate(*pEntry, NULL);
1043
    while (iter != NULL) {
20,518✔
1044
      size_t   dbNameLen = 0;
1045
      char*    name = NULL;
20,518✔
1046
      char*    dbName = NULL;
20,518✔
UNCOV
1047
      name = taosHashGetKey(iter, &dbNameLen);
×
1048
      TSDB_CHECK_NULL(name, code, line, _return, terrno);
1049
      dbName = taosMemoryMalloc(dbNameLen + 1);
20,518✔
1050
      TSDB_CHECK_NULL(dbName, code, line, _return, terrno);
1051
      tstrncpy(dbName, name, dbNameLen + 1);
1052
      TSDB_CHECK_NULL(taosArrayPush(pList, &dbName), code, line, _return, terrno);
23,618✔
1053
      iter = taosHashIterate(*pEntry, iter);
23,618✔
1054
    }
23,618✔
1055
  }
23,618✔
1056

23,618✔
1057
_return:
23,618✔
1058
  if (code) {
1059
    metaError("%s failed at line %d since %s", __func__, line, tstrerror(code));
23,618✔
1060
  }
1061
  (void)taosThreadMutexUnlock(pLock);
23,618✔
1062
  return code;
23,618✔
1063
}
23,618✔
1064

20,518✔
1065
static int32_t addRefDbsCacheNewEntry(SHashObj* pRefDbs, uint64_t suid, SHashObj **pEntry) {
20,518✔
1066
  int32_t      code = TSDB_CODE_SUCCESS;
1067
  int32_t      lino = 0;
3,100✔
1068
  SHashObj*    p = NULL;
1069

1070
  p = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
55,573✔
1071
  TSDB_CHECK_NULL(p, code, lino, _end, terrno);
31,955✔
1072

31,955✔
1073
  code = taosHashPut(pRefDbs, &suid, sizeof(uint64_t), &p, POINTER_BYTES);
31,955✔
1074
  TSDB_CHECK_CODE(code, lino, _end);
31,955✔
1075

31,955✔
1076
  *pEntry = p;
1077

1078
_end:
1079
  if (code != TSDB_CODE_SUCCESS) {
23,618✔
1080
    metaError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
23,618✔
UNCOV
1081
  }
×
1082
  return code;
1083
}
23,618✔
1084

1085
int32_t metaPutRefDbsToCache(void* pVnode, tb_uid_t suid, SArray* pList) {
23,618✔
1086
  int32_t        code = 0;
1087
  int32_t        line = 0;
1088
  SMeta*         pMeta = ((SVnode*)pVnode)->pMeta;
1089
  SHashObj*      pStbRefs = pMeta->pCache->STbRefDbCache.pStbRefs;
1090
  TdThreadMutex* pLock = &pMeta->pCache->STbRefDbCache.lock;
1091

1092
  (void)taosThreadMutexLock(pLock);
1093

1094
  SHashObj*  pEntry = NULL;
1095
  SHashObj** find = taosHashGet(pStbRefs, &suid, sizeof(uint64_t));
1096
  if (find == NULL) {
1097
    code = addRefDbsCacheNewEntry(pStbRefs, suid, &pEntry);
1098
    TSDB_CHECK_CODE(code, line, _return);
1099
  } else {  // check if it exists or not
1100
    pEntry = *find;
1101
  }
1102

1103
  for (int32_t i = 0; i < taosArrayGetSize(pList); i++) {
1104
    char* dbName = taosArrayGetP(pList, i);
1105
    void* pItem = taosHashGet(pEntry, dbName, strlen(dbName));
1106
    if (pItem == NULL) {
1107
      code = taosHashPut(pEntry, dbName, strlen(dbName), NULL, 0);
1108
      TSDB_CHECK_CODE(code, line, _return);
1109
    }
1110
  }
1111

1112
_return:
1113
  if (code) {
1114
    metaError("%s failed at line %d since %s", __func__, line, tstrerror(code));
1115
  }
1116
  (void)taosThreadMutexUnlock(pLock);
1117

1118
  return code;
1119
}
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