diff --git a/include/os/osMath.h b/include/os/osMath.h index e13c32422e..b0c75f4dd7 100644 --- a/include/os/osMath.h +++ b/include/os/osMath.h @@ -60,6 +60,13 @@ extern "C" { }) #endif +#ifndef __COMPAR_FN_T +#define __COMPAR_FN_T +typedef int32_t (*__compar_fn_t)(const void *, const void *); +#endif + +void taosSort(void* arr, int64_t sz, int64_t width, __compar_fn_t compar); + #ifdef __cplusplus } #endif diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 7b142e3053..0ec63e90af 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -892,7 +892,7 @@ int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo) { int64_t p0 = taosGetTimestampUs(); __compar_fn_t fn = getKeyComparFunc(pColInfoData->info.type, pOrder->order); - qsort(pColInfoData->pData, pDataBlock->info.rows, pColInfoData->info.bytes, fn); + taosSort(pColInfoData->pData, pDataBlock->info.rows, pColInfoData->info.bytes, fn); int64_t p1 = taosGetTimestampUs(); uDebug("blockDataSort easy cost:%" PRId64 ", rows:%d\n", p1 - p0, pDataBlock->info.rows); diff --git a/source/common/src/tdataformat.c b/source/common/src/tdataformat.c index 7c1b31b6e4..83ae442ae7 100644 --- a/source/common/src/tdataformat.c +++ b/source/common/src/tdataformat.c @@ -931,9 +931,9 @@ int32_t tTagNew(SArray *pArray, int32_t version, int8_t isJson, STag **ppTag) { // sort if (isJson) { - qsort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn); + taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValJsonCmprFn); } else { - qsort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn); + taosSort(pArray->pData, nTag, sizeof(STagVal), tTagValCmprFn); } // get size diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 2561516f6a..415df595e9 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -118,7 +118,7 @@ void initGroupedResultInfo(SGroupResInfo* pGroupResInfo, SHashObj* pHashmap, int if (order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC) { __compar_fn_t fn = (order == TSDB_ORDER_ASC) ? resultrowComparAsc : resultrowComparDesc; - qsort(pGroupResInfo->pRows->pData, taosArrayGetSize(pGroupResInfo->pRows), POINTER_BYTES, fn); + taosSort(pGroupResInfo->pRows->pData, taosArrayGetSize(pGroupResInfo->pRows), POINTER_BYTES, fn); } pGroupResInfo->index = 0; diff --git a/source/libs/function/src/taggfunction.c b/source/libs/function/src/taggfunction.c index 47ae07f823..c8998b9d94 100644 --- a/source/libs/function/src/taggfunction.c +++ b/source/libs/function/src/taggfunction.c @@ -1887,10 +1887,10 @@ static void top_bottom_func_finalizer(SqlFunctionCtx *pCtx) { // user specify the order of output by sort the result according to timestamp if (pCtx->param[1].param.i == PRIMARYKEY_TIMESTAMP_COL_ID) { __compar_fn_t comparator = (pCtx->param[2].param.i == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn; - qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); + taosSort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); } else /*if (pCtx->param[1].param.i > PRIMARYKEY_TIMESTAMP_COL_ID)*/ { __compar_fn_t comparator = (pCtx->param[2].param.i == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn; - qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); + taosSort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); } GET_TRUE_DATA_TYPE(); diff --git a/source/libs/function/src/tpercentile.c b/source/libs/function/src/tpercentile.c index b40dd8b78d..057d2bc7dc 100644 --- a/source/libs/function/src/tpercentile.c +++ b/source/libs/function/src/tpercentile.c @@ -44,7 +44,7 @@ static SFilePage *loadDataFromFilePage(tMemBucket *pMemBucket, int32_t slotIdx) offset += (int32_t)(pg->num * pMemBucket->bytes); } - qsort(buffer->data, pMemBucket->pSlots[slotIdx].info.size, pMemBucket->bytes, pMemBucket->comparFn); + taosSort(buffer->data, pMemBucket->pSlots[slotIdx].info.size, pMemBucket->bytes, pMemBucket->comparFn); return buffer; } diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index b97f1df38b..a76640d0b5 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -790,11 +790,11 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo* pColIdx[i].schemaColIdx = pColList->boundColumns[i]; pColIdx[i].boundIdx = i; } - qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar); + taosSort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar); for (col_id_t i = 0; i < pColList->numOfBound; ++i) { pColIdx[i].finalIdx = i; } - qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar); + taosSort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar); } if (pColList->numOfCols > pColList->numOfBound) { @@ -2232,11 +2232,11 @@ static int32_t smlBoundColumnData(SArray* cols, SParsedDataColInfo* pColList, SS pColIdx[i].schemaColIdx = pColList->boundColumns[i]; pColIdx[i].boundIdx = i; } - qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar); + taosSort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), schemaIdxCompar); for (col_id_t i = 0; i < pColList->numOfBound; ++i) { pColIdx[i].finalIdx = i; } - qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar); + taosSort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar); } if (pColList->numOfCols > pColList->numOfBound) { diff --git a/source/libs/parser/src/parInsertData.c b/source/libs/parser/src/parInsertData.c index 56301c072c..84bcef7185 100644 --- a/source/libs/parser/src/parInsertData.c +++ b/source/libs/parser/src/parInsertData.c @@ -295,7 +295,7 @@ void sortRemoveDataBlockDupRowsRaw(STableDataBlocks* dataBuf) { char* pBlockData = pBlocks->data; // todo. qsort is unstable, if timestamp is same, should get the last one - qsort(pBlockData, pBlocks->numOfRows, dataBuf->rowSize, rowDataCompar); + taosSort(pBlockData, pBlocks->numOfRows, dataBuf->rowSize, rowDataCompar); int32_t i = 0; int32_t j = 1; @@ -365,7 +365,7 @@ int sortRemoveDataBlockDupRows(STableDataBlocks* dataBuf, SBlockKeyInfo* pBlkKey pBlkKeyTuple = pBlkKeyInfo->pKeyTuple; // todo. qsort is unstable, if timestamp is same, should get the last one - qsort(pBlkKeyTuple, nRows, sizeof(SBlockKeyTuple), rowDataComparStable); + taosSort(pBlkKeyTuple, nRows, sizeof(SBlockKeyTuple), rowDataComparStable); pBlkKeyTuple = pBlkKeyInfo->pKeyTuple; int32_t i = 0; diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index b8bcae161b..9897acfe1a 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -2059,7 +2059,7 @@ int32_t filterMergeGroupUnits(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t } if (colIdxi > 1) { - qsort(colIdx, colIdxi, sizeof(uint32_t), getComparFunc(TSDB_DATA_TYPE_USMALLINT, 0)); + taosSort(colIdx, colIdxi, sizeof(uint32_t), getComparFunc(TSDB_DATA_TYPE_USMALLINT, 0)); } for (uint32_t l = 0; l < colIdxi; ++l) { @@ -2294,7 +2294,7 @@ int32_t filterMergeGroups(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t *gR return TSDB_CODE_SUCCESS; } - qsort(gRes, *gResNum, POINTER_BYTES, filterCompareGroupCtx); + taosSort(gRes, *gResNum, POINTER_BYTES, filterCompareGroupCtx); int32_t pEnd = 0, cStart = 0, cEnd = 0; uint32_t pColNum = 0, cColNum = 0; diff --git a/source/os/src/osMath.c b/source/os/src/osMath.c new file mode 100644 index 0000000000..98cd63a831 --- /dev/null +++ b/source/os/src/osMath.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#define ALLOW_FORBID_FUNC +#define _DEFAULT_SOURCE +#include "os.h" + +#ifdef WINDOWS +void swapStr(char* j, char* J, int width) { + int i; + char tmp; + for (i = 0; i < width; i++) { + tmp = *j; + *j = *J; + *J = tmp; + j++; + J++; + } +} +#endif + +void taosSort(void* arr, int64_t sz, int64_t width, __compar_fn_t compar) { +#ifdef WINDOWS + int64_t i, j; + for (i = 0; i < sz - 1; i++) { + for (j = 0; j < sz - 1 - i; j++) { + if (compar((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0.00) { + swapStr((char*)arr + j * width, (char*)arr + (j + 1) * width, width); + } + } + } +#else + qsort(arr, sz, width, compar); +#endif +} diff --git a/source/util/src/tarray.c b/source/util/src/tarray.c index ec90e5a9b9..23e79da948 100644 --- a/source/util/src/tarray.c +++ b/source/util/src/tarray.c @@ -373,7 +373,7 @@ void taosArraySort(SArray* pArray, __compar_fn_t compar) { assert(pArray != NULL); assert(compar != NULL); - qsort(pArray->pData, pArray->size, pArray->elemSize, compar); + taosSort(pArray->pData, pArray->size, pArray->elemSize, compar); } void* taosArraySearch(const SArray* pArray, const void* key, __compar_fn_t comparFn, int32_t flags) { @@ -390,7 +390,7 @@ int32_t taosArraySearchIdx(const SArray* pArray, const void* key, __compar_fn_t void taosArraySortString(SArray* pArray, __compar_fn_t comparFn) { assert(pArray != NULL); - qsort(pArray->pData, pArray->size, pArray->elemSize, comparFn); + taosSort(pArray->pData, pArray->size, pArray->elemSize, comparFn); } char* taosArraySearchString(const SArray* pArray, const char* key, __compar_fn_t comparFn, int32_t flags) { diff --git a/source/util/src/tdigest.c b/source/util/src/tdigest.c index 56b113fd8f..a722cfeee2 100644 --- a/source/util/src/tdigest.c +++ b/source/util/src/tdigest.c @@ -124,7 +124,7 @@ void tdigestCompress(TDigest *t) { t->num_buffered_pts = 0; t->total_weight += unmerged_weight; - qsort(unmerged_centroids, num_unmerged, sizeof(SCentroid), cmpCentroid); + taosSort(unmerged_centroids, num_unmerged, sizeof(SCentroid), cmpCentroid); memset(&args, 0, sizeof(SMergeArgs)); args.centroids = (SCentroid*)taosMemoryMalloc((size_t)(sizeof(SCentroid) * t->size)); memset(args.centroids, 0, (size_t)(sizeof(SCentroid) * t->size)); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 3ab307dc3f..58de4970a0 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -614,7 +614,7 @@ static int32_t taosCompareTaosError(const void* a, const void* b) { static TdThreadOnce tsErrorInit = PTHREAD_ONCE_INIT; static void tsSortError(void) { - qsort(errors, sizeof(errors) / sizeof(errors[0]), sizeof(errors[0]), taosCompareTaosError); + taosSort(errors, sizeof(errors) / sizeof(errors[0]), sizeof(errors[0]), taosCompareTaosError); } const char* tstrerror(int32_t err) {