tarray.c 12.9 KB
Newer Older
H
more  
hzcheng 已提交
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/>.
 */

S
tarray  
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
H
more  
hzcheng 已提交
17
#include "tarray.h"
18
#include "tcoding.h"
H
more  
hzcheng 已提交
19

20
SArray* taosArrayInit(size_t size, size_t elemSize) {
H
more  
hzcheng 已提交
21 22 23 24 25 26
  assert(elemSize > 0);

  if (size < TARRAY_MIN_SIZE) {
    size = TARRAY_MIN_SIZE;
  }

wafwerar's avatar
wafwerar 已提交
27
  SArray* pArray = taosMemoryMalloc(sizeof(SArray));
H
more  
hzcheng 已提交
28 29 30 31
  if (pArray == NULL) {
    return NULL;
  }

H
Haojun Liao 已提交
32
  pArray->size = 0;
wafwerar's avatar
wafwerar 已提交
33
  pArray->pData = taosMemoryCalloc(size, elemSize);
H
more  
hzcheng 已提交
34
  if (pArray->pData == NULL) {
wafwerar's avatar
wafwerar 已提交
35
    taosMemoryFree(pArray);
H
more  
hzcheng 已提交
36 37 38 39 40 41 42 43
    return NULL;
  }

  pArray->capacity = size;
  pArray->elemSize = elemSize;
  return pArray;
}

H
hjxilinx 已提交
44
static int32_t taosArrayResize(SArray* pArray) {
H
more  
hzcheng 已提交
45 46 47 48 49
  assert(pArray->size >= pArray->capacity);

  size_t size = pArray->capacity;
  size = (size << 1u);

wafwerar's avatar
wafwerar 已提交
50
  void* tmp = taosMemoryRealloc(pArray->pData, size * pArray->elemSize);
H
hjxilinx 已提交
51 52
  if (tmp == NULL) {  // reallocate failed, the original buffer remains
    return -1;
H
more  
hzcheng 已提交
53 54 55 56
  }

  pArray->pData = tmp;
  pArray->capacity = size;
S
tarray  
Shengliang Guan 已提交
57

H
hjxilinx 已提交
58
  return 0;
H
more  
hzcheng 已提交
59 60
}

L
Liu Jicong 已提交
61 62
int32_t taosArrayEnsureCap(SArray* pArray, size_t newCap) {
  if (newCap > pArray->capacity) {
H
Hongze Cheng 已提交
63
    size_t tsize = (pArray->capacity << 1u);
L
Liu Jicong 已提交
64
    while (newCap > tsize) {
H
Hongze Cheng 已提交
65 66 67
      tsize = (tsize << 1u);
    }

wafwerar's avatar
wafwerar 已提交
68
    pArray->pData = taosMemoryRealloc(pArray->pData, tsize * pArray->elemSize);
H
Hongze Cheng 已提交
69
    if (pArray->pData == NULL) {
L
Liu Jicong 已提交
70
      return -1;
H
hjxilinx 已提交
71
    }
H
Hongze Cheng 已提交
72 73

    pArray->capacity = tsize;
H
more  
hzcheng 已提交
74
  }
L
Liu Jicong 已提交
75 76 77
  return 0;
}

S
tarray  
Shengliang Guan 已提交
78
void* taosArrayAddBatch(SArray* pArray, const void* pData, int32_t nEles) {
L
Liu Jicong 已提交
79
  if (pData == NULL) {
L
Liu Jicong 已提交
80 81 82
    return NULL;
  }

S
tarray  
Shengliang Guan 已提交
83
  if (taosArrayEnsureCap(pArray, pArray->size + nEles) != 0) {
L
Liu Jicong 已提交
84 85
    return NULL;
  }
H
more  
hzcheng 已提交
86 87

  void* dst = TARRAY_GET_ELEM(pArray, pArray->size);
H
Hongze Cheng 已提交
88
  memcpy(dst, pData, pArray->elemSize * nEles);
H
more  
hzcheng 已提交
89

H
Hongze Cheng 已提交
90
  pArray->size += nEles;
H
more  
hzcheng 已提交
91 92 93
  return dst;
}

S
tarray  
Shengliang Guan 已提交
94
void taosArrayRemoveBatch(SArray* pArray, const int32_t* pData, int32_t numOfElems) {
95 96 97 98 99 100 101 102 103 104 105 106
  assert(pArray != NULL && pData != NULL);
  if (numOfElems <= 0) {
    return;
  }

  size_t size = taosArrayGetSize(pArray);
  if (numOfElems >= size) {
    taosArrayClear(pArray);
    return;
  }

  int32_t i = pData[0] + 1, j = 0;
S
tarray  
Shengliang Guan 已提交
107
  while (i < size) {
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    if (j == numOfElems - 1) {
      break;
    }

    char* p = TARRAY_GET_ELEM(pArray, i);
    if (i > pData[j] && i < pData[j + 1]) {
      char* dst = TARRAY_GET_ELEM(pArray, i - (j + 1));
      memmove(dst, p, pArray->elemSize);
    } else if (i == pData[j + 1]) {
      j += 1;
    }

    i += 1;
  }

H
Haojun Liao 已提交
123
  assert(i == pData[numOfElems - 1] + 1 && i <= size);
124 125

  int32_t srcIndex = pData[numOfElems - 1] + 1;
H
Haojun Liao 已提交
126 127 128 129 130 131
  int32_t dstIndex = pData[numOfElems - 1] - numOfElems + 1;
  if (pArray->size - srcIndex > 0) {
    char* dst = TARRAY_GET_ELEM(pArray, dstIndex);
    char* src = TARRAY_GET_ELEM(pArray, srcIndex);
    memmove(dst, src, pArray->elemSize * (pArray->size - srcIndex));
  }
132 133 134 135

  pArray->size -= numOfElems;
}

S
tarray  
Shengliang Guan 已提交
136
void taosArrayRemoveDuplicate(SArray* pArray, __compar_fn_t comparFn, void (*fp)(void*)) {
137 138 139 140 141 142 143 144
  assert(pArray);

  size_t size = pArray->size;
  if (size <= 1) {
    return;
  }

  int32_t pos = 0;
S
tarray  
Shengliang Guan 已提交
145
  for (int32_t i = 1; i < size; ++i) {
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    char* p1 = taosArrayGet(pArray, pos);
    char* p2 = taosArrayGet(pArray, i);

    if (comparFn(p1, p2) == 0) {
      // do nothing
    } else {
      if (pos + 1 != i) {
        void* p = taosArrayGet(pArray, pos + 1);
        if (fp != NULL) {
          fp(p);
        }

        taosArraySet(pArray, pos + 1, p2);
        pos += 1;
      } else {
        pos += 1;
      }
    }
  }

  if (fp != NULL) {
S
tarray  
Shengliang Guan 已提交
167
    for (int32_t i = pos + 1; i < pArray->size; ++i) {
168 169 170 171 172 173 174 175
      void* p = taosArrayGet(pArray, i);
      fp(p);
    }
  }

  pArray->size = pos + 1;
}

H
Haojun Liao 已提交
176
void* taosArrayAddAll(SArray* pArray, const SArray* pInput) {
177 178 179 180 181
  if (pInput) {
    return taosArrayAddBatch(pArray, pInput->pData, (int32_t)taosArrayGetSize(pInput));
  } else {
    return NULL;
  }
H
Haojun Liao 已提交
182 183
}

weixin_48148422's avatar
weixin_48148422 已提交
184
void* taosArrayPop(SArray* pArray) {
S
tarray  
Shengliang Guan 已提交
185
  assert(pArray != NULL);
186 187

  if (pArray->size == 0) {
weixin_48148422's avatar
weixin_48148422 已提交
188
    return NULL;
H
more  
hzcheng 已提交
189 190
  }
  pArray->size -= 1;
weixin_48148422's avatar
weixin_48148422 已提交
191
  return TARRAY_GET_ELEM(pArray, pArray->size);
H
more  
hzcheng 已提交
192 193
}

194
void* taosArrayGet(const SArray* pArray, size_t index) {
H
more  
hzcheng 已提交
195 196 197 198
  assert(index < pArray->size);
  return TARRAY_GET_ELEM(pArray, index);
}

199
void* taosArrayGetP(const SArray* pArray, size_t index) {
H
Haojun Liao 已提交
200
  assert(index < pArray->size);
S
tarray  
Shengliang Guan 已提交
201

H
Haojun Liao 已提交
202
  void* d = TARRAY_GET_ELEM(pArray, index);
S
tarray  
Shengliang Guan 已提交
203

H
Haojun Liao 已提交
204
  return *(void**)d;
H
hjxilinx 已提交
205 206
}

S
tarray  
Shengliang Guan 已提交
207
void* taosArrayGetLast(const SArray* pArray) { return TARRAY_GET_ELEM(pArray, pArray->size - 1); }
H
Haojun Liao 已提交
208

L
Liu Jicong 已提交
209
size_t taosArrayGetSize(const SArray* pArray) {
S
Shengliang Guan 已提交
210 211 212
  if (pArray == NULL) {
    return 0;
  }
L
Liu Jicong 已提交
213
  return pArray->size;
S
Shengliang Guan 已提交
214
}
H
more  
hzcheng 已提交
215

216 217 218 219 220
void taosArraySetSize(SArray* pArray, size_t size) {
  assert(size <= pArray->capacity);
  pArray->size = size;
}

H
hjxilinx 已提交
221
void* taosArrayInsert(SArray* pArray, size_t index, void* pData) {
H
more  
hzcheng 已提交
222
  if (pArray == NULL || pData == NULL) {
H
hjxilinx 已提交
223
    return NULL;
H
more  
hzcheng 已提交
224 225 226
  }

  if (index >= pArray->size) {
H
hjxilinx 已提交
227
    return taosArrayPush(pArray, pData);
H
more  
hzcheng 已提交
228 229 230
  }

  if (pArray->size >= pArray->capacity) {
H
hjxilinx 已提交
231
    int32_t ret = taosArrayResize(pArray);
S
tarray  
Shengliang Guan 已提交
232

H
hjxilinx 已提交
233 234 235
    if (ret < 0) {
      return NULL;
    }
H
more  
hzcheng 已提交
236 237 238 239
  }

  void* dst = TARRAY_GET_ELEM(pArray, index);

S
Shengliang Guan 已提交
240 241
  int32_t remain = (int32_t)(pArray->size - index);
  memmove((char*)dst + pArray->elemSize, (char*)dst, pArray->elemSize * remain);
H
more  
hzcheng 已提交
242 243 244
  memcpy(dst, pData, pArray->elemSize);

  pArray->size += 1;
S
tarray  
Shengliang Guan 已提交
245

H
hjxilinx 已提交
246
  return dst;
H
more  
hzcheng 已提交
247 248
}

H
Hongze Cheng 已提交
249
void taosArraySet(SArray* pArray, size_t index, void* pData) {
H
refact  
Hongze Cheng 已提交
250 251 252 253
  assert(index < pArray->size);
  memcpy(TARRAY_GET_ELEM(pArray, index), pData, pArray->elemSize);
}

L
Liu Jicong 已提交
254 255 256
void taosArrayPopFrontBatch(SArray* pArray, size_t cnt) {
  assert(cnt <= pArray->size);
  pArray->size = pArray->size - cnt;
S
tarray  
Shengliang Guan 已提交
257
  if (pArray->size == 0) {
L
Liu Jicong 已提交
258 259
    return;
  }
L
Liu Jicong 已提交
260
  memmove(pArray->pData, (char*)pArray->pData + cnt * pArray->elemSize, pArray->size * pArray->elemSize);
L
Liu Jicong 已提交
261 262
}

L
Liu Jicong 已提交
263 264 265 266 267
void taosArrayPopTailBatch(SArray* pArray, size_t cnt) {
  assert(cnt <= pArray->size);
  pArray->size = pArray->size - cnt;
}

268 269
void taosArrayRemove(SArray* pArray, size_t index) {
  assert(index < pArray->size);
S
tarray  
Shengliang Guan 已提交
270

271 272 273 274
  if (index == pArray->size - 1) {
    taosArrayPop(pArray);
    return;
  }
S
tarray  
Shengliang Guan 已提交
275

276
  size_t remain = pArray->size - index - 1;
S
tarray  
Shengliang Guan 已提交
277 278
  memmove((char*)pArray->pData + index * pArray->elemSize, (char*)pArray->pData + (index + 1) * pArray->elemSize,
          remain * pArray->elemSize);
279 280 281
  pArray->size -= 1;
}

H
Haojun Liao 已提交
282 283 284 285 286 287 288 289
SArray* taosArrayFromList(const void* src, size_t size, size_t elemSize) {
  assert(src != NULL && elemSize > 0);
  SArray* pDst = taosArrayInit(size, elemSize);

  memcpy(pDst->pData, src, elemSize * size);
  pDst->size = size;

  return pDst;
290 291
}

H
Haojun Liao 已提交
292
SArray* taosArrayDup(const SArray* pSrc) {
H
hjxilinx 已提交
293
  assert(pSrc != NULL);
S
tarray  
Shengliang Guan 已提交
294 295

  if (pSrc->size == 0) {  // empty array list
H
hjxilinx 已提交
296 297
    return taosArrayInit(8, pSrc->elemSize);
  }
S
tarray  
Shengliang Guan 已提交
298

H
hjxilinx 已提交
299
  SArray* dst = taosArrayInit(pSrc->size, pSrc->elemSize);
S
tarray  
Shengliang Guan 已提交
300

H
hjxilinx 已提交
301 302 303 304 305
  memcpy(dst->pData, pSrc->pData, pSrc->elemSize * pSrc->size);
  dst->size = pSrc->size;
  return dst;
}

weixin_48148422's avatar
weixin_48148422 已提交
306
void taosArrayClear(SArray* pArray) {
S
Shengliang Guan 已提交
307
  if (pArray == NULL) return;
weixin_48148422's avatar
weixin_48148422 已提交
308 309 310
  pArray->size = 0;
}

D
dapan1121 已提交
311 312 313 314 315 316 317 318 319 320 321 322 323 324
void taosArrayClearEx(SArray* pArray, void (*fp)(void*)) {
  if (pArray == NULL) return;
  if (fp == NULL) {
    pArray->size = 0;
    return;
  }

  for (int32_t i = 0; i < pArray->size; ++i) {
    fp(TARRAY_GET_ELEM(pArray, i));
  }

  pArray->size = 0;
}

R
root 已提交
325 326 327 328 329 330 331 332 333 334 335 336 337 338
void taosArrayClearP(SArray* pArray, FDelete fp) {
  if (pArray == NULL) return;
  if (fp == NULL) {
    pArray->size = 0;
    return;
  }

  for (int32_t i = 0; i < pArray->size; ++i) {
    fp(*(void**)TARRAY_GET_ELEM(pArray, i));
  }

  pArray->size = 0;
}

H
Hongze Cheng 已提交
339 340
void* taosArrayDestroy(SArray* pArray) {
  if (pArray) {
wafwerar's avatar
wafwerar 已提交
341 342
    taosMemoryFree(pArray->pData);
    taosMemoryFree(pArray);
H
more  
hzcheng 已提交
343 344
  }

H
Hongze Cheng 已提交
345
  return NULL;
H
more  
hzcheng 已提交
346
}
weixin_48148422's avatar
weixin_48148422 已提交
347

348 349 350 351 352 353 354 355
void taosArrayDestroyP(SArray* pArray, FDelete fp) {
  for (int32_t i = 0; i < pArray->size; i++) {
    fp(*(void**)TARRAY_GET_ELEM(pArray, i));
  }
  taosArrayDestroy(pArray);
}

void taosArrayDestroyEx(SArray* pArray, FDelete fp) {
H
Haojun Liao 已提交
356 357 358 359
  if (pArray == NULL) {
    return;
  }

H
Haojun Liao 已提交
360
  if (fp == NULL) {
H
Haojun Liao 已提交
361 362
    taosArrayDestroy(pArray);
    return;
H
Haojun Liao 已提交
363 364
  }

S
tarray  
Shengliang Guan 已提交
365
  for (int32_t i = 0; i < pArray->size; ++i) {
H
Haojun Liao 已提交
366 367 368 369 370 371
    fp(TARRAY_GET_ELEM(pArray, i));
  }

  taosArrayDestroy(pArray);
}

372
void taosArraySort(SArray* pArray, __compar_fn_t compar) {
weixin_48148422's avatar
weixin_48148422 已提交
373 374 375
  assert(pArray != NULL);
  assert(compar != NULL);

wafwerar's avatar
wafwerar 已提交
376
  taosSort(pArray->pData, pArray->size, pArray->elemSize, compar);
weixin_48148422's avatar
weixin_48148422 已提交
377 378
}

S
tarray  
Shengliang Guan 已提交
379
void* taosArraySearch(const SArray* pArray, const void* key, __compar_fn_t comparFn, int32_t flags) {
380
  assert(pArray != NULL && comparFn != NULL);
weixin_48148422's avatar
weixin_48148422 已提交
381 382
  assert(key != NULL);

H
refact  
Hongze Cheng 已提交
383
  return taosbsearch(key, pArray->pData, pArray->size, pArray->elemSize, comparFn, flags);
weixin_48148422's avatar
weixin_48148422 已提交
384 385
}

S
tarray  
Shengliang Guan 已提交
386
int32_t taosArraySearchIdx(const SArray* pArray, const void* key, __compar_fn_t comparFn, int32_t flags) {
L
Liu Jicong 已提交
387
  void* item = taosArraySearch(pArray, key, comparFn, flags);
L
Liu Jicong 已提交
388
  return item == NULL ? -1 : (int32_t)((char*)item - (char*)pArray->pData) / pArray->elemSize;
L
Liu Jicong 已提交
389 390
}

391
void taosArraySortString(SArray* pArray, __compar_fn_t comparFn) {
weixin_48148422's avatar
weixin_48148422 已提交
392
  assert(pArray != NULL);
wafwerar's avatar
wafwerar 已提交
393
  taosSort(pArray->pData, pArray->size, pArray->elemSize, comparFn);
weixin_48148422's avatar
weixin_48148422 已提交
394 395
}

S
tarray  
Shengliang Guan 已提交
396
char* taosArraySearchString(const SArray* pArray, const char* key, __compar_fn_t comparFn, int32_t flags) {
weixin_48148422's avatar
weixin_48148422 已提交
397 398 399
  assert(pArray != NULL);
  assert(key != NULL);

H
refact  
Hongze Cheng 已提交
400
  void* p = taosbsearch(&key, pArray->pData, pArray->size, pArray->elemSize, comparFn, flags);
weixin_48148422's avatar
weixin_48148422 已提交
401 402 403 404
  if (p == NULL) {
    return NULL;
  }
  return *(char**)p;
405 406
}

S
tarray  
Shengliang Guan 已提交
407 408
static int32_t taosArrayPartition(SArray* pArray, int32_t i, int32_t j, __ext_compar_fn_t fn, const void* userData) {
  void* key = taosArrayGetP(pArray, i);
409
  while (i < j) {
S
tarray  
Shengliang Guan 已提交
410 411 412 413 414
    while (i < j && fn(taosArrayGetP(pArray, j), key, userData) >= 0) {
      j--;
    }
    if (i < j) {
      void* a = taosArrayGetP(pArray, j);
415 416
      taosArraySet(pArray, i, &a);
    }
S
tarray  
Shengliang Guan 已提交
417 418 419
    while (i < j && fn(taosArrayGetP(pArray, i), key, userData) <= 0) {
      i++;
    }
420
    if (i < j) {
S
tarray  
Shengliang Guan 已提交
421
      void* a = taosArrayGetP(pArray, i);
422 423 424
      taosArraySet(pArray, j, &a);
    }
  }
S
tarray  
Shengliang Guan 已提交
425
  taosArraySet(pArray, i, &key);
426 427 428
  return i;
}

S
tarray  
Shengliang Guan 已提交
429 430
static void taosArrayQuicksortHelper(SArray* pArray, int32_t low, int32_t high, __ext_compar_fn_t fn,
                                     const void* param) {
431
  if (low < high) {
S
tarray  
Shengliang Guan 已提交
432
    int32_t idx = taosArrayPartition(pArray, low, high, fn, param);
433 434
    taosArrayQuicksortHelper(pArray, low, idx - 1, fn, param);
    taosArrayQuicksortHelper(pArray, idx + 1, high, fn, param);
S
tarray  
Shengliang Guan 已提交
435
  }
436 437
}

S
tarray  
Shengliang Guan 已提交
438
static void taosArrayQuickSort(SArray* pArray, __ext_compar_fn_t fn, const void* param) {
439
  if (pArray->size <= 1) {
440
    return;
S
tarray  
Shengliang Guan 已提交
441 442
  }
  taosArrayQuicksortHelper(pArray, 0, (int32_t)(taosArrayGetSize(pArray) - 1), fn, param);
443
}
S
tarray  
Shengliang Guan 已提交
444 445

static void taosArrayInsertSort(SArray* pArray, __ext_compar_fn_t fn, const void* param) {
446
  if (pArray->size <= 1) {
447
    return;
S
tarray  
Shengliang Guan 已提交
448 449 450
  }
  for (int32_t i = 1; i <= pArray->size - 1; ++i) {
    for (int32_t j = i; j > 0; --j) {
451
      if (fn(taosArrayGetP(pArray, j), taosArrayGetP(pArray, j - 1), param) == -1) {
S
tarray  
Shengliang Guan 已提交
452 453
        void* a = taosArrayGetP(pArray, j);
        void* b = taosArrayGetP(pArray, j - 1);
454 455 456 457 458 459 460
        taosArraySet(pArray, j - 1, &a);
        taosArraySet(pArray, j, &b);
      } else {
        break;
      }
    }
  }
461
  return;
S
tarray  
Shengliang Guan 已提交
462 463
}

464
SArray* taosArrayDeepCopy(const SArray* pSrc, FCopy deepCopy) {
D
dapan1121 已提交
465 466 467
  if (NULL == pSrc) {
    return NULL;
  }
L
Liu Jicong 已提交
468 469
  ASSERT(pSrc->elemSize == sizeof(void*));
  SArray* pArray = taosArrayInit(pSrc->size, sizeof(void*));
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
  for (int32_t i = 0; i < pSrc->size; i++) {
    void* clone = deepCopy(taosArrayGetP(pSrc, i));
    taosArrayPush(pArray, &clone);
  }
  return pArray;
}

int32_t taosEncodeArray(void** buf, const SArray* pArray, FEncode encode) {
  int32_t tlen = 0;
  int32_t sz = pArray->size;
  tlen += taosEncodeFixedI32(buf, sz);
  for (int32_t i = 0; i < sz; i++) {
    void* data = taosArrayGetP(pArray, i);
    tlen += encode(buf, data);
  }
  return tlen;
}

void* taosDecodeArray(const void* buf, SArray** pArray, FDecode decode, int32_t dataSz) {
  int32_t sz;
  buf = taosDecodeFixedI32(buf, &sz);
  *pArray = taosArrayInit(sz, sizeof(void*));
  for (int32_t i = 0; i < sz; i++) {
    void* data = taosMemoryCalloc(1, dataSz);
    buf = decode(buf, data);
L
Liu Jicong 已提交
495
    taosArrayPush(*pArray, &data);
496 497 498 499
  }
  return (void*)buf;
}

500
// todo remove it
S
tarray  
Shengliang Guan 已提交
501 502 503 504 505
// order array<type *>
void taosArraySortPWithExt(SArray* pArray, __ext_compar_fn_t fn, const void* param) {
  taosArrayGetSize(pArray) > 8 ? taosArrayQuickSort(pArray, fn, param) : taosArrayInsertSort(pArray, fn, param);
}
// TODO(yihaoDeng) add order array<type>
L
Liu Jicong 已提交
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
//

char* taosShowStrArray(const SArray* pArray) {
  int32_t sz = pArray->size;
  int32_t tlen = 0;
  for (int32_t i = 0; i < sz; i++) {
    tlen += strlen(taosArrayGetP(pArray, i)) + 1;
  }
  char* res = taosMemoryCalloc(1, tlen);
  char* buf = res;
  for (int32_t i = 0; i < sz; i++) {
    char*   str = taosArrayGetP(pArray, i);
    int32_t len = strlen(str);
    memcpy(buf, str, len);
    buf += len;
    if (i != sz - 1) *buf = ',';
  }
  return res;
}