sortTests.cpp 9.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * 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/>.
 */

#include <gtest/gtest.h>
#include <tglobal.h>
#include <tsort.h>
#include <iostream>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#include "os.h"

28
#include "executorimpl.h"
29 30 31
#include "executor.h"
#include "stub.h"
#include "taos.h"
H
Haojun Liao 已提交
32
#include "tdatablock.h"
33 34 35
#include "tdef.h"
#include "trpc.h"
#include "tvariant.h"
36
#include "tcompare.h"
37 38 39 40 41 42 43 44 45 46 47 48 49 50

namespace {
typedef struct {
  int32_t startVal;
  int32_t count;
  int32_t pageRows;
} _info;

SSDataBlock* getSingleColDummyBlock(void* param) {
  _info* pInfo = (_info*) param;
  if (--pInfo->count < 0) {
    return NULL;
  }

wafwerar's avatar
wafwerar 已提交
51
  SSDataBlock* pBlock = static_cast<SSDataBlock*>(taosMemoryCalloc(1, sizeof(SSDataBlock)));
52 53 54 55 56 57
  pBlock->pDataBlock = taosArrayInit(4, sizeof(SColumnInfoData));

  SColumnInfoData colInfo = {0};
  colInfo.info.type = TSDB_DATA_TYPE_INT;
  colInfo.info.bytes = sizeof(int32_t);
  colInfo.info.colId = 1;
wafwerar's avatar
wafwerar 已提交
58 59
  colInfo.pData = static_cast<char*>(taosMemoryCalloc(pInfo->pageRows, sizeof(int32_t)));
  colInfo.nullbitmap = static_cast<char*>(taosMemoryCalloc(1, (pInfo->pageRows + 7) / 8));
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

  taosArrayPush(pBlock->pDataBlock, &colInfo);

  for (int32_t i = 0; i < pInfo->pageRows; ++i) {
    SColumnInfoData* pColInfo = static_cast<SColumnInfoData*>(TARRAY_GET_ELEM(pBlock->pDataBlock, 0));

    int32_t v = ++pInfo->startVal;
    colDataAppend(pColInfo, i, reinterpret_cast<const char*>(&v), false);
  }

  pBlock->info.rows = pInfo->pageRows;
  pBlock->info.numOfCols = 1;
  return pBlock;
}

wmmhello's avatar
wmmhello 已提交
75 76 77 78 79 80 81 82 83 84 85
SSDataBlock* getSingleColStrBlock(void* param) {
  _info* pInfo = (_info*) param;
  if (--pInfo->count < 0) {
    return NULL;
  }

  SSDataBlock* pBlock = static_cast<SSDataBlock*>(taosMemoryCalloc(1, sizeof(SSDataBlock)));
  pBlock->pDataBlock = taosArrayInit(4, sizeof(SColumnInfoData));

  SColumnInfoData colInfo = {0};
  colInfo.info.type = TSDB_DATA_TYPE_NCHAR;
wmmhello's avatar
wmmhello 已提交
86
  colInfo.info.bytes = TSDB_NCHAR_SIZE * 16 + VARSTR_HEADER_SIZE;
wmmhello's avatar
wmmhello 已提交
87 88 89 90 91 92 93 94
  colInfo.info.colId = 1;
  colInfo.varmeta.offset = static_cast<int32_t *>(taosMemoryCalloc(pInfo->pageRows, sizeof(int32_t)));

  taosArrayPush(pBlock->pDataBlock, &colInfo);

  for (int32_t i = 0; i < pInfo->pageRows; ++i) {
    SColumnInfoData* pColInfo = static_cast<SColumnInfoData*>(TARRAY_GET_ELEM(pBlock->pDataBlock, 0));

wmmhello's avatar
wmmhello 已提交
95
    int32_t size = taosRand() % 16;
wmmhello's avatar
wmmhello 已提交
96 97 98 99 100 101 102 103
    char str[64] = {0};
    taosRandStr(varDataVal(str), size);
    varDataSetLen(str, size);
    colDataAppend(pColInfo, i, reinterpret_cast<const char*>(str), false);
  }

  pBlock->info.rows = pInfo->pageRows;
  pBlock->info.numOfCols = 1;
wmmhello's avatar
wmmhello 已提交
104 105
  pBlock->info.hasVarCol = true;

wmmhello's avatar
wmmhello 已提交
106 107 108 109
  return pBlock;
}


110 111 112 113 114
int32_t docomp(const void* p1, const void* p2, void* param) {
  int32_t pLeftIdx  = *(int32_t *)p1;
  int32_t pRightIdx = *(int32_t *)p2;

  SMsortComparParam *pParam = (SMsortComparParam *)param;
H
Haojun Liao 已提交
115
  SGenericSource** px = reinterpret_cast<SGenericSource**>(pParam->pSources);
116 117 118

  SArray *pInfo = pParam->orderInfo;

H
Haojun Liao 已提交
119 120
  SGenericSource* pLeftSource  = px[pLeftIdx];
  SGenericSource* pRightSource = px[pRightIdx];
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

  // this input is exhausted, set the special value to denote this
  if (pLeftSource->src.rowIndex == -1) {
    return 1;
  }

  if (pRightSource->src.rowIndex == -1) {
    return -1;
  }

  SSDataBlock* pLeftBlock = pLeftSource->src.pBlock;
  SSDataBlock* pRightBlock = pRightSource->src.pBlock;

  for(int32_t i = 0; i < pInfo->size; ++i) {
    SBlockOrderInfo* pOrder = (SBlockOrderInfo*)TARRAY_GET_ELEM(pInfo, i);

H
Haojun Liao 已提交
137
    SColumnInfoData* pLeftColInfoData = (SColumnInfoData*)TARRAY_GET_ELEM(pLeftBlock->pDataBlock, pOrder->slotId);
138 139 140 141 142 143

    bool leftNull  = false;
    if (pLeftColInfoData->hasNull) {
      leftNull = colDataIsNull(pLeftColInfoData, pLeftBlock->info.rows, pLeftSource->src.rowIndex, pLeftBlock->pBlockAgg);
    }

H
Haojun Liao 已提交
144
    SColumnInfoData* pRightColInfoData = (SColumnInfoData*) TARRAY_GET_ELEM(pRightBlock->pDataBlock, pOrder->slotId);
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
    bool rightNull = false;
    if (pRightColInfoData->hasNull) {
      rightNull = colDataIsNull(pRightColInfoData, pRightBlock->info.rows, pRightSource->src.rowIndex, pRightBlock->pBlockAgg);
    }

    if (leftNull && rightNull) {
      continue; // continue to next slot
    }

    if (rightNull) {
      return pParam->nullFirst? 1:-1;
    }

    if (leftNull) {
      return pParam->nullFirst? -1:1;
    }

162 163
    void* left1  = colDataGetData(pLeftColInfoData, pLeftSource->src.rowIndex);
    void* right1 = colDataGetData(pRightColInfoData, pRightSource->src.rowIndex);
164
    __compar_fn_t fn = getKeyComparFunc(pLeftColInfoData->info.type, pOrder->order);
165

166 167 168 169 170
    int ret = fn(left1, right1);
    if (ret == 0) {
      continue;
    } else {
      return ret;
171 172
    }
  }
H
Haojun Liao 已提交
173 174

  return 0;
175 176 177
}
}  // namespace

wmmhello's avatar
wmmhello 已提交
178
#if 1
179
TEST(testCase, inMem_sort_Test) {
H
Haojun Liao 已提交
180 181
  SBlockOrderInfo oi = {0};
  oi.order = TSDB_ORDER_ASC;
182
  oi.slotId = 0;
H
Haojun Liao 已提交
183 184 185 186
  SArray* orderInfo = taosArrayInit(1, sizeof(SBlockOrderInfo));
  taosArrayPush(orderInfo, &oi);

  SSchema s = {.type = TSDB_DATA_TYPE_INT, .colId = 1, .bytes = 4, };
187
  SSortHandle* phandle = tsortCreateSortHandle(orderInfo, SORT_SINGLESOURCE_SORT, 1024, 5, NULL, "test_abc");
H
Haojun Liao 已提交
188
  tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);
189 190 191 192 193 194 195 196 197

  _info* pInfo = (_info*) taosMemoryCalloc(1, sizeof(_info));
  pInfo->startVal = 0;
  pInfo->pageRows = 100;
  pInfo->count = 6;

  SGenericSource* ps = static_cast<SGenericSource*>(taosMemoryCalloc(1, sizeof(SGenericSource)));
  ps->param = pInfo;
  tsortAddSource(phandle, ps);
H
Haojun Liao 已提交
198

H
Haojun Liao 已提交
199
  int32_t code = tsortOpen(phandle);
200
  int32_t row = 1;
wmmhello's avatar
wmmhello 已提交
201
  taosMemoryFreeClear(ps);
202 203

  while(1) {
H
Haojun Liao 已提交
204
    STupleHandle* pTupleHandle = tsortNextTuple(phandle);
205 206 207 208
    if (pTupleHandle == NULL) {
      break;
    }

H
Haojun Liao 已提交
209
    void* v = tsortGetValue(pTupleHandle, 0);
210 211
    printf("%d: %d\n", row, *(int32_t*) v);
    ASSERT_EQ(row++, *(int32_t*) v);
212 213

  }
H
Haojun Liao 已提交
214
  tsortDestroySortHandle(phandle);
215 216 217 218 219
}

TEST(testCase, external_mem_sort_Test) {
  SBlockOrderInfo oi = {0};
  oi.order = TSDB_ORDER_ASC;
wmmhello's avatar
wmmhello 已提交
220
  oi.slotId = 0;
221 222 223
  SArray* orderInfo = taosArrayInit(1, sizeof(SBlockOrderInfo));
  taosArrayPush(orderInfo, &oi);

wmmhello's avatar
wmmhello 已提交
224
  SSortHandle* phandle = tsortCreateSortHandle(orderInfo, SORT_SINGLESOURCE_SORT, 128, 6, NULL, "test_abc");
H
Haojun Liao 已提交
225
  tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);
H
Haojun Liao 已提交
226

wafwerar's avatar
wafwerar 已提交
227
  _info* pInfo = (_info*) taosMemoryCalloc(1, sizeof(_info));
228 229 230
  pInfo->startVal = 0;
  pInfo->pageRows = 100;
  pInfo->count = 6;
H
Haojun Liao 已提交
231

wafwerar's avatar
wafwerar 已提交
232
  SGenericSource* ps = static_cast<SGenericSource*>(taosMemoryCalloc(1, sizeof(SGenericSource)));
H
Haojun Liao 已提交
233 234
  ps->param = pInfo;

H
Haojun Liao 已提交
235
  tsortAddSource(phandle, ps);
H
Haojun Liao 已提交
236

H
Haojun Liao 已提交
237
  int32_t code = tsortOpen(phandle);
H
Haojun Liao 已提交
238
  int32_t row = 1;
wmmhello's avatar
wmmhello 已提交
239
  taosMemoryFreeClear(ps);
H
Haojun Liao 已提交
240 241

  while(1) {
H
Haojun Liao 已提交
242
    STupleHandle* pTupleHandle = tsortNextTuple(phandle);
H
Haojun Liao 已提交
243 244 245 246
    if (pTupleHandle == NULL) {
      break;
    }

H
Haojun Liao 已提交
247
    void* v = tsortGetValue(pTupleHandle, 0);
248 249
    printf("%d: %d\n", row, *(int32_t*) v);
    ASSERT_EQ(row++, *(int32_t*) v);
wmmhello's avatar
wmmhello 已提交
250 251
    char        buf[64] = {0};
    memcpy(buf, varDataVal(v), varDataLen(v));
wmmhello's avatar
wmmhello 已提交
252
    //printf("%d: %s\n", row, buf);
H
Haojun Liao 已提交
253
  }
H
Haojun Liao 已提交
254
  tsortDestroySortHandle(phandle);
H
Haojun Liao 已提交
255
}
256

257 258 259
TEST(testCase, ordered_merge_sort_Test) {
  SBlockOrderInfo oi = {0};
  oi.order = TSDB_ORDER_ASC;
260
  oi.slotId = 0;
261 262 263
  SArray* orderInfo = taosArrayInit(1, sizeof(SBlockOrderInfo));
  taosArrayPush(orderInfo, &oi);

wmmhello's avatar
wmmhello 已提交
264 265 266 267 268 269 270 271 272 273 274 275
  SSDataBlock* pBlock = static_cast<SSDataBlock*>(taosMemoryCalloc(1, sizeof(SSDataBlock)));
  pBlock->pDataBlock = taosArrayInit(1, sizeof(SColumnInfoData));
  pBlock->info.numOfCols = 1;
  for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) {
    SColumnInfoData colInfo = {0};
    colInfo.info.type = TSDB_DATA_TYPE_INT;
    colInfo.info.bytes = sizeof(int32_t);
    colInfo.info.colId = 1;
    taosArrayPush(pBlock->pDataBlock, &colInfo);
  }

  SSortHandle* phandle = tsortCreateSortHandle(orderInfo, SORT_MULTISOURCE_MERGE, 1024, 5, pBlock,"test_abc");
H
Haojun Liao 已提交
276 277
  tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);
  tsortSetComparFp(phandle, docomp);
278 279

  for(int32_t i = 0; i < 10; ++i) {
wafwerar's avatar
wafwerar 已提交
280 281
    SGenericSource* p = static_cast<SGenericSource*>(taosMemoryCalloc(1, sizeof(SGenericSource)));
    _info* c = static_cast<_info*>(taosMemoryCalloc(1, sizeof(_info)));
282 283
    c->count    = 1;
    c->pageRows = 1000;
284
    c->startVal = i*1000;
285 286

    p->param = c;
H
Haojun Liao 已提交
287
    tsortAddSource(phandle, p);
288 289
  }

H
Haojun Liao 已提交
290
  int32_t code = tsortOpen(phandle);
291 292 293
  int32_t row = 1;

  while(1) {
H
Haojun Liao 已提交
294
    STupleHandle* pTupleHandle = tsortNextTuple(phandle);
295 296 297 298
    if (pTupleHandle == NULL) {
      break;
    }

H
Haojun Liao 已提交
299
    void* v = tsortGetValue(pTupleHandle, 0);
300 301
    printf("%d: %d\n", row, *(int32_t*) v);
    ASSERT_EQ(row++, *(int32_t*) v);
302 303

  }
H
Haojun Liao 已提交
304
  tsortDestroySortHandle(phandle);
wmmhello's avatar
wmmhello 已提交
305
  taosMemoryFree(pBlock);
306 307 308
}

#endif
309 310

#pragma GCC diagnostic pop