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

H
Hongze Cheng 已提交
16
#include "meta.h"
H
Hongze Cheng 已提交
17

H
Hongze Cheng 已提交
18
void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) {
H
Hongze Cheng 已提交
19 20
  memset(pReader, 0, sizeof(*pReader));
  pReader->flags = flags;
H
Hongze Cheng 已提交
21
  pReader->pMeta = pMeta;
22 23 24
  if (!(flags & META_READER_NOLOCK)) {
    metaRLock(pMeta);
  }
H
Hongze Cheng 已提交
25
}
H
Hongze Cheng 已提交
26

27 28 29 30 31 32 33
void metaReaderReleaseLock(SMetaReader *pReader) {
  if (pReader->pMeta && !(pReader->flags & META_READER_NOLOCK)) {
    metaULock(pReader->pMeta);
    pReader->flags |= META_READER_NOLOCK;
  }
}

H
Hongze Cheng 已提交
34
void metaReaderClear(SMetaReader *pReader) {
35
  if (pReader->pMeta && !(pReader->flags & META_READER_NOLOCK)) {
H
Hongze Cheng 已提交
36 37
    metaULock(pReader->pMeta);
  }
H
Hongze Cheng 已提交
38
  tDecoderClear(&pReader->coder);
H
Hongze Cheng 已提交
39
  tdbFree(pReader->pBuf);
H
Hongze Cheng 已提交
40 41
}

H
Hongze Cheng 已提交
42
int metaGetTableEntryByVersion(SMetaReader *pReader, int64_t version, tb_uid_t uid) {
H
Hongze Cheng 已提交
43
  SMeta   *pMeta = pReader->pMeta;
H
Hongze Cheng 已提交
44 45
  STbDbKey tbDbKey = {.version = version, .uid = uid};

H
Hongze Cheng 已提交
46
  // query table.db
H
Hongze Cheng 已提交
47
  if (tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pReader->pBuf, &pReader->szBuf) < 0) {
H
Hongze Cheng 已提交
48
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
49 50 51 52
    goto _err;
  }

  // decode the entry
H
Hongze Cheng 已提交
53
  tDecoderInit(&pReader->coder, pReader->pBuf, pReader->szBuf);
H
Hongze Cheng 已提交
54 55 56 57 58 59 60 61 62 63 64

  if (metaDecodeEntry(&pReader->coder, &pReader->me) < 0) {
    goto _err;
  }

  return 0;

_err:
  return -1;
}

dengyihao's avatar
dengyihao 已提交
65
// int metaGetTableEntryByUidTest(void* meta, SArray *uidList) {
wmmhello's avatar
wmmhello 已提交
66
//
dengyihao's avatar
dengyihao 已提交
67 68 69 70 71
//   SArray* readerList = taosArrayInit(taosArrayGetSize(uidList), sizeof(SMetaReader));
//   SArray* uidVersion = taosArrayInit(taosArrayGetSize(uidList), sizeof(STbDbKey));
//   SMeta  *pMeta = meta;
//   int64_t version;
//   SHashObj *uHash = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
wmmhello's avatar
wmmhello 已提交
72
//
dengyihao's avatar
dengyihao 已提交
73 74 75 76 77 78 79 80 81 82
//   int64_t stt1 = taosGetTimestampUs();
//   for(int i = 0; i < taosArrayGetSize(uidList); i++) {
//     void* ppVal = NULL;
//     int vlen = 0;
//     uint64_t *  uid = taosArrayGet(uidList, i);
//     // query uid.idx
//     if (tdbTbGet(pMeta->pUidIdx, uid, sizeof(*uid), &ppVal, &vlen) < 0) {
//       continue;
//     }
//     version = *(int64_t *)ppVal;
wmmhello's avatar
wmmhello 已提交
83
//
dengyihao's avatar
dengyihao 已提交
84 85 86 87 88 89
//     STbDbKey tbDbKey = {.version = version, .uid = *uid};
//     taosArrayPush(uidVersion, &tbDbKey);
//     taosHashPut(uHash, uid, sizeof(int64_t), ppVal, sizeof(int64_t));
//   }
//   int64_t stt2 = taosGetTimestampUs();
//   qDebug("metaGetTableEntryByUidTest1 rows:%d, cost:%ld us", taosArrayGetSize(uidList), stt2-stt1);
wmmhello's avatar
wmmhello 已提交
90
//
dengyihao's avatar
dengyihao 已提交
91 92 93 94 95
//   TBC        *pCur = NULL;
//   tdbTbcOpen(pMeta->pTbDb, &pCur, NULL);
//   tdbTbcMoveToFirst(pCur);
//   void *pKey = NULL;
//   int   kLen = 0;
wmmhello's avatar
wmmhello 已提交
96
//
dengyihao's avatar
dengyihao 已提交
97 98 99 100 101 102 103 104 105 106
//   while(1){
//     SMetaReader pReader = {0};
//     int32_t ret = tdbTbcNext(pCur, &pKey, &kLen, &pReader.pBuf, &pReader.szBuf);
//     if (ret < 0) break;
//     STbDbKey *tmp = (STbDbKey*)pKey;
//     int64_t *ver = (int64_t*)taosHashGet(uHash, &tmp->uid, sizeof(int64_t));
//     if(ver == NULL || *ver != tmp->version) continue;
//     taosArrayPush(readerList, &pReader);
//   }
//   tdbTbcClose(pCur);
wmmhello's avatar
wmmhello 已提交
107
//
dengyihao's avatar
dengyihao 已提交
108 109 110 111 112
//   taosArrayClear(readerList);
//   int64_t stt3 = taosGetTimestampUs();
//   qDebug("metaGetTableEntryByUidTest2 rows:%d, cost:%ld us", taosArrayGetSize(uidList), stt3-stt2);
//   for(int i = 0; i < taosArrayGetSize(uidVersion); i++) {
//     SMetaReader pReader = {0};
wmmhello's avatar
wmmhello 已提交
113
//
dengyihao's avatar
dengyihao 已提交
114 115 116 117 118 119 120 121 122
//     STbDbKey *tbDbKey = taosArrayGet(uidVersion, i);
//     // query table.db
//     if (tdbTbGet(pMeta->pTbDb, tbDbKey, sizeof(STbDbKey), &pReader.pBuf, &pReader.szBuf) < 0) {
//       continue;
//     }
//     taosArrayPush(readerList, &pReader);
//   }
//   int64_t stt4 = taosGetTimestampUs();
//   qDebug("metaGetTableEntryByUidTest3 rows:%d, cost:%ld us", taosArrayGetSize(uidList), stt4-stt3);
wmmhello's avatar
wmmhello 已提交
123
//
dengyihao's avatar
dengyihao 已提交
124 125 126 127 128
//   for(int i = 0; i < taosArrayGetSize(readerList); i++){
//     SMetaReader* pReader  = taosArrayGet(readerList, i);
//     metaReaderInit(pReader, meta, 0);
//     // decode the entry
//     tDecoderInit(&pReader->coder, pReader->pBuf, pReader->szBuf);
wmmhello's avatar
wmmhello 已提交
129
//
dengyihao's avatar
dengyihao 已提交
130 131 132 133 134 135 136 137
//     if (metaDecodeEntry(&pReader->coder, &pReader->me) < 0) {
//     }
//     metaReaderClear(pReader);
//   }
//   int64_t stt5 = taosGetTimestampUs();
//   qDebug("metaGetTableEntryByUidTest4 rows:%d, cost:%ld us", taosArrayGetSize(readerList), stt5-stt4);
//   return 0;
// }
wmmhello's avatar
wmmhello 已提交
138

H
Hongze Cheng 已提交
139
bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid) {
140
  // query uid.idx
141 142
  metaRLock(pMeta);

143
  if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), NULL, NULL) < 0) {
144 145
    metaULock(pMeta);

146 147 148
    return false;
  }

149 150
  metaULock(pMeta);

151 152 153
  return true;
}

H
Hongze Cheng 已提交
154
int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) {
155 156
  SMeta *pMeta = pReader->pMeta;
  /*
157
  int64_t version1;
H
Hongze Cheng 已提交
158 159

  // query uid.idx
H
Hongze Cheng 已提交
160
  if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pReader->pBuf, &pReader->szBuf) < 0) {
H
Hongze Cheng 已提交
161
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
162 163 164
    return -1;
  }

165 166
  version1 = ((SUidIdxVal *)pReader->pBuf)[0].version;
  return metaGetTableEntryByVersion(pReader, version1, uid);
167 168 169 170 171 172 173 174
  */
  SMetaInfo info;
  if (metaGetInfo(pMeta, uid, &info) == TSDB_CODE_NOT_FOUND) {
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
    return -1;
  }

  return metaGetTableEntryByVersion(pReader, info.version, uid);
H
Hongze Cheng 已提交
175 176
}

H
Hongze Cheng 已提交
177
int metaGetTableEntryByName(SMetaReader *pReader, const char *name) {
H
Hongze Cheng 已提交
178
  SMeta   *pMeta = pReader->pMeta;
H
Hongze Cheng 已提交
179 180 181
  tb_uid_t uid;

  // query name.idx
H
Hongze Cheng 已提交
182
  if (tdbTbGet(pMeta->pNameIdx, name, strlen(name) + 1, &pReader->pBuf, &pReader->szBuf) < 0) {
H
Hongze Cheng 已提交
183
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
H
Hongze Cheng 已提交
184 185 186 187
    return -1;
  }

  uid = *(tb_uid_t *)pReader->pBuf;
H
Hongze Cheng 已提交
188
  return metaGetTableEntryByUid(pReader, uid);
H
Hongze Cheng 已提交
189 190
}

H
Hongze Cheng 已提交
191
tb_uid_t metaGetTableEntryUidByName(SMeta *pMeta, const char *name) {
H
Hongze Cheng 已提交
192
  void    *pData = NULL;
H
Hongze Cheng 已提交
193 194 195
  int      nData = 0;
  tb_uid_t uid = 0;

wmmhello's avatar
wmmhello 已提交
196 197
  metaRLock(pMeta);

H
Hongze Cheng 已提交
198 199 200 201 202
  if (tdbTbGet(pMeta->pNameIdx, name, strlen(name) + 1, &pData, &nData) == 0) {
    uid = *(tb_uid_t *)pData;
    tdbFree(pData);
  }

wmmhello's avatar
wmmhello 已提交
203 204
  metaULock(pMeta);

205
  return uid;
H
Hongze Cheng 已提交
206 207
}

dengyihao's avatar
dengyihao 已提交
208
int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName) {
209
  int         code = 0;
D
dapan1121 已提交
210
  SMetaReader mr = {0};
dengyihao's avatar
dengyihao 已提交
211
  metaReaderInit(&mr, (SMeta *)meta, 0);
212 213 214 215 216
  code = metaGetTableEntryByUid(&mr, uid);
  if (code < 0) {
    metaReaderClear(&mr);
    return -1;
  }
D
dapan1121 已提交
217 218 219 220 221 222

  STR_TO_VARSTR(tbName, mr.me.name);
  metaReaderClear(&mr);

  return 0;
}
H
Haojun Liao 已提交
223
int metaGetTableUidByName(void *meta, char *tbName, uint64_t *uid) {
dengyihao's avatar
dengyihao 已提交
224 225 226
  int         code = 0;
  SMetaReader mr = {0};
  metaReaderInit(&mr, (SMeta *)meta, 0);
dengyihao's avatar
dengyihao 已提交
227 228 229 230

  SMetaReader *pReader = &mr;

  // query name.idx
dengyihao's avatar
dengyihao 已提交
231
  if (tdbTbGet(pReader->pMeta->pNameIdx, tbName, strlen(tbName) + 1, &pReader->pBuf, &pReader->szBuf) < 0) {
dengyihao's avatar
dengyihao 已提交
232
    terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
dengyihao's avatar
dengyihao 已提交
233 234 235 236
    metaReaderClear(&mr);
    return -1;
  }

dengyihao's avatar
dengyihao 已提交
237
  *uid = *(tb_uid_t *)pReader->pBuf;
dengyihao's avatar
dengyihao 已提交
238

dengyihao's avatar
dengyihao 已提交
239 240 241 242
  metaReaderClear(&mr);

  return 0;
}
D
dapan1121 已提交
243

dengyihao's avatar
dengyihao 已提交
244 245 246 247 248
int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType) {
  int         code = 0;
  SMetaReader mr = {0};
  metaReaderInit(&mr, (SMeta *)meta, 0);

dengyihao's avatar
dengyihao 已提交
249 250 251
  code = metaGetTableEntryByName(&mr, tbName);
  if (code == 0) *tbType = mr.me.type;

dengyihao's avatar
dengyihao 已提交
252
  metaReaderClear(&mr);
dengyihao's avatar
dengyihao 已提交
253
  return code;
dengyihao's avatar
dengyihao 已提交
254 255
}

H
Hongze Cheng 已提交
256
int metaReadNext(SMetaReader *pReader) {
H
Hongze Cheng 已提交
257 258
  SMeta *pMeta = pReader->pMeta;

H
Hongze Cheng 已提交
259
  // TODO
H
Hongze Cheng 已提交
260

H
Hongze Cheng 已提交
261 262 263 264
  return 0;
}

#if 1  // ===================================================
H
Hongze Cheng 已提交
265 266 267 268 269 270 271 272
SMTbCursor *metaOpenTbCursor(SMeta *pMeta) {
  SMTbCursor *pTbCur = NULL;

  pTbCur = (SMTbCursor *)taosMemoryCalloc(1, sizeof(*pTbCur));
  if (pTbCur == NULL) {
    return NULL;
  }

H
Hongze Cheng 已提交
273
  metaReaderInit(&pTbCur->mr, pMeta, 0);
H
Hongze Cheng 已提交
274

H
Hongze Cheng 已提交
275
  tdbTbcOpen(pMeta->pUidIdx, &pTbCur->pDbc, NULL);
H
Hongze Cheng 已提交
276

H
Hongze Cheng 已提交
277
  tdbTbcMoveToFirst(pTbCur->pDbc);
H
Hongze Cheng 已提交
278

H
Hongze Cheng 已提交
279 280 281 282 283
  return pTbCur;
}

void metaCloseTbCursor(SMTbCursor *pTbCur) {
  if (pTbCur) {
H
Hongze Cheng 已提交
284 285
    tdbFree(pTbCur->pKey);
    tdbFree(pTbCur->pVal);
H
Hongze Cheng 已提交
286
    metaReaderClear(&pTbCur->mr);
H
Hongze Cheng 已提交
287
    if (pTbCur->pDbc) {
H
Hongze Cheng 已提交
288
      tdbTbcClose(pTbCur->pDbc);
H
Hongze Cheng 已提交
289 290 291 292 293
    }
    taosMemoryFree(pTbCur);
  }
}

H
Hongze Cheng 已提交
294
int metaTbCursorNext(SMTbCursor *pTbCur) {
H
Hongze Cheng 已提交
295
  int    ret;
H
Hongze Cheng 已提交
296
  void  *pBuf;
H
Hongze Cheng 已提交
297 298 299
  STbCfg tbCfg;

  for (;;) {
H
Hongze Cheng 已提交
300
    ret = tdbTbcNext(pTbCur->pDbc, &pTbCur->pKey, &pTbCur->kLen, &pTbCur->pVal, &pTbCur->vLen);
H
Hongze Cheng 已提交
301 302
    if (ret < 0) {
      return -1;
H
Hongze Cheng 已提交
303 304
    }

M
Minglei Jin 已提交
305 306
    tDecoderClear(&pTbCur->mr.coder);

H
Hongze Cheng 已提交
307
    metaGetTableEntryByVersion(&pTbCur->mr, ((SUidIdxVal *)pTbCur->pVal)[0].version, *(tb_uid_t *)pTbCur->pKey);
H
Hongze Cheng 已提交
308
    if (pTbCur->mr.me.type == TSDB_SUPER_TABLE) {
H
Hongze Cheng 已提交
309 310
      continue;
    }
H
Hongze Cheng 已提交
311 312

    break;
H
Hongze Cheng 已提交
313 314
  }

H
Hongze Cheng 已提交
315
  return 0;
H
Hongze Cheng 已提交
316 317
}

318
SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) {
H
Hongze Cheng 已提交
319
  void           *pData = NULL;
H
Hongze Cheng 已提交
320 321 322 323 324
  int             nData = 0;
  int64_t         version;
  SSchemaWrapper  schema = {0};
  SSchemaWrapper *pSchema = NULL;
  SDecoder        dc = {0};
325 326 327
  if (lock) {
    metaRLock(pMeta);
  }
H
Hongze Cheng 已提交
328 329 330 331
_query:
  if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData) < 0) {
    goto _err;
  }
H
Hongze Cheng 已提交
332

H
Hongze Cheng 已提交
333
  version = ((SUidIdxVal *)pData)[0].version;
H
Hongze Cheng 已提交
334

H
Hongze Cheng 已提交
335 336 337 338 339 340
  tdbTbGet(pMeta->pTbDb, &(STbDbKey){.uid = uid, .version = version}, sizeof(STbDbKey), &pData, &nData);
  SMetaEntry me = {0};
  tDecoderInit(&dc, pData, nData);
  metaDecodeEntry(&dc, &me);
  if (me.type == TSDB_SUPER_TABLE) {
    if (sver == -1 || sver == me.stbEntry.schemaRow.version) {
H
Hongze Cheng 已提交
341
      pSchema = tCloneSSchemaWrapper(&me.stbEntry.schemaRow);
H
Hongze Cheng 已提交
342 343
      tDecoderClear(&dc);
      goto _exit;
H
Hongze Cheng 已提交
344
    }
345 346
    {  // Traverse to find the previous qualified data
      TBC *pCur;
347 348
      tdbTbcOpen(pMeta->pTbDb, &pCur, NULL);
      STbDbKey key = {.version = sver, .uid = INT64_MAX};
349
      int      c = 0;
350
      tdbTbcMoveTo(pCur, &key, sizeof(key), &c);
351
      if (c < 0) {
352 353 354 355 356 357
        tdbTbcMoveToPrev(pCur);
      }

      void *pKey = NULL;
      void *pVal = NULL;
      int   vLen = 0, kLen = 0;
358
      while (1) {
359 360 361
        int32_t ret = tdbTbcPrev(pCur, &pKey, &kLen, &pVal, &vLen);
        if (ret < 0) break;

362 363
        STbDbKey *tmp = (STbDbKey *)pKey;
        if (tmp->uid != uid) {
364 365 366 367 368 369 370 371 372
          continue;
        }
        SDecoder   dcNew = {0};
        SMetaEntry meNew = {0};
        tDecoderInit(&dcNew, pVal, vLen);
        metaDecodeEntry(&dcNew, &meNew);
        pSchema = tCloneSSchemaWrapper(&meNew.stbEntry.schemaRow);
        tDecoderClear(&dcNew);
        tdbTbcClose(pCur);
373 374
        tdbFree(pKey);
        tdbFree(pVal);
375 376
        goto _exit;
      }
377 378
      tdbFree(pKey);
      tdbFree(pVal);
379 380
      tdbTbcClose(pCur);
    }
H
Hongze Cheng 已提交
381 382
  } else if (me.type == TSDB_CHILD_TABLE) {
    uid = me.ctbEntry.suid;
H
Hongze Cheng 已提交
383
    tDecoderClear(&dc);
H
Hongze Cheng 已提交
384
    goto _query;
H
Hongze Cheng 已提交
385
  } else {
H
Hongze Cheng 已提交
386 387 388 389
    if (sver == -1 || sver == me.ntbEntry.schemaRow.version) {
      pSchema = tCloneSSchemaWrapper(&me.ntbEntry.schemaRow);
      tDecoderClear(&dc);
      goto _exit;
H
Hongze Cheng 已提交
390
    }
H
Hongze Cheng 已提交
391 392
  }
  tDecoderClear(&dc);
H
Hongze Cheng 已提交
393

H
Hongze Cheng 已提交
394 395 396
  // query from skm db
  if (tdbTbGet(pMeta->pSkmDb, &(SSkmDbKey){.uid = uid, .sver = sver}, sizeof(SSkmDbKey), &pData, &nData) < 0) {
    goto _err;
H
Hongze Cheng 已提交
397
  }
H
Hongze Cheng 已提交
398

H
Hongze Cheng 已提交
399
  tDecoderInit(&dc, pData, nData);
M
Minglei Jin 已提交
400
  tDecodeSSchemaWrapperEx(&dc, &schema);
H
Hongze Cheng 已提交
401 402 403 404
  pSchema = tCloneSSchemaWrapper(&schema);
  tDecoderClear(&dc);

_exit:
405
  tDecoderClear(&dc);
406 407 408
  if (lock) {
    metaULock(pMeta);
  }
H
Hongze Cheng 已提交
409 410
  tdbFree(pData);
  return pSchema;
H
Hongze Cheng 已提交
411

H
Hongze Cheng 已提交
412
_err:
413
  tDecoderClear(&dc);
414 415 416
  if (lock) {
    metaULock(pMeta);
  }
H
Hongze Cheng 已提交
417 418
  tdbFree(pData);
  return NULL;
H
Hongze Cheng 已提交
419 420
}

H
Hongze Cheng 已提交
421 422 423
int metaTtlSmaller(SMeta *pMeta, uint64_t ttl, SArray *uidList) {
  TBC *pCur;
  int  ret = tdbTbcOpen(pMeta->pTtlIdx, &pCur, NULL);
424 425 426 427 428 429 430 431 432 433 434 435 436 437
  if (ret < 0) {
    return ret;
  }

  STtlIdxKey ttlKey = {0};
  ttlKey.dtime = ttl;
  ttlKey.uid = INT64_MAX;
  int c = 0;
  tdbTbcMoveTo(pCur, &ttlKey, sizeof(ttlKey), &c);
  if (c < 0) {
    tdbTbcMoveToPrev(pCur);
  }

  void *pKey = NULL;
H
Hongze Cheng 已提交
438 439
  int   kLen = 0;
  while (1) {
440 441 442 443
    ret = tdbTbcPrev(pCur, &pKey, &kLen, NULL, NULL);
    if (ret < 0) {
      break;
    }
H
Hongze Cheng 已提交
444
    ttlKey = *(STtlIdxKey *)pKey;
445 446
    taosArrayPush(uidList, &ttlKey.uid);
  }
wmmhello's avatar
wmmhello 已提交
447
  tdbFree(pKey);
448 449 450 451
  tdbTbcClose(pCur);
  return 0;
}

H
Hongze Cheng 已提交
452
struct SMCtbCursor {
H
Hongze Cheng 已提交
453 454
  SMeta   *pMeta;
  TBC     *pCur;
H
Hongze Cheng 已提交
455
  tb_uid_t suid;
H
Hongze Cheng 已提交
456 457
  void    *pKey;
  void    *pVal;
H
Hongze Cheng 已提交
458 459 460 461
  int      kLen;
  int      vLen;
};

462
SMCtbCursor *metaOpenCtbCursor(SMeta *pMeta, tb_uid_t uid, int lock) {
H
Hongze Cheng 已提交
463
  SMCtbCursor *pCtbCur = NULL;
H
Hongze Cheng 已提交
464
  SCtbIdxKey   ctbIdxKey;
C
Cary Xu 已提交
465 466
  int          ret = 0;
  int          c = 0;
H
Hongze Cheng 已提交
467

H
Hongze Cheng 已提交
468 469 470 471
  pCtbCur = (SMCtbCursor *)taosMemoryCalloc(1, sizeof(*pCtbCur));
  if (pCtbCur == NULL) {
    return NULL;
  }
H
Hongze Cheng 已提交
472

H
fix  
Hongze Cheng 已提交
473
  pCtbCur->pMeta = pMeta;
H
Hongze Cheng 已提交
474
  pCtbCur->suid = uid;
475 476 477
  if (lock) {
    metaRLock(pMeta);
  }
H
fix  
Hongze Cheng 已提交
478

H
Hongze Cheng 已提交
479
  ret = tdbTbcOpen(pMeta->pCtbIdx, &pCtbCur->pCur, NULL);
H
Hongze Cheng 已提交
480
  if (ret < 0) {
H
fix  
Hongze Cheng 已提交
481
    metaULock(pMeta);
H
Hongze Cheng 已提交
482 483 484
    taosMemoryFree(pCtbCur);
    return NULL;
  }
H
Hongze Cheng 已提交
485

H
Hongze Cheng 已提交
486 487 488
  // move to the suid
  ctbIdxKey.suid = uid;
  ctbIdxKey.uid = INT64_MIN;
H
Hongze Cheng 已提交
489
  tdbTbcMoveTo(pCtbCur->pCur, &ctbIdxKey, sizeof(ctbIdxKey), &c);
H
Hongze Cheng 已提交
490
  if (c > 0) {
H
Hongze Cheng 已提交
491
    tdbTbcMoveToNext(pCtbCur->pCur);
H
Hongze Cheng 已提交
492 493
  }

H
Hongze Cheng 已提交
494 495 496
  return pCtbCur;
}

497
void metaCloseCtbCursor(SMCtbCursor *pCtbCur, int lock) {
H
Hongze Cheng 已提交
498
  if (pCtbCur) {
499
    if (pCtbCur->pMeta && lock) metaULock(pCtbCur->pMeta);
H
Hongze Cheng 已提交
500
    if (pCtbCur->pCur) {
H
Hongze Cheng 已提交
501
      tdbTbcClose(pCtbCur->pCur);
H
Hongze Cheng 已提交
502

H
Hongze Cheng 已提交
503 504
      tdbFree(pCtbCur->pKey);
      tdbFree(pCtbCur->pVal);
H
Hongze Cheng 已提交
505
    }
H
Hongze Cheng 已提交
506

H
Hongze Cheng 已提交
507 508
    taosMemoryFree(pCtbCur);
  }
H
Hongze Cheng 已提交
509 510 511
}

tb_uid_t metaCtbCursorNext(SMCtbCursor *pCtbCur) {
H
Hongze Cheng 已提交
512 513
  int         ret;
  SCtbIdxKey *pCtbIdxKey;
H
Hongze Cheng 已提交
514

H
Hongze Cheng 已提交
515
  ret = tdbTbcNext(pCtbCur->pCur, &pCtbCur->pKey, &pCtbCur->kLen, &pCtbCur->pVal, &pCtbCur->vLen);
H
Hongze Cheng 已提交
516 517 518
  if (ret < 0) {
    return 0;
  }
H
Hongze Cheng 已提交
519

H
Hongze Cheng 已提交
520
  pCtbIdxKey = pCtbCur->pKey;
H
Hongze Cheng 已提交
521 522 523
  if (pCtbIdxKey->suid > pCtbCur->suid) {
    return 0;
  }
H
Hongze Cheng 已提交
524

H
Hongze Cheng 已提交
525
  return pCtbIdxKey->uid;
H
Hongze Cheng 已提交
526 527
}

C
Cary Xu 已提交
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
struct SMStbCursor {
  SMeta   *pMeta;
  TBC     *pCur;
  tb_uid_t suid;
  void    *pKey;
  void    *pVal;
  int      kLen;
  int      vLen;
};

SMStbCursor *metaOpenStbCursor(SMeta *pMeta, tb_uid_t suid) {
  SMStbCursor *pStbCur = NULL;
  int          ret = 0;
  int          c = 0;

  pStbCur = (SMStbCursor *)taosMemoryCalloc(1, sizeof(*pStbCur));
  if (pStbCur == NULL) {
C
Cary Xu 已提交
545
    terrno = TSDB_CODE_OUT_OF_MEMORY;
C
Cary Xu 已提交
546 547 548 549 550 551 552 553 554
    return NULL;
  }

  pStbCur->pMeta = pMeta;
  pStbCur->suid = suid;
  metaRLock(pMeta);

  ret = tdbTbcOpen(pMeta->pSuidIdx, &pStbCur->pCur, NULL);
  if (ret < 0) {
C
Cary Xu 已提交
555
    terrno = TSDB_CODE_OUT_OF_MEMORY;
C
Cary Xu 已提交
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
    metaULock(pMeta);
    taosMemoryFree(pStbCur);
    return NULL;
  }

  // move to the suid
  tdbTbcMoveTo(pStbCur->pCur, &suid, sizeof(suid), &c);
  if (c > 0) {
    tdbTbcMoveToNext(pStbCur->pCur);
  }

  return pStbCur;
}

void metaCloseStbCursor(SMStbCursor *pStbCur) {
  if (pStbCur) {
    if (pStbCur->pMeta) metaULock(pStbCur->pMeta);
    if (pStbCur->pCur) {
      tdbTbcClose(pStbCur->pCur);

      tdbFree(pStbCur->pKey);
      tdbFree(pStbCur->pVal);
    }

    taosMemoryFree(pStbCur);
  }
}

tb_uid_t metaStbCursorNext(SMStbCursor *pStbCur) {
  int ret;

  ret = tdbTbcNext(pStbCur->pCur, &pStbCur->pKey, &pStbCur->kLen, &pStbCur->pVal, &pStbCur->vLen);
  if (ret < 0) {
    return 0;
  }
H
Hongze Cheng 已提交
591
  return *(tb_uid_t *)pStbCur->pKey;
C
Cary Xu 已提交
592 593
}

594
STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) {
H
Hongze Cheng 已提交
595
  // SMetaReader     mr = {0};
H
Hongze Cheng 已提交
596
  STSchema       *pTSchema = NULL;
H
Hongze Cheng 已提交
597 598
  SSchemaWrapper *pSW = NULL;
  STSchemaBuilder sb = {0};
H
Hongze Cheng 已提交
599
  SSchema        *pSchema;
H
Hongze Cheng 已提交
600

601
  pSW = metaGetTableSchema(pMeta, uid, sver, lock);
C
Cary Xu 已提交
602
  if (!pSW) return NULL;
H
fix  
Hongze Cheng 已提交
603

604
  tdInitTSchemaBuilder(&sb, pSW->version);
H
Hongze Cheng 已提交
605 606 607 608 609
  for (int i = 0; i < pSW->nCols; i++) {
    pSchema = pSW->pSchema + i;
    tdAddColToSchema(&sb, pSchema->type, pSchema->flags, pSchema->colId, pSchema->bytes);
  }
  pTSchema = tdGetSchemaFromBuilder(&sb);
C
Cary Xu 已提交
610

H
Hongze Cheng 已提交
611 612
  tdDestroyTSchemaBuilder(&sb);

H
Hongze Cheng 已提交
613 614
  taosMemoryFree(pSW->pSchema);
  taosMemoryFree(pSW);
H
Hongze Cheng 已提交
615 616 617
  return pTSchema;
}

H
Hongze Cheng 已提交
618
int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sver, STSchema **ppTSchema) {
H
Hongze Cheng 已提交
619 620
  int32_t code = 0;

H
Hongze Cheng 已提交
621 622
  void     *pData = NULL;
  int       nData = 0;
H
Hongze Cheng 已提交
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
  SSkmDbKey skmDbKey;
  if (sver <= 0) {
    SMetaInfo info;
    if (metaGetInfo(pMeta, suid ? suid : uid, &info) == 0) {
      sver = info.skmVer;
    } else {
      TBC *pSkmDbC = NULL;
      int  c;

      skmDbKey.uid = suid ? suid : uid;
      skmDbKey.sver = INT32_MAX;

      tdbTbcOpen(pMeta->pSkmDb, &pSkmDbC, NULL);
      metaRLock(pMeta);

      if (tdbTbcMoveTo(pSkmDbC, &skmDbKey, sizeof(skmDbKey), &c) < 0) {
        metaULock(pMeta);
        tdbTbcClose(pSkmDbC);
        code = TSDB_CODE_NOT_FOUND;
        goto _exit;
      }

      ASSERT(c);

      if (c < 0) {
        tdbTbcMoveToPrev(pSkmDbC);
      }

      const void *pKey = NULL;
      int32_t     nKey = 0;
      tdbTbcGet(pSkmDbC, &pKey, &nKey, NULL, NULL);

H
Hongze Cheng 已提交
655
      if (((SSkmDbKey *)pKey)->uid != skmDbKey.uid) {
H
Hongze Cheng 已提交
656 657 658 659 660 661 662 663 664 665 666 667
        metaULock(pMeta);
        tdbTbcClose(pSkmDbC);
        code = TSDB_CODE_NOT_FOUND;
        goto _exit;
      }

      sver = ((SSkmDbKey *)pKey)->sver;

      metaULock(pMeta);
      tdbTbcClose(pSkmDbC);
    }
  }
H
Hongze Cheng 已提交
668

H
Hongze Cheng 已提交
669 670 671 672
  ASSERT(sver > 0);

  skmDbKey.uid = suid ? suid : uid;
  skmDbKey.sver = sver;
H
Hongze Cheng 已提交
673
  metaRLock(pMeta);
H
Hongze Cheng 已提交
674
  if (tdbTbGet(pMeta->pSkmDb, &skmDbKey, sizeof(SSkmDbKey), &pData, &nData) < 0) {
H
Hongze Cheng 已提交
675
    metaULock(pMeta);
H
Hongze Cheng 已提交
676 677
    code = TSDB_CODE_NOT_FOUND;
    goto _exit;
H
Hongze Cheng 已提交
678 679 680 681 682 683 684 685 686
  }
  metaULock(pMeta);

  // decode
  SDecoder        dc = {0};
  SSchemaWrapper  schema;
  SSchemaWrapper *pSchemaWrapper = &schema;

  tDecoderInit(&dc, pData, nData);
M
Minglei Jin 已提交
687
  (void)tDecodeSSchemaWrapper(&dc, pSchemaWrapper);
H
Hongze Cheng 已提交
688
  tDecoderClear(&dc);
689
  tdbFree(pData);
H
Hongze Cheng 已提交
690 691 692 693 694 695 696 697 698

  // convert
  STSchemaBuilder sb = {0};

  tdInitTSchemaBuilder(&sb, pSchemaWrapper->version);
  for (int i = 0; i < pSchemaWrapper->nCols; i++) {
    SSchema *pSchema = pSchemaWrapper->pSchema + i;
    tdAddColToSchema(&sb, pSchema->type, pSchema->flags, pSchema->colId, pSchema->bytes);
  }
H
Haojun Liao 已提交
699

H
Hongze Cheng 已提交
700
  STSchema *pTSchema = tdGetSchemaFromBuilder(&sb);
H
Haojun Liao 已提交
701 702 703 704
  if (pTSchema == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
  }

H
Hongze Cheng 已提交
705 706 707 708 709
  tdDestroyTSchemaBuilder(&sb);

  *ppTSchema = pTSchema;
  taosMemoryFree(pSchemaWrapper->pSchema);

H
Hongze Cheng 已提交
710
_exit:
H
Hongze Cheng 已提交
711 712 713
  return code;
}

714 715
// N.B. Called by statusReq per second
int64_t metaGetTbNum(SMeta *pMeta) {
716 717 718 719 720
  // num of child tables (excluding normal tables , stables and others)

  /* int64_t num = 0; */
  /* vnodeGetAllCtbNum(pMeta->pVnode, &num); */

721
  return pMeta->pVnode->config.vndStats.numOfCTables + pMeta->pVnode->config.vndStats.numOfNTables;
722 723 724
}

// N.B. Called by statusReq per second
M
Minglei Jin 已提交
725
int64_t metaGetTimeSeriesNum(SMeta *pMeta) {
726
  // sum of (number of columns of stable -  1) * number of ctables (excluding timestamp column)
727 728
  if (pMeta->pVnode->config.vndStats.numOfTimeSeries <= 0 ||
      ++pMeta->pVnode->config.vndStats.itvTimeSeries % (60 * 5) == 0) {
729 730 731 732
    int64_t num = 0;
    vnodeGetTimeSeriesNum(pMeta->pVnode, &num);
    pMeta->pVnode->config.vndStats.numOfTimeSeries = num;

733
    pMeta->pVnode->config.vndStats.itvTimeSeries = (TD_VID(pMeta->pVnode) % 100) * 2;
734
  }
735

736
  return pMeta->pVnode->config.vndStats.numOfTimeSeries + pMeta->pVnode->config.vndStats.numOfNTimeSeries;
C
Cary Xu 已提交
737
}
H
Hongze Cheng 已提交
738

C
Cary Xu 已提交
739
typedef struct {
H
Hongze Cheng 已提交
740 741
  SMeta   *pMeta;
  TBC     *pCur;
C
Cary Xu 已提交
742
  tb_uid_t uid;
H
Hongze Cheng 已提交
743 744
  void    *pKey;
  void    *pVal;
C
Cary Xu 已提交
745 746 747 748 749 750 751 752 753 754 755 756 757
  int      kLen;
  int      vLen;
} SMSmaCursor;

SMSmaCursor *metaOpenSmaCursor(SMeta *pMeta, tb_uid_t uid) {
  SMSmaCursor *pSmaCur = NULL;
  SSmaIdxKey   smaIdxKey;
  int          ret;
  int          c;

  pSmaCur = (SMSmaCursor *)taosMemoryCalloc(1, sizeof(*pSmaCur));
  if (pSmaCur == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
758 759 760
    return NULL;
  }

C
Cary Xu 已提交
761 762 763 764
  pSmaCur->pMeta = pMeta;
  pSmaCur->uid = uid;
  metaRLock(pMeta);

H
Hongze Cheng 已提交
765
  ret = tdbTbcOpen(pMeta->pSmaIdx, &pSmaCur->pCur, NULL);
C
Cary Xu 已提交
766 767 768
  if (ret < 0) {
    metaULock(pMeta);
    taosMemoryFree(pSmaCur);
H
Hongze Cheng 已提交
769 770 771
    return NULL;
  }

C
Cary Xu 已提交
772 773 774
  // move to the suid
  smaIdxKey.uid = uid;
  smaIdxKey.smaUid = INT64_MIN;
H
Hongze Cheng 已提交
775
  tdbTbcMoveTo(pSmaCur->pCur, &smaIdxKey, sizeof(smaIdxKey), &c);
C
Cary Xu 已提交
776
  if (c > 0) {
H
Hongze Cheng 已提交
777
    tdbTbcMoveToNext(pSmaCur->pCur);
C
Cary Xu 已提交
778
  }
H
Hongze Cheng 已提交
779

C
Cary Xu 已提交
780 781
  return pSmaCur;
}
H
Hongze Cheng 已提交
782

C
Cary Xu 已提交
783 784 785 786
void metaCloseSmaCursor(SMSmaCursor *pSmaCur) {
  if (pSmaCur) {
    if (pSmaCur->pMeta) metaULock(pSmaCur->pMeta);
    if (pSmaCur->pCur) {
H
Hongze Cheng 已提交
787
      tdbTbcClose(pSmaCur->pCur);
H
Hongze Cheng 已提交
788

C
Cary Xu 已提交
789 790 791
      tdbFree(pSmaCur->pKey);
      tdbFree(pSmaCur->pVal);
    }
H
Hongze Cheng 已提交
792

C
Cary Xu 已提交
793 794 795 796 797 798 799 800
    taosMemoryFree(pSmaCur);
  }
}

tb_uid_t metaSmaCursorNext(SMSmaCursor *pSmaCur) {
  int         ret;
  SSmaIdxKey *pSmaIdxKey;

H
Hongze Cheng 已提交
801
  ret = tdbTbcNext(pSmaCur->pCur, &pSmaCur->pKey, &pSmaCur->kLen, &pSmaCur->pVal, &pSmaCur->vLen);
C
Cary Xu 已提交
802 803 804 805 806 807 808 809 810 811 812 813 814 815
  if (ret < 0) {
    return 0;
  }

  pSmaIdxKey = pSmaCur->pKey;
  if (pSmaIdxKey->uid > pSmaCur->uid) {
    return 0;
  }

  return pSmaIdxKey->uid;
}

STSmaWrapper *metaGetSmaInfoByTable(SMeta *pMeta, tb_uid_t uid, bool deepCopy) {
  STSmaWrapper *pSW = NULL;
H
Hongze Cheng 已提交
816
  SArray       *pSmaIds = NULL;
C
Cary Xu 已提交
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839

  if (!(pSmaIds = metaGetSmaIdsByTable(pMeta, uid))) {
    return NULL;
  }

  pSW = taosMemoryCalloc(1, sizeof(*pSW));
  if (!pSW) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _err;
  }

  pSW->number = taosArrayGetSize(pSmaIds);
  pSW->tSma = taosMemoryCalloc(pSW->number, sizeof(STSma));

  if (!pSW->tSma) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    goto _err;
  }

  SMetaReader mr = {0};
  metaReaderInit(&mr, pMeta, 0);
  int64_t smaId;
  int     smaIdx = 0;
H
Hongze Cheng 已提交
840
  STSma  *pTSma = NULL;
C
Cary Xu 已提交
841 842 843
  for (int i = 0; i < pSW->number; ++i) {
    smaId = *(tb_uid_t *)taosArrayGet(pSmaIds, i);
    if (metaGetTableEntryByUid(&mr, smaId) < 0) {
844
      tDecoderClear(&mr.coder);
S
Shengliang Guan 已提交
845
      metaWarn("vgId:%d, no entry for tbId:%" PRIi64 ", smaId:%" PRIi64, TD_VID(pMeta->pVnode), uid, smaId);
C
Cary Xu 已提交
846 847
      continue;
    }
848
    tDecoderClear(&mr.coder);
C
Cary Xu 已提交
849 850 851 852 853 854 855 856
    pTSma = pSW->tSma + smaIdx;
    memcpy(pTSma, mr.me.smaEntry.tsma, sizeof(STSma));
    if (deepCopy) {
      if (pTSma->exprLen > 0) {
        if (!(pTSma->expr = taosMemoryCalloc(1, pTSma->exprLen))) {
          terrno = TSDB_CODE_OUT_OF_MEMORY;
          goto _err;
        }
H
Hongze Cheng 已提交
857
        memcpy((void *)pTSma->expr, mr.me.smaEntry.tsma->expr, pTSma->exprLen);
H
Hongze Cheng 已提交
858
      }
C
Cary Xu 已提交
859 860 861 862 863
      if (pTSma->tagsFilterLen > 0) {
        if (!(pTSma->tagsFilter = taosMemoryCalloc(1, pTSma->tagsFilterLen))) {
          terrno = TSDB_CODE_OUT_OF_MEMORY;
          goto _err;
        }
H
Hongze Cheng 已提交
864
      }
H
Hongze Cheng 已提交
865
      memcpy((void *)pTSma->tagsFilter, mr.me.smaEntry.tsma->tagsFilter, pTSma->tagsFilterLen);
C
Cary Xu 已提交
866 867 868 869 870
    } else {
      pTSma->exprLen = 0;
      pTSma->expr = NULL;
      pTSma->tagsFilterLen = 0;
      pTSma->tagsFilter = NULL;
H
Hongze Cheng 已提交
871
    }
H
Hongze Cheng 已提交
872

C
Cary Xu 已提交
873
    ++smaIdx;
H
Hongze Cheng 已提交
874 875
  }

C
Cary Xu 已提交
876 877
  if (smaIdx <= 0) goto _err;
  pSW->number = smaIdx;
H
Hongze Cheng 已提交
878

C
Cary Xu 已提交
879 880
  metaReaderClear(&mr);
  taosArrayDestroy(pSmaIds);
H
Hongze Cheng 已提交
881
  return pSW;
C
Cary Xu 已提交
882 883 884
_err:
  metaReaderClear(&mr);
  taosArrayDestroy(pSmaIds);
C
Cary Xu 已提交
885
  tFreeTSmaWrapper(pSW, deepCopy);
H
Hongze Cheng 已提交
886 887 888
  return NULL;
}

C
Cary Xu 已提交
889
STSma *metaGetSmaInfoByIndex(SMeta *pMeta, int64_t indexUid) {
H
Hongze Cheng 已提交
890
  STSma      *pTSma = NULL;
C
Cary Xu 已提交
891 892 893
  SMetaReader mr = {0};
  metaReaderInit(&mr, pMeta, 0);
  if (metaGetTableEntryByUid(&mr, indexUid) < 0) {
S
Shengliang Guan 已提交
894
    metaWarn("vgId:%d, failed to get table entry for smaId:%" PRIi64, TD_VID(pMeta->pVnode), indexUid);
C
Cary Xu 已提交
895 896 897 898 899 900 901 902 903 904 905 906 907 908
    metaReaderClear(&mr);
    return NULL;
  }
  pTSma = (STSma *)taosMemoryMalloc(sizeof(STSma));
  if (!pTSma) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    metaReaderClear(&mr);
    return NULL;
  }

  memcpy(pTSma, mr.me.smaEntry.tsma, sizeof(STSma));

  metaReaderClear(&mr);
  return pTSma;
H
Hongze Cheng 已提交
909 910
}

C
Cary Xu 已提交
911
SArray *metaGetSmaIdsByTable(SMeta *pMeta, tb_uid_t uid) {
H
Hongze Cheng 已提交
912
  SArray     *pUids = NULL;
C
Cary Xu 已提交
913
  SSmaIdxKey *pSmaIdxKey = NULL;
H
Hongze Cheng 已提交
914

C
Cary Xu 已提交
915 916
  SMSmaCursor *pCur = metaOpenSmaCursor(pMeta, uid);
  if (!pCur) {
H
Hongze Cheng 已提交
917 918 919
    return NULL;
  }

C
Cary Xu 已提交
920 921 922 923 924
  while (1) {
    tb_uid_t id = metaSmaCursorNext(pCur);
    if (id == 0) {
      break;
    }
H
Hongze Cheng 已提交
925

C
Cary Xu 已提交
926 927
    if (!pUids) {
      pUids = taosArrayInit(16, sizeof(tb_uid_t));
H
Hongze Cheng 已提交
928
      if (!pUids) {
C
Cary Xu 已提交
929 930 931
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        metaCloseSmaCursor(pCur);
        return NULL;
H
Hongze Cheng 已提交
932
      }
C
Cary Xu 已提交
933
    }
H
Hongze Cheng 已提交
934

C
Cary Xu 已提交
935
    pSmaIdxKey = (SSmaIdxKey *)pCur->pKey;
H
Hongze Cheng 已提交
936

C
Cary Xu 已提交
937
    if (!taosArrayPush(pUids, &pSmaIdxKey->smaUid)) {
C
Cary Xu 已提交
938 939 940 941
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      metaCloseSmaCursor(pCur);
      taosArrayDestroy(pUids);
      return NULL;
H
Hongze Cheng 已提交
942 943 944 945 946 947 948
    }
  }

  metaCloseSmaCursor(pCur);
  return pUids;
}

C
Cary Xu 已提交
949
SArray *metaGetSmaTbUids(SMeta *pMeta) {
H
Hongze Cheng 已提交
950
  SArray     *pUids = NULL;
C
Cary Xu 已提交
951 952 953 954 955
  SSmaIdxKey *pSmaIdxKey = NULL;
  tb_uid_t    lastUid = 0;

  SMSmaCursor *pCur = metaOpenSmaCursor(pMeta, 0);
  if (!pCur) {
H
Hongze Cheng 已提交
956 957 958
    return NULL;
  }

C
Cary Xu 已提交
959 960 961 962 963
  while (1) {
    tb_uid_t uid = metaSmaCursorNext(pCur);
    if (uid == 0) {
      break;
    }
H
Hongze Cheng 已提交
964

C
Cary Xu 已提交
965 966 967
    if (lastUid == uid) {
      continue;
    }
H
Hongze Cheng 已提交
968

C
Cary Xu 已提交
969 970 971 972 973 974 975 976 977 978 979
    lastUid = uid;

    if (!pUids) {
      pUids = taosArrayInit(16, sizeof(tb_uid_t));
      if (!pUids) {
        terrno = TSDB_CODE_OUT_OF_MEMORY;
        metaCloseSmaCursor(pCur);
        return NULL;
      }
    }

C
Cary Xu 已提交
980
    if (!taosArrayPush(pUids, &uid)) {
C
Cary Xu 已提交
981 982 983 984 985
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      metaCloseSmaCursor(pCur);
      taosArrayDestroy(pUids);
      return NULL;
    }
H
Hongze Cheng 已提交
986 987
  }

C
Cary Xu 已提交
988 989
  metaCloseSmaCursor(pCur);
  return pUids;
H
Hongze Cheng 已提交
990 991
}

L
Liu Jicong 已提交
992
#endif
H
Hongze Cheng 已提交
993

994
const void *metaGetTableTagVal(void *pTag, int16_t type, STagVal *val) {
dengyihao's avatar
dengyihao 已提交
995
  STag *tag = (STag *)pTag;
dengyihao's avatar
dengyihao 已提交
996
  if (type == TSDB_DATA_TYPE_JSON) {
wmmhello's avatar
wmmhello 已提交
997 998
    return tag;
  }
wmmhello's avatar
wmmhello 已提交
999 1000
  bool find = tTagGet(tag, val);

dengyihao's avatar
dengyihao 已提交
1001
  if (!find) {
wmmhello's avatar
wmmhello 已提交
1002 1003
    return NULL;
  }
wmmhello's avatar
wmmhello 已提交
1004

wmmhello's avatar
wmmhello 已提交
1005
#ifdef TAG_FILTER_DEBUG
wmmhello's avatar
wmmhello 已提交
1006
  if (IS_VAR_DATA_TYPE(val->type)) {
1007
    char *buf = taosMemoryCalloc(val->nData + 1, 1);
wmmhello's avatar
wmmhello 已提交
1008 1009 1010 1011 1012 1013 1014 1015 1016
    memcpy(buf, val->pData, val->nData);
    metaDebug("metaTag table val varchar index:%d cid:%d type:%d value:%s", 1, val->cid, val->type, buf);
    taosMemoryFree(buf);
  } else {
    double dval = 0;
    GET_TYPED_DATA(dval, double, val->type, &val->i64);
    metaDebug("metaTag table val number index:%d cid:%d type:%d value:%f", 1, val->cid, val->type, dval);
  }

1017 1018
  SArray *pTagVals = NULL;
  tTagToValArray((STag *)pTag, &pTagVals);
wmmhello's avatar
wmmhello 已提交
1019
  for (int i = 0; i < taosArrayGetSize(pTagVals); i++) {
1020
    STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
wmmhello's avatar
wmmhello 已提交
1021 1022

    if (IS_VAR_DATA_TYPE(pTagVal->type)) {
1023
      char *buf = taosMemoryCalloc(pTagVal->nData + 1, 1);
wmmhello's avatar
wmmhello 已提交
1024 1025 1026 1027 1028 1029 1030 1031 1032
      memcpy(buf, pTagVal->pData, pTagVal->nData);
      metaDebug("metaTag table varchar index:%d cid:%d type:%d value:%s", i, pTagVal->cid, pTagVal->type, buf);
      taosMemoryFree(buf);
    } else {
      double dval = 0;
      GET_TYPED_DATA(dval, double, pTagVal->type, &pTagVal->i64);
      metaDebug("metaTag table number index:%d cid:%d type:%d value:%f", i, pTagVal->cid, pTagVal->type, dval);
    }
  }
wmmhello's avatar
wmmhello 已提交
1033
#endif
wmmhello's avatar
wmmhello 已提交
1034

wmmhello's avatar
wmmhello 已提交
1035
  return val;
dengyihao's avatar
dengyihao 已提交
1036
}
wmmhello's avatar
wmmhello 已提交
1037 1038

typedef struct {
H
Hongze Cheng 已提交
1039 1040
  SMeta   *pMeta;
  TBC     *pCur;
wmmhello's avatar
wmmhello 已提交
1041 1042 1043
  tb_uid_t suid;
  int16_t  cid;
  int16_t  type;
H
Hongze Cheng 已提交
1044 1045
  void    *pKey;
  void    *pVal;
wmmhello's avatar
wmmhello 已提交
1046 1047 1048 1049
  int32_t  kLen;
  int32_t  vLen;
} SIdxCursor;

dengyihao's avatar
dengyihao 已提交
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
int32_t metaFilterCreateTime(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) {
  int32_t ret = 0;

  SIdxCursor *pCursor = NULL;
  pCursor = (SIdxCursor *)taosMemoryCalloc(1, sizeof(SIdxCursor));
  pCursor->pMeta = pMeta;
  pCursor->suid = param->suid;
  pCursor->cid = param->cid;
  pCursor->type = param->type;

  metaRLock(pMeta);
  ret = tdbTbcOpen(pMeta->pCtimeIdx, &pCursor->pCur, NULL);
  if (ret != 0) {
    goto END;
  }
  int64_t uidLimit = param->reverse ? INT64_MAX : 0;

  SCtimeIdxKey  ctimeKey = {.ctime = *(int64_t *)(param->val), .uid = uidLimit};
  SCtimeIdxKey *pCtimeKey = &ctimeKey;

  int cmp = 0;
  if (tdbTbcMoveTo(pCursor->pCur, &ctimeKey, sizeof(ctimeKey), &cmp) < 0) {
    goto END;
  }
dengyihao's avatar
dengyihao 已提交
1074

dengyihao's avatar
dengyihao 已提交
1075 1076 1077 1078 1079 1080 1081 1082
  int32_t valid = 0;
  while (1) {
    void   *entryKey = NULL;
    int32_t nEntryKey = -1;
    valid = tdbTbcGet(pCursor->pCur, (const void **)&entryKey, &nEntryKey, NULL, NULL);
    if (valid < 0) break;

    SCtimeIdxKey *p = entryKey;
dengyihao's avatar
dengyihao 已提交
1083

dengyihao's avatar
dengyihao 已提交
1084 1085
    int32_t cmp = (*param->filterFunc)((void *)&p->ctime, (void *)&pCtimeKey->ctime, param->type);
    if (cmp == 0) taosArrayPush(pUids, &p->uid);
dengyihao's avatar
dengyihao 已提交
1086 1087 1088 1089 1090 1091 1092

    if (param->reverse == false) {
      if (cmp == -1) break;
    } else if (param->reverse) {
      if (cmp == 1) break;
    }

dengyihao's avatar
dengyihao 已提交
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
    valid = param->reverse ? tdbTbcMoveToPrev(pCursor->pCur) : tdbTbcMoveToNext(pCursor->pCur);
    if (valid < 0) break;
  }

END:
  if (pCursor->pMeta) metaULock(pCursor->pMeta);
  if (pCursor->pCur) tdbTbcClose(pCursor->pCur);
  taosMemoryFree(pCursor);
  return ret;
}

int32_t metaFilterTableName(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) {
  int32_t ret = 0;
  char   *buf = NULL;

  STagIdxKey *pKey = NULL;
  int32_t     nKey = 0;

  SIdxCursor *pCursor = NULL;
  pCursor = (SIdxCursor *)taosMemoryCalloc(1, sizeof(SIdxCursor));
  pCursor->pMeta = pMeta;
  pCursor->suid = param->suid;
  pCursor->cid = param->cid;
  pCursor->type = param->type;

dengyihao's avatar
dengyihao 已提交
1118 1119
  char *pName = param->val;

dengyihao's avatar
dengyihao 已提交
1120 1121
  metaRLock(pMeta);
  ret = tdbTbcOpen(pMeta->pNameIdx, &pCursor->pCur, NULL);
dengyihao's avatar
dengyihao 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
  if (ret != 0) {
    goto END;
  }

  int cmp = 0;
  if (tdbTbcMoveTo(pCursor->pCur, pName, strlen(pName) + 1, &cmp) < 0) {
    goto END;
  }
  bool    first = true;
  int32_t valid = 0;
  while (1) {
    void   *pEntryKey = NULL, *pEntryVal = NULL;
    int32_t nEntryKey = -1, nEntryVal = 0;
    valid = tdbTbcGet(pCursor->pCur, (const void **)pEntryKey, &nEntryKey, (const void **)&pEntryVal, &nEntryVal);
    if (valid < 0) break;

1138
    char *pTableKey = (char *)pEntryKey;
H
Haojun Liao 已提交
1139
    cmp = (*param->filterFunc)(pTableKey, pName, pCursor->type);
dengyihao's avatar
dengyihao 已提交
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152
    if (cmp == 0) {
      tb_uid_t tuid = *(tb_uid_t *)pEntryVal;
      taosArrayPush(pUids, &tuid);
    } else if (cmp == 1) {
      // next
    } else {
      break;
    }
    valid = param->reverse ? tdbTbcMoveToPrev(pCursor->pCur) : tdbTbcMoveToNext(pCursor->pCur);
    if (valid < 0) {
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192

END:
  if (pCursor->pMeta) metaULock(pCursor->pMeta);
  if (pCursor->pCur) tdbTbcClose(pCursor->pCur);
  taosMemoryFree(buf);
  taosMemoryFree(pKey);

  taosMemoryFree(pCursor);

  return ret;
}
int32_t metaFilterTtl(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) {
  int32_t ret = 0;
  char   *buf = NULL;

  STtlIdxKey *pKey = NULL;
  int32_t     nKey = 0;

  SIdxCursor *pCursor = NULL;
  pCursor = (SIdxCursor *)taosMemoryCalloc(1, sizeof(SIdxCursor));
  pCursor->pMeta = pMeta;
  pCursor->suid = param->suid;
  pCursor->cid = param->cid;
  pCursor->type = param->type;

  metaRLock(pMeta);
  ret = tdbTbcOpen(pMeta->pTtlIdx, &pCursor->pCur, NULL);

END:
  if (pCursor->pMeta) metaULock(pCursor->pMeta);
  if (pCursor->pCur) tdbTbcClose(pCursor->pCur);
  taosMemoryFree(buf);
  taosMemoryFree(pKey);

  taosMemoryFree(pCursor);

  return ret;
  // impl later
  return 0;
}
dengyihao's avatar
dengyihao 已提交
1193 1194 1195
int32_t metaFilterTableIds(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) {
  int32_t ret = 0;
  char   *buf = NULL;
wmmhello's avatar
wmmhello 已提交
1196

dengyihao's avatar
dengyihao 已提交
1197 1198 1199 1200
  STagIdxKey *pKey = NULL;
  int32_t     nKey = 0;

  SIdxCursor *pCursor = NULL;
wmmhello's avatar
wmmhello 已提交
1201 1202 1203 1204 1205 1206 1207
  pCursor = (SIdxCursor *)taosMemoryCalloc(1, sizeof(SIdxCursor));
  pCursor->pMeta = pMeta;
  pCursor->suid = param->suid;
  pCursor->cid = param->cid;
  pCursor->type = param->type;

  metaRLock(pMeta);
dengyihao's avatar
dengyihao 已提交
1208
  ret = tdbTbcOpen(pMeta->pCtimeIdx, &pCursor->pCur, NULL);
wmmhello's avatar
wmmhello 已提交
1209 1210 1211 1212
  if (ret < 0) {
    goto END;
  }

dengyihao's avatar
dengyihao 已提交
1213
  int32_t maxSize = 0;
wmmhello's avatar
wmmhello 已提交
1214
  int32_t nTagData = 0;
H
Hongze Cheng 已提交
1215
  void   *tagData = NULL;
dengyihao's avatar
dengyihao 已提交
1216

dengyihao's avatar
dengyihao 已提交
1217
  if (param->val == NULL) {
S
Shengliang Guan 已提交
1218
    metaError("vgId:%d, failed to filter NULL data", TD_VID(pMeta->pVnode));
dengyihao's avatar
dengyihao 已提交
1219
    ret = -1;
dengyihao's avatar
dengyihao 已提交
1220
    goto END;
dengyihao's avatar
dengyihao 已提交
1221
  } else {
dengyihao's avatar
dengyihao 已提交
1222 1223 1224 1225 1226 1227 1228 1229 1230 1231
    if (IS_VAR_DATA_TYPE(param->type)) {
      tagData = varDataVal(param->val);
      nTagData = varDataLen(param->val);

      if (param->type == TSDB_DATA_TYPE_NCHAR) {
        maxSize = 4 * nTagData + 1;
        buf = taosMemoryCalloc(1, maxSize);
        if (false == taosMbsToUcs4(tagData, nTagData, (TdUcs4 *)buf, maxSize, &maxSize)) {
          goto END;
        }
dengyihao's avatar
dengyihao 已提交
1232

dengyihao's avatar
dengyihao 已提交
1233 1234 1235 1236 1237 1238
        tagData = buf;
        nTagData = maxSize;
      }
    } else {
      tagData = param->val;
      nTagData = tDataTypes[param->type].bytes;
dengyihao's avatar
dengyihao 已提交
1239
    }
wmmhello's avatar
wmmhello 已提交
1240
  }
dengyihao's avatar
dengyihao 已提交
1241
  ret = metaCreateTagIdxKey(pCursor->suid, pCursor->cid, tagData, nTagData, pCursor->type,
wmmhello's avatar
wmmhello 已提交
1242
                            param->reverse ? INT64_MAX : INT64_MIN, &pKey, &nKey);
dengyihao's avatar
dengyihao 已提交
1243

wmmhello's avatar
wmmhello 已提交
1244 1245 1246 1247 1248 1249 1250
  if (ret != 0) {
    goto END;
  }
  int cmp = 0;
  if (tdbTbcMoveTo(pCursor->pCur, pKey, nKey, &cmp) < 0) {
    goto END;
  }
dengyihao's avatar
dengyihao 已提交
1251

dengyihao's avatar
dengyihao 已提交
1252
  bool    first = true;
dengyihao's avatar
dengyihao 已提交
1253
  int32_t valid = 0;
wmmhello's avatar
wmmhello 已提交
1254
  while (1) {
dengyihao's avatar
dengyihao 已提交
1255 1256 1257
    void   *entryKey = NULL, *entryVal = NULL;
    int32_t nEntryKey, nEntryVal;

wmmhello's avatar
wmmhello 已提交
1258 1259
    valid = tdbTbcGet(pCursor->pCur, (const void **)&entryKey, &nEntryKey, (const void **)&entryVal, &nEntryVal);
    if (valid < 0) {
dengyihao's avatar
dengyihao 已提交
1260
      tdbFree(entryVal);
wmmhello's avatar
wmmhello 已提交
1261 1262 1263
      break;
    }
    STagIdxKey *p = entryKey;
dengyihao's avatar
dengyihao 已提交
1264
    if (p == NULL) break;
dengyihao's avatar
dengyihao 已提交
1265 1266 1267 1268 1269 1270 1271 1272 1273
    if (p->type != pCursor->type) {
      if (first) {
        valid = param->reverse ? tdbTbcMoveToPrev(pCursor->pCur) : tdbTbcMoveToNext(pCursor->pCur);
        if (valid < 0) break;
        continue;
      } else {
        break;
      }
    }
dengyihao's avatar
dengyihao 已提交
1274
    if (p->suid != pKey->suid) {
dengyihao's avatar
dengyihao 已提交
1275 1276
      break;
    }
dengyihao's avatar
dengyihao 已提交
1277
    first = false;
dengyihao's avatar
dengyihao 已提交
1278 1279 1280 1281 1282 1283
    int32_t cmp = (*param->filterFunc)(p->data, pKey->data, pKey->type);
    if (cmp == 0) {
      // match
      tb_uid_t tuid = 0;
      if (IS_VAR_DATA_TYPE(pKey->type)) {
        tuid = *(tb_uid_t *)(p->data + varDataTLen(p->data));
wmmhello's avatar
wmmhello 已提交
1284
      } else {
dengyihao's avatar
dengyihao 已提交
1285
        tuid = *(tb_uid_t *)(p->data + tDataTypes[pCursor->type].bytes);
wmmhello's avatar
wmmhello 已提交
1286
      }
dengyihao's avatar
dengyihao 已提交
1287 1288 1289 1290 1291 1292
      taosArrayPush(pUids, &tuid);
    } else if (cmp == 1) {
      // not match but should continue to iter
    } else {
      // not match and no more result
      break;
wmmhello's avatar
wmmhello 已提交
1293 1294 1295 1296 1297 1298
    }
    valid = param->reverse ? tdbTbcMoveToPrev(pCursor->pCur) : tdbTbcMoveToNext(pCursor->pCur);
    if (valid < 0) {
      break;
    }
  }
dengyihao's avatar
dengyihao 已提交
1299

wmmhello's avatar
wmmhello 已提交
1300 1301 1302
END:
  if (pCursor->pMeta) metaULock(pCursor->pMeta);
  if (pCursor->pCur) tdbTbcClose(pCursor->pCur);
dengyihao's avatar
dengyihao 已提交
1303
  taosMemoryFree(buf);
dengyihao's avatar
dengyihao 已提交
1304
  taosMemoryFree(pKey);
wmmhello's avatar
wmmhello 已提交
1305 1306 1307 1308

  taosMemoryFree(pCursor);

  return ret;
dengyihao's avatar
dengyihao 已提交
1309
}
H
Hongze Cheng 已提交
1310

dengyihao's avatar
dengyihao 已提交
1311
static int32_t metaGetTableTagByUid(SMeta *pMeta, int64_t suid, int64_t uid, void **tag, int32_t *len, bool lock) {
dengyihao's avatar
dengyihao 已提交
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
  int ret = 0;
  if (lock) {
    metaRLock(pMeta);
  }

  SCtbIdxKey ctbIdxKey = {.suid = suid, .uid = uid};
  ret = tdbTbGet(pMeta->pCtbIdx, &ctbIdxKey, sizeof(SCtbIdxKey), tag, len);
  if (lock) {
    metaULock(pMeta);
  }

  return ret;
}
dengyihao's avatar
dengyihao 已提交
1325
int32_t metaGetTableTagsByUids(SMeta *pMeta, int64_t suid, SArray *uidList, SHashObj *tags) {
dengyihao's avatar
dengyihao 已提交
1326 1327 1328
  const int32_t LIMIT = 128;

  int32_t isLock = false;
dengyihao's avatar
dengyihao 已提交
1329 1330
  int32_t sz = uidList ? taosArrayGetSize(uidList) : 0;
  for (int i = 0; i < sz; i++) {
dengyihao's avatar
dengyihao 已提交
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
    tb_uid_t *id = taosArrayGet(uidList, i);

    if (i % LIMIT == 0) {
      if (isLock) metaULock(pMeta);

      metaRLock(pMeta);
      isLock = true;
    }

    if (taosHashGet(tags, id, sizeof(tb_uid_t)) == NULL) {
      void   *val = NULL;
      int32_t len = 0;
      if (metaGetTableTagByUid(pMeta, suid, *id, &val, &len, false) == 0) {
        taosHashPut(tags, id, sizeof(tb_uid_t), val, len);
        tdbFree(val);
dengyihao's avatar
dengyihao 已提交
1346 1347 1348
      } else {
        metaError("vgId:%d, failed to table IDs, suid: %" PRId64 ", uid: %" PRId64 "", TD_VID(pMeta->pVnode), suid,
                  *id);
dengyihao's avatar
dengyihao 已提交
1349
      }
dengyihao's avatar
dengyihao 已提交
1350 1351
    }
  }
dengyihao's avatar
dengyihao 已提交
1352 1353
  if (isLock) metaULock(pMeta);

dengyihao's avatar
dengyihao 已提交
1354 1355
  return 0;
}
dengyihao's avatar
dengyihao 已提交
1356

1357
int32_t metaGetTableTags(SMeta *pMeta, uint64_t suid, SArray *uidList, SHashObj *tags) {
1358
  SMCtbCursor *pCur = metaOpenCtbCursor(pMeta, suid, 1);
1359

1360
  SHashObj *uHash = NULL;
dengyihao's avatar
dengyihao 已提交
1361 1362
  size_t    len = taosArrayGetSize(uidList);  // len > 0 means there already have uids
  if (len > 0) {
1363
    uHash = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
dengyihao's avatar
dengyihao 已提交
1364
    for (int i = 0; i < len; i++) {
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374
      int64_t *uid = taosArrayGet(uidList, i);
      taosHashPut(uHash, uid, sizeof(int64_t), &i, sizeof(i));
    }
  }
  while (1) {
    tb_uid_t id = metaCtbCursorNext(pCur);
    if (id == 0) {
      break;
    }

wmmhello's avatar
wmmhello 已提交
1375
    if (len > 0 && taosHashGet(uHash, &id, sizeof(int64_t)) == NULL) {
1376
      continue;
dengyihao's avatar
dengyihao 已提交
1377
    } else if (len == 0) {
1378 1379 1380
      taosArrayPush(uidList, &id);
    }

1381
    taosHashPut(tags, &id, sizeof(int64_t), pCur->pVal, pCur->vLen);
1382 1383
  }

1384
  taosHashCleanup(uHash);
1385
  metaCloseCtbCursor(pCur, 1);
1386 1387
  return TSDB_CODE_SUCCESS;
}
wmmhello's avatar
wmmhello 已提交
1388

H
Hongze Cheng 已提交
1389 1390
int32_t metaCacheGet(SMeta *pMeta, int64_t uid, SMetaInfo *pInfo);

H
Hongze Cheng 已提交
1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427
int32_t metaGetInfo(SMeta *pMeta, int64_t uid, SMetaInfo *pInfo) {
  int32_t code = 0;
  void   *pData = NULL;
  int     nData = 0;

  metaRLock(pMeta);

  // search cache
  if (metaCacheGet(pMeta, uid, pInfo) == 0) {
    metaULock(pMeta);
    goto _exit;
  }

  // search TDB
  if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData) < 0) {
    // not found
    metaULock(pMeta);
    code = TSDB_CODE_NOT_FOUND;
    goto _exit;
  }

  metaULock(pMeta);

  pInfo->uid = uid;
  pInfo->suid = ((SUidIdxVal *)pData)->suid;
  pInfo->version = ((SUidIdxVal *)pData)->version;
  pInfo->skmVer = ((SUidIdxVal *)pData)->skmVer;

  // upsert the cache
  metaWLock(pMeta);
  metaCacheUpsert(pMeta, pInfo);
  metaULock(pMeta);

_exit:
  tdbFree(pData);
  return code;
}
1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456

int32_t metaGetStbStats(SMeta *pMeta, int64_t uid, SMetaStbStats *pInfo) {
  int32_t code = 0;

  metaRLock(pMeta);

  // fast path: search cache
  if (metaStatsCacheGet(pMeta, uid, pInfo) == TSDB_CODE_SUCCESS) {
    metaULock(pMeta);
    goto _exit;
  }

  // slow path: search TDB
  int64_t ctbNum = 0;
  vnodeGetCtbNum(pMeta->pVnode, uid, &ctbNum);

  metaULock(pMeta);

  pInfo->uid = uid;
  pInfo->ctbNum = ctbNum;

  // upsert the cache
  metaWLock(pMeta);
  metaStatsCacheUpsert(pMeta, pInfo);
  metaULock(pMeta);

_exit:
  return code;
}