sortTests.cpp 11.7 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

namespace {
typedef struct {
  int32_t startVal;
  int32_t count;
  int32_t pageRows;
wmmhello's avatar
wmmhello 已提交
43
  int16_t type;
44 45
} _info;

wmmhello's avatar
wmmhello 已提交
46
int16_t VARCOUNT = 16;
47

wmmhello's avatar
wmmhello 已提交
48 49 50 51 52 53
float rand_f2()
{
  unsigned r = taosRand();
  r &= 0x007fffff;
  r |= 0x40800000;
  return *(float*)&r - 6.0;
54 55
}

wmmhello's avatar
wmmhello 已提交
56 57 58 59
static const int32_t TEST_NUMBER = 1;
#define bigendian()     ((*(char *)&TEST_NUMBER) == 0)

SSDataBlock* getSingleColDummyBlock(void* param) {
wmmhello's avatar
wmmhello 已提交
60 61 62 63 64 65 66 67 68
  _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};
wmmhello's avatar
wmmhello 已提交
69 70 71 72 73 74 75 76 77 78 79 80
  colInfo.info.type = pInfo->type;
  if (pInfo->type == TSDB_DATA_TYPE_NCHAR){
    colInfo.info.bytes = TSDB_NCHAR_SIZE * VARCOUNT + VARSTR_HEADER_SIZE;
    colInfo.varmeta.offset = static_cast<int32_t *>(taosMemoryCalloc(pInfo->pageRows, sizeof(int32_t)));
  } else if(pInfo->type == TSDB_DATA_TYPE_BINARY) {
    colInfo.info.bytes = VARCOUNT + VARSTR_HEADER_SIZE;
    colInfo.varmeta.offset = static_cast<int32_t *>(taosMemoryCalloc(pInfo->pageRows, sizeof(int32_t)));
  } else{
    colInfo.info.bytes = tDataTypes[pInfo->type].bytes;
    colInfo.pData = static_cast<char*>(taosMemoryCalloc(pInfo->pageRows, colInfo.info.bytes));
    colInfo.nullbitmap = static_cast<char*>(taosMemoryCalloc(1, (pInfo->pageRows + 7) / 8));
  }
wmmhello's avatar
wmmhello 已提交
81 82 83 84 85 86 87
  colInfo.info.colId = 1;

  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 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    if (pInfo->type == TSDB_DATA_TYPE_NCHAR){
      int32_t size = taosRand() % VARCOUNT;
      char str[128] = {0};
      char strOri[128] = {0};
      taosRandStr(strOri, size);
      int32_t len = 0;
      bool ret = taosMbsToUcs4(strOri, size, (TdUcs4*)varDataVal(str), 128, &len);
      if (!ret){
        printf("error\n");
        return NULL;
      }
      varDataSetLen(str, len);
      colDataAppend(pColInfo, i, reinterpret_cast<const char*>(str), false);
      pBlock->info.hasVarCol = true;
      printf("nchar: %s\n",strOri);
    } else if(pInfo->type == TSDB_DATA_TYPE_BINARY){
      int32_t size = taosRand() % VARCOUNT;
      char str[64] = {0};
      taosRandStr(varDataVal(str), size);
      varDataSetLen(str, size);
      colDataAppend(pColInfo, i, reinterpret_cast<const char*>(str), false);
      pBlock->info.hasVarCol = true;
      printf("binary: %s\n", varDataVal(str));
    } else if(pInfo->type == TSDB_DATA_TYPE_DOUBLE || pInfo->type == TSDB_DATA_TYPE_FLOAT) {
      double v = rand_f2();
      colDataAppend(pColInfo, i, reinterpret_cast<const char*>(&v), false);
      printf("float: %f\n", v);
    } else{
      int64_t v = ++pInfo->startVal;
      char *result = static_cast<char*>(taosMemoryCalloc(tDataTypes[pInfo->type].bytes, 1));
      if (!bigendian()){
        memcpy(result, &v, tDataTypes[pInfo->type].bytes);
      }else{
        memcpy(result, (char*)(&v) + sizeof(int64_t) - tDataTypes[pInfo->type].bytes, tDataTypes[pInfo->type].bytes);
      }

      colDataAppend(pColInfo, i, result, false);
      printf("int: %lld\n", v);
    }
wmmhello's avatar
wmmhello 已提交
127 128 129 130 131 132 133 134
  }

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


135 136 137 138 139
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 已提交
140
  SGenericSource** px = reinterpret_cast<SGenericSource**>(pParam->pSources);
141 142 143

  SArray *pInfo = pParam->orderInfo;

H
Haojun Liao 已提交
144 145
  SGenericSource* pLeftSource  = px[pLeftIdx];
  SGenericSource* pRightSource = px[pRightIdx];
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

  // 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 已提交
162
    SColumnInfoData* pLeftColInfoData = (SColumnInfoData*)TARRAY_GET_ELEM(pLeftBlock->pDataBlock, pOrder->slotId);
163 164 165 166 167 168

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

H
Haojun Liao 已提交
169
    SColumnInfoData* pRightColInfoData = (SColumnInfoData*) TARRAY_GET_ELEM(pRightBlock->pDataBlock, pOrder->slotId);
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    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;
    }

187 188
    void* left1  = colDataGetData(pLeftColInfoData, pLeftSource->src.rowIndex);
    void* right1 = colDataGetData(pRightColInfoData, pRightSource->src.rowIndex);
189
    __compar_fn_t fn = getKeyComparFunc(pLeftColInfoData->info.type, pOrder->order);
190

191 192 193 194 195
    int ret = fn(left1, right1);
    if (ret == 0) {
      continue;
    } else {
      return ret;
196 197
    }
  }
H
Haojun Liao 已提交
198 199

  return 0;
200 201 202
}
}  // namespace

wmmhello's avatar
wmmhello 已提交
203
#if 1
204
TEST(testCase, inMem_sort_Test) {
H
Haojun Liao 已提交
205 206
  SBlockOrderInfo oi = {0};
  oi.order = TSDB_ORDER_ASC;
207
  oi.slotId = 0;
H
Haojun Liao 已提交
208 209 210
  SArray* orderInfo = taosArrayInit(1, sizeof(SBlockOrderInfo));
  taosArrayPush(orderInfo, &oi);

211
  SSortHandle* phandle = tsortCreateSortHandle(orderInfo, SORT_SINGLESOURCE_SORT, 1024, 5, NULL, "test_abc");
H
Haojun Liao 已提交
212
  tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);
213 214 215 216 217

  _info* pInfo = (_info*) taosMemoryCalloc(1, sizeof(_info));
  pInfo->startVal = 0;
  pInfo->pageRows = 100;
  pInfo->count = 6;
wmmhello's avatar
wmmhello 已提交
218
  pInfo->type = TSDB_DATA_TYPE_USMALLINT;
219 220 221 222

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

H
Haojun Liao 已提交
224
  int32_t code = tsortOpen(phandle);
225
  int32_t row = 1;
wmmhello's avatar
wmmhello 已提交
226
  taosMemoryFreeClear(ps);
227 228

  while(1) {
H
Haojun Liao 已提交
229
    STupleHandle* pTupleHandle = tsortNextTuple(phandle);
230 231 232 233
    if (pTupleHandle == NULL) {
      break;
    }

H
Haojun Liao 已提交
234
    void* v = tsortGetValue(pTupleHandle, 0);
wmmhello's avatar
wmmhello 已提交
235 236
    printf("%d: %d\n", row, *(uint16_t*) v);
    ASSERT_EQ(row++, *(uint16_t*) v);
237 238

  }
wmmhello's avatar
wmmhello 已提交
239
  taosArrayDestroy(orderInfo);
H
Haojun Liao 已提交
240
  tsortDestroySortHandle(phandle);
241 242 243
}

TEST(testCase, external_mem_sort_Test) {
H
Haojun Liao 已提交
244

wmmhello's avatar
wmmhello 已提交
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
  _info* pInfo = (_info*) taosMemoryCalloc(7, sizeof(_info));
  pInfo[0].startVal = 0;
  pInfo[0].pageRows = 10;
  pInfo[0].count = 6;
  pInfo[0].type = TSDB_DATA_TYPE_BOOL;

  pInfo[1].startVal = 0;
  pInfo[1].pageRows = 10;
  pInfo[1].count = 6;
  pInfo[1].type = TSDB_DATA_TYPE_TINYINT;

  pInfo[2].startVal = 0;
  pInfo[2].pageRows = 100;
  pInfo[2].count = 6;
  pInfo[2].type = TSDB_DATA_TYPE_USMALLINT;

  pInfo[2].startVal = 0;
  pInfo[2].pageRows = 100;
  pInfo[2].count = 6;
  pInfo[2].type = TSDB_DATA_TYPE_INT;

  pInfo[3].startVal = 0;
  pInfo[3].pageRows = 100;
  pInfo[3].count = 6;
  pInfo[3].type = TSDB_DATA_TYPE_UBIGINT;

  pInfo[4].startVal = 0;
  pInfo[4].pageRows = 100;
  pInfo[4].count = 6;
  pInfo[4].type = TSDB_DATA_TYPE_DOUBLE;

  pInfo[5].startVal = 0;
  pInfo[5].pageRows = 50;
  pInfo[5].count = 6;
  pInfo[5].type = TSDB_DATA_TYPE_NCHAR;

  pInfo[6].startVal = 0;
  pInfo[6].pageRows = 100;
  pInfo[6].count = 6;
  pInfo[6].type = TSDB_DATA_TYPE_BINARY;

  for (int i = 0; i < 7; i++){
    SBlockOrderInfo oi = {0};
    oi.order = TSDB_ORDER_ASC;
    oi.slotId = 0;
    SArray* orderInfo = taosArrayInit(1, sizeof(SBlockOrderInfo));
    taosArrayPush(orderInfo, &oi);

    SSortHandle* phandle = tsortCreateSortHandle(orderInfo, SORT_SINGLESOURCE_SORT, 128, 3, NULL, "test_abc");
    tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);

    SGenericSource* ps = static_cast<SGenericSource*>(taosMemoryCalloc(1, sizeof(SGenericSource)));
    ps->param = &pInfo[i];

    tsortAddSource(phandle, ps);

    int32_t code = tsortOpen(phandle);
    int32_t row = 1;
    taosMemoryFreeClear(ps);

    printf("--------start with %s-----------\n", tDataTypes[pInfo[i].type].name);
    while(1) {
      STupleHandle* pTupleHandle = tsortNextTuple(phandle);
      if (pTupleHandle == NULL) {
        break;
      }

      void* v = tsortGetValue(pTupleHandle, 0);

      if(pInfo[i].type == TSDB_DATA_TYPE_NCHAR){
        char        buf[128] = {0};
        int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(v), varDataLen(v), buf);
        printf("%d: %s\n", row++, buf);
      }else if(pInfo[i].type == TSDB_DATA_TYPE_BINARY){
        char        buf[128] = {0};
        memcpy(buf, varDataVal(v), varDataLen(v));
        printf("%d: %s\n", row++, buf);
      }else{
        int64_t result = 0;
        if (!bigendian()){
          memcpy(&result, v, tDataTypes[pInfo[i].type].bytes);
        }else{
          memcpy((char*)(&result) + sizeof(int64_t) - tDataTypes[pInfo[i].type].bytes, v, tDataTypes[pInfo[i].type].bytes);
        }
        printf("%d: %lld\n", row++, result);
      }
H
Haojun Liao 已提交
331
    }
wmmhello's avatar
wmmhello 已提交
332 333
    taosArrayDestroy(orderInfo);
    tsortDestroySortHandle(phandle);
H
Haojun Liao 已提交
334
  }
wmmhello's avatar
wmmhello 已提交
335
  taosMemoryFree(pInfo);
H
Haojun Liao 已提交
336
}
337

338 339 340
TEST(testCase, ordered_merge_sort_Test) {
  SBlockOrderInfo oi = {0};
  oi.order = TSDB_ORDER_ASC;
341
  oi.slotId = 0;
342 343 344
  SArray* orderInfo = taosArrayInit(1, sizeof(SBlockOrderInfo));
  taosArrayPush(orderInfo, &oi);

wmmhello's avatar
wmmhello 已提交
345 346 347 348 349 350 351 352 353 354 355 356
  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 已提交
357 358
  tsortSetFetchRawDataFp(phandle, getSingleColDummyBlock);
  tsortSetComparFp(phandle, docomp);
359 360

  for(int32_t i = 0; i < 10; ++i) {
wafwerar's avatar
wafwerar 已提交
361 362
    SGenericSource* p = static_cast<SGenericSource*>(taosMemoryCalloc(1, sizeof(SGenericSource)));
    _info* c = static_cast<_info*>(taosMemoryCalloc(1, sizeof(_info)));
363 364
    c->count    = 1;
    c->pageRows = 1000;
365
    c->startVal = i*1000;
366 367

    p->param = c;
H
Haojun Liao 已提交
368
    tsortAddSource(phandle, p);
369 370
  }

H
Haojun Liao 已提交
371
  int32_t code = tsortOpen(phandle);
372 373 374
  int32_t row = 1;

  while(1) {
H
Haojun Liao 已提交
375
    STupleHandle* pTupleHandle = tsortNextTuple(phandle);
376 377 378 379
    if (pTupleHandle == NULL) {
      break;
    }

H
Haojun Liao 已提交
380
    void* v = tsortGetValue(pTupleHandle, 0);
381 382
    printf("%d: %d\n", row, *(int32_t*) v);
    ASSERT_EQ(row++, *(int32_t*) v);
383 384

  }
H
Haojun Liao 已提交
385
  tsortDestroySortHandle(phandle);
wmmhello's avatar
wmmhello 已提交
386
  taosMemoryFree(pBlock);
387 388 389
}

#endif
390 391

#pragma GCC diagnostic pop