From 9f5cf450dea680174a01bc879b053f744d635d94 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 10 Nov 2022 15:37:18 +0800 Subject: [PATCH 01/66] refactor: do some internal refactor. --- cmake/cmake.define | 2 +- include/common/tcommon.h | 6 +- include/common/tmsg.h | 32 +- source/dnode/vnode/inc/vnode.h | 2 +- source/dnode/vnode/src/meta/metaQuery.c | 4 +- source/dnode/vnode/src/tsdb/tsdbRead.c | 2 +- source/libs/executor/src/executil.c | 4 +- source/libs/function/CMakeLists.txt | 3 +- source/libs/function/inc/builtinsimpl.h | 14 +- source/libs/function/src/builtinsimpl.c | 788 +++++++++--------- .../libs/function/src/detail/tavgfunction.c | 482 +++++++++++ 11 files changed, 894 insertions(+), 445 deletions(-) create mode 100644 source/libs/function/src/detail/tavgfunction.c diff --git a/cmake/cmake.define b/cmake/cmake.define index 3f152f1f09..c7ad766a91 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -125,7 +125,7 @@ ELSE () MESSAGE("System processor ID: ${CMAKE_SYSTEM_PROCESSOR}") IF (TD_INTEL_64 OR TD_INTEL_32) - ADD_DEFINITIONS("-msse4.2") + ADD_DEFINITIONS("-msse4.2 -mavx") IF("${FMA_SUPPORT}" MATCHES "true") MESSAGE(STATUS "turn fma function support on") ADD_DEFINITIONS("-mfma") diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 674bdcf171..9c1f2063a7 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -225,13 +225,13 @@ typedef struct SVarColAttr { // pBlockAgg->numOfNull == info.rows, all data are null // pBlockAgg->numOfNull == 0, no data are null. typedef struct SColumnInfoData { - char* pData; // the corresponding block data in memory + char* pData; // the corresponding block data in memory union { char* nullbitmap; // bitmap, one bit for each item in the list SVarColAttr varmeta; }; - SColumnInfo info; // column info - bool hasNull; // if current column data has null value. + SColumnInfo info; // column info + bool hasNull; // if current column data has null value. } SColumnInfoData; typedef struct SQueryTableDataCond { diff --git a/include/common/tmsg.h b/include/common/tmsg.h index db7d0640f6..b6f4a36ae5 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -643,34 +643,6 @@ int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pR int32_t tDeserializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp); void tFreeSGetUserAuthRsp(SGetUserAuthRsp* pRsp); -typedef struct { - int16_t lowerRelOptr; - int16_t upperRelOptr; - int16_t filterstr; // denote if current column is char(binary/nchar) - - union { - struct { - int64_t lowerBndi; - int64_t upperBndi; - }; - struct { - double lowerBndd; - double upperBndd; - }; - struct { - int64_t pz; - int64_t len; - }; - }; -} SColumnFilterInfo; - -typedef struct { - int16_t numOfFilters; - union { - int64_t placeholder; - SColumnFilterInfo* filterInfo; - }; -} SColumnFilterList; /* * for client side struct, only column id, type, bytes are necessary * But for data in vnode side, we need all the following information. @@ -681,10 +653,10 @@ typedef struct { int16_t slotId; }; - int8_t type; - int32_t bytes; uint8_t precision; uint8_t scale; + int32_t bytes; + int8_t type; } SColumnInfo; typedef struct STimeWindow { diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 370103c222..0b58959822 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -105,7 +105,7 @@ int32_t metaGetTableTagsByUids(SMeta *pMeta, int64_t suid, SArray *uidList, int32_t metaReadNext(SMetaReader *pReader); const void *metaGetTableTagVal(void *tag, int16_t type, STagVal *tagVal); int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName); -int metaGetTableUidByName(void *meta, char *tbName, int64_t *uid); +int metaGetTableUidByName(void *meta, char *tbName, uint64_t *uid); int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType); bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid); diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 4aabd39800..32dd427d09 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -211,7 +211,7 @@ int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName) { return 0; } -int metaGetTableUidByName(void *meta, char *tbName, int64_t *uid) { +int metaGetTableUidByName(void *meta, char *tbName, uint64_t *uid) { int code = 0; SMetaReader mr = {0}; metaReaderInit(&mr, (SMeta *)meta, 0); @@ -1127,7 +1127,7 @@ int32_t metaFilterTableName(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) { if (valid < 0) break; char *pTableKey = (char *)pEntryKey; - int32_t cmp = (*param->filterFunc)(pTableKey, pName, pCursor->type); + cmp = (*param->filterFunc)(pTableKey, pName, pCursor->type); if (cmp == 0) { tb_uid_t tuid = *(tb_uid_t *)pEntryVal; taosArrayPush(pUids, &tuid); diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index c157faecb1..6ea270e5f4 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -535,7 +535,7 @@ static SSDataBlock* createResBlock(SQueryTableDataCond* pCond, int32_t capacity) } for (int32_t i = 0; i < pCond->numOfCols; ++i) { - SColumnInfoData colInfo = {0, {0}}; + SColumnInfoData colInfo = {0}; colInfo.info = pCond->colList[i]; blockDataAppendColInfo(pResBlock, &colInfo); } diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index d1046ff02c..f0db51dc9d 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -421,7 +421,7 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, int64_t suid, SArray* } for (int32_t i = 0; i < taosArrayGetSize(ctx.cInfoList); ++i) { - SColumnInfoData colInfo = {0, {0}}; + SColumnInfoData colInfo = {0}; colInfo.info = *(SColumnInfo*)taosArrayGet(ctx.cInfoList, i); blockDataAppendColInfo(pResBlock, &colInfo); } @@ -582,7 +582,7 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis } for (int32_t i = 0; i < taosArrayGetSize(ctx.cInfoList); ++i) { - SColumnInfoData colInfo = {0, {0}}; + SColumnInfoData colInfo = {0}; colInfo.info = *(SColumnInfo*)taosArrayGet(ctx.cInfoList, i); blockDataAppendColInfo(pResBlock, &colInfo); } diff --git a/source/libs/function/CMakeLists.txt b/source/libs/function/CMakeLists.txt index fa241dc6ef..9d11d7b376 100644 --- a/source/libs/function/CMakeLists.txt +++ b/source/libs/function/CMakeLists.txt @@ -1,6 +1,7 @@ aux_source_directory(src FUNCTION_SRC) +aux_source_directory(src/detail FUNCTION_SRC_DETAIL) list(REMOVE_ITEM FUNCTION_SRC src/udfd.c) -add_library(function STATIC ${FUNCTION_SRC}) +add_library(function STATIC ${FUNCTION_SRC} ${FUNCTION_SRC_DETAIL}) target_include_directories( function PUBLIC diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h index 89e9673b06..c0b1f62fda 100644 --- a/source/libs/function/inc/builtinsimpl.h +++ b/source/libs/function/inc/builtinsimpl.h @@ -23,6 +23,15 @@ extern "C" { #include "function.h" #include "functionMgt.h" +typedef struct SSumRes { + union { + int64_t isum; + uint64_t usum; + double dsum; + }; + int16_t type; +} SSumRes; + bool functionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo); int32_t functionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); int32_t functionFinalizeWithResultBuf(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, char* finalResult); @@ -119,15 +128,10 @@ EFuncDataRequired lastDynDataReq(void* pRes, STimeWindow* pTimeWindow); int32_t lastRowFunction(SqlFunctionCtx* pCtx); bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv); -bool getTopBotMergeFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv); bool topBotFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo); int32_t topFunction(SqlFunctionCtx* pCtx); -int32_t topFunctionMerge(SqlFunctionCtx* pCtx); int32_t bottomFunction(SqlFunctionCtx* pCtx); -int32_t bottomFunctionMerge(SqlFunctionCtx* pCtx); int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); -int32_t topBotPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); -int32_t topBotMergeFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); int32_t topCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); int32_t bottomCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); int32_t getTopBotInfoSize(int64_t numOfItems); diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 079e553b07..fc9c62c68f 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -41,21 +41,12 @@ #define HLL_BUCKET_MASK (HLL_BUCKETS - 1) #define HLL_ALPHA_INF 0.721347520444481703680 // constant for 0.5/ln(2) -typedef struct SSumRes { - union { - int64_t isum; - uint64_t usum; - double dsum; - }; - int16_t type; -} SSumRes; - -typedef struct SAvgRes { - double result; - SSumRes sum; - int64_t count; - int16_t type; // store the original input type, used in merge function -} SAvgRes; +//typedef struct SAvgRes { +// double result; +// SSumRes sum; +// int64_t count; +// int16_t type; // store the original input type, used in merge function +//} SAvgRes; typedef struct SMinmaxResInfo { bool assign; // assign the first value or not @@ -362,19 +353,19 @@ typedef struct SGroupKeyInfo { } \ } while (0) -#define LIST_AVG_N(sumT, T) \ - do { \ - T* plist = (T*)pCol->pData; \ - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { \ - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { \ - continue; \ - } \ - \ - numOfElem += 1; \ - pAvgRes->count -= 1; \ - sumT -= plist[i]; \ - } \ - } while (0) +//#define LIST_AVG_N(sumT, T) \ +// do { \ +// T* plist = (T*)pCol->pData; \ +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { \ +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { \ +// continue; \ +// } \ +// \ +// numOfElem += 1; \ +// pAvgRes->count -= 1; \ +// sumT -= plist[i]; \ +// } \ +// } while (0) #define LIST_STDDEV_SUB_N(sumT, T) \ do { \ @@ -741,374 +732,374 @@ bool getSumFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { return true; } -int32_t getAvgInfoSize() { return (int32_t)sizeof(SAvgRes); } - -bool getAvgFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { - pEnv->calcMemSize = sizeof(SAvgRes); - return true; -} - -bool avgFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) { - if (!functionSetup(pCtx, pResultInfo)) { - return false; - } - - SAvgRes* pRes = GET_ROWCELL_INTERBUF(pResultInfo); - memset(pRes, 0, sizeof(SAvgRes)); - return true; -} - -int32_t avgFunction(SqlFunctionCtx* pCtx) { - int32_t numOfElem = 0; - - SInputColumnInfoData* pInput = &pCtx->input; - SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0]; - int32_t type = pInput->pData[0]->info.type; - - SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - pAvgRes->type = type; - - // computing based on the true data block - SColumnInfoData* pCol = pInput->pData[0]; - - int32_t start = pInput->startRowIndex; - int32_t numOfRows = pInput->numOfRows; - - if (IS_NULL_TYPE(type)) { - numOfElem = 0; - goto _avg_over; - } - - if (pInput->colDataAggIsSet) { - numOfElem = numOfRows - pAgg->numOfNull; - ASSERT(numOfElem >= 0); - - pAvgRes->count += numOfElem; - if (IS_SIGNED_NUMERIC_TYPE(type)) { - pAvgRes->sum.isum += pAgg->sum; - } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - pAvgRes->sum.usum += pAgg->sum; - } else if (IS_FLOAT_TYPE(type)) { - pAvgRes->sum.dsum += GET_DOUBLE_VAL((const char*)&(pAgg->sum)); - } - } else { // computing based on the true data block - switch (type) { - case TSDB_DATA_TYPE_TINYINT: { - int8_t* plist = (int8_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.isum += plist[i]; - } - - break; - } - - case TSDB_DATA_TYPE_SMALLINT: { - int16_t* plist = (int16_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.isum += plist[i]; - } - break; - } - - case TSDB_DATA_TYPE_INT: { - int32_t* plist = (int32_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.isum += plist[i]; - } - - break; - } - - case TSDB_DATA_TYPE_BIGINT: { - int64_t* plist = (int64_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.isum += plist[i]; - } - break; - } - - case TSDB_DATA_TYPE_UTINYINT: { - uint8_t* plist = (uint8_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.usum += plist[i]; - } - - break; - } - - case TSDB_DATA_TYPE_USMALLINT: { - uint16_t* plist = (uint16_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.usum += plist[i]; - } - break; - } - - case TSDB_DATA_TYPE_UINT: { - uint32_t* plist = (uint32_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.usum += plist[i]; - } - - break; - } - - case TSDB_DATA_TYPE_UBIGINT: { - uint64_t* plist = (uint64_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.usum += plist[i]; - } - break; - } - - case TSDB_DATA_TYPE_FLOAT: { - float* plist = (float*)pCol->pData; -// float val = 0; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.dsum += plist[i]; - } -// pAvgRes->sum.dsum = val; - break; - } - - case TSDB_DATA_TYPE_DOUBLE: { - double* plist = (double*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.dsum += plist[i]; - } - break; - } - - default: - break; - } - } - -_avg_over: - // data in the check operation are all null, not output - SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1); - return TSDB_CODE_SUCCESS; -} - -static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) { - pOutput->type = pInput->type; - if (IS_SIGNED_NUMERIC_TYPE(pOutput->type)) { - pOutput->sum.isum += pInput->sum.isum; - } else if (IS_UNSIGNED_NUMERIC_TYPE(pOutput->type)) { - pOutput->sum.usum += pInput->sum.usum; - } else { - pOutput->sum.dsum += pInput->sum.dsum; - } - - pOutput->count += pInput->count; - - return; -} - -int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) { - SInputColumnInfoData* pInput = &pCtx->input; - SColumnInfoData* pCol = pInput->pData[0]; - ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY); - - SAvgRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - - int32_t start = pInput->startRowIndex; - - for (int32_t i = start; i < start + pInput->numOfRows; ++i) { - char* data = colDataGetData(pCol, i); - SAvgRes* pInputInfo = (SAvgRes*)varDataVal(data); - avgTransferInfo(pInputInfo, pInfo); - } - - SET_VAL(GET_RES_INFO(pCtx), 1, 1); - - return TSDB_CODE_SUCCESS; -} - -int32_t avgInvertFunction(SqlFunctionCtx* pCtx) { - int32_t numOfElem = 0; - - // Only the pre-computing information loaded and actual data does not loaded - SInputColumnInfoData* pInput = &pCtx->input; - int32_t type = pInput->pData[0]->info.type; - - SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - - // computing based on the true data block - SColumnInfoData* pCol = pInput->pData[0]; - - int32_t start = pInput->startRowIndex; - int32_t numOfRows = pInput->numOfRows; - - switch (type) { - case TSDB_DATA_TYPE_TINYINT: { - LIST_AVG_N(pAvgRes->sum.isum, int8_t); - break; - } - case TSDB_DATA_TYPE_SMALLINT: { - LIST_AVG_N(pAvgRes->sum.isum, int16_t); - break; - } - case TSDB_DATA_TYPE_INT: { - LIST_AVG_N(pAvgRes->sum.isum, int32_t); - break; - } - case TSDB_DATA_TYPE_BIGINT: { - LIST_AVG_N(pAvgRes->sum.isum, int64_t); - break; - } - case TSDB_DATA_TYPE_UTINYINT: { - LIST_AVG_N(pAvgRes->sum.usum, uint8_t); - break; - } - case TSDB_DATA_TYPE_USMALLINT: { - LIST_AVG_N(pAvgRes->sum.usum, uint16_t); - break; - } - case TSDB_DATA_TYPE_UINT: { - LIST_AVG_N(pAvgRes->sum.usum, uint32_t); - break; - } - case TSDB_DATA_TYPE_UBIGINT: { - LIST_AVG_N(pAvgRes->sum.usum, uint64_t); - break; - } - case TSDB_DATA_TYPE_FLOAT: { - LIST_AVG_N(pAvgRes->sum.dsum, float); - break; - } - case TSDB_DATA_TYPE_DOUBLE: { - LIST_AVG_N(pAvgRes->sum.dsum, double); - break; - } - default: - break; - } - - // data in the check operation are all null, not output - SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1); - return TSDB_CODE_SUCCESS; -} - -int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { - SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx); - SAvgRes* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo); - - SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx); - SAvgRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo); - int16_t type = pDBuf->type == TSDB_DATA_TYPE_NULL ? pSBuf->type : pDBuf->type; - - if (IS_SIGNED_NUMERIC_TYPE(type)) { - pDBuf->sum.isum += pSBuf->sum.isum; - } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - pDBuf->sum.usum += pSBuf->sum.usum; - } else { - pDBuf->sum.dsum += pSBuf->sum.dsum; - } - pDBuf->count += pSBuf->count; - - return TSDB_CODE_SUCCESS; -} - -int32_t avgFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { - SInputColumnInfoData* pInput = &pCtx->input; - - SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - int32_t type = pAvgRes->type; - - if (IS_SIGNED_NUMERIC_TYPE(type)) { - pAvgRes->result = pAvgRes->sum.isum / ((double)pAvgRes->count); - } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - pAvgRes->result = pAvgRes->sum.usum / ((double)pAvgRes->count); - } else { - pAvgRes->result = pAvgRes->sum.dsum / ((double)pAvgRes->count); - } - - // check for overflow - if (isinf(pAvgRes->result) || isnan(pAvgRes->result)) { - GET_RES_INFO(pCtx)->numOfRes = 0; - } - - return functionFinalize(pCtx, pBlock); -} - -int32_t avgPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { - SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); - SAvgRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - int32_t resultBytes = getAvgInfoSize(); - char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char)); - - memcpy(varDataVal(res), pInfo, resultBytes); - varDataSetLen(res, resultBytes); - - int32_t slotId = pCtx->pExpr->base.resSchema.slotId; - SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); - - colDataAppend(pCol, pBlock->info.rows, res, false); - - taosMemoryFree(res); - return pResInfo->numOfRes; -} +//int32_t getAvgInfoSize() { return (int32_t)sizeof(SAvgRes); } +// +//bool getAvgFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { +// pEnv->calcMemSize = sizeof(SAvgRes); +// return true; +//} +// +//bool avgFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) { +// if (!functionSetup(pCtx, pResultInfo)) { +// return false; +// } +// +// SAvgRes* pRes = GET_ROWCELL_INTERBUF(pResultInfo); +// memset(pRes, 0, sizeof(SAvgRes)); +// return true; +//} + +//int32_t avgFunction(SqlFunctionCtx* pCtx) { +// int32_t numOfElem = 0; +// +// SInputColumnInfoData* pInput = &pCtx->input; +// SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0]; +// int32_t type = pInput->pData[0]->info.type; +// +// SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); +// pAvgRes->type = type; +// +// // computing based on the true data block +// SColumnInfoData* pCol = pInput->pData[0]; +// +// int32_t start = pInput->startRowIndex; +// int32_t numOfRows = pInput->numOfRows; +// +// if (IS_NULL_TYPE(type)) { +// numOfElem = 0; +// goto _avg_over; +// } +// +// if (pInput->colDataAggIsSet) { +// numOfElem = numOfRows - pAgg->numOfNull; +// ASSERT(numOfElem >= 0); +// +// pAvgRes->count += numOfElem; +// if (IS_SIGNED_NUMERIC_TYPE(type)) { +// pAvgRes->sum.isum += pAgg->sum; +// } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { +// pAvgRes->sum.usum += pAgg->sum; +// } else if (IS_FLOAT_TYPE(type)) { +// pAvgRes->sum.dsum += GET_DOUBLE_VAL((const char*)&(pAgg->sum)); +// } +// } else { // computing based on the true data block +// switch (type) { +// case TSDB_DATA_TYPE_TINYINT: { +// int8_t* plist = (int8_t*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.isum += plist[i]; +// } +// +// break; +// } +// +// case TSDB_DATA_TYPE_SMALLINT: { +// int16_t* plist = (int16_t*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.isum += plist[i]; +// } +// break; +// } +// +// case TSDB_DATA_TYPE_INT: { +// int32_t* plist = (int32_t*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.isum += plist[i]; +// } +// +// break; +// } +// +// case TSDB_DATA_TYPE_BIGINT: { +// int64_t* plist = (int64_t*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.isum += plist[i]; +// } +// break; +// } +// +// case TSDB_DATA_TYPE_UTINYINT: { +// uint8_t* plist = (uint8_t*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.usum += plist[i]; +// } +// +// break; +// } +// +// case TSDB_DATA_TYPE_USMALLINT: { +// uint16_t* plist = (uint16_t*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.usum += plist[i]; +// } +// break; +// } +// +// case TSDB_DATA_TYPE_UINT: { +// uint32_t* plist = (uint32_t*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.usum += plist[i]; +// } +// +// break; +// } +// +// case TSDB_DATA_TYPE_UBIGINT: { +// uint64_t* plist = (uint64_t*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.usum += plist[i]; +// } +// break; +// } +// +// case TSDB_DATA_TYPE_FLOAT: { +// float* plist = (float*)pCol->pData; +//// float val = 0; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.dsum += plist[i]; +// } +//// pAvgRes->sum.dsum = val; +// break; +// } +// +// case TSDB_DATA_TYPE_DOUBLE: { +// double* plist = (double*)pCol->pData; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.dsum += plist[i]; +// } +// break; +// } +// +// default: +// break; +// } +// } +// +//_avg_over: +// // data in the check operation are all null, not output +// SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1); +// return TSDB_CODE_SUCCESS; +//} + +//static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) { +// pOutput->type = pInput->type; +// if (IS_SIGNED_NUMERIC_TYPE(pOutput->type)) { +// pOutput->sum.isum += pInput->sum.isum; +// } else if (IS_UNSIGNED_NUMERIC_TYPE(pOutput->type)) { +// pOutput->sum.usum += pInput->sum.usum; +// } else { +// pOutput->sum.dsum += pInput->sum.dsum; +// } +// +// pOutput->count += pInput->count; +// +// return; +//} +// +//int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) { +// SInputColumnInfoData* pInput = &pCtx->input; +// SColumnInfoData* pCol = pInput->pData[0]; +// ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY); +// +// SAvgRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); +// +// int32_t start = pInput->startRowIndex; +// +// for (int32_t i = start; i < start + pInput->numOfRows; ++i) { +// char* data = colDataGetData(pCol, i); +// SAvgRes* pInputInfo = (SAvgRes*)varDataVal(data); +// avgTransferInfo(pInputInfo, pInfo); +// } +// +// SET_VAL(GET_RES_INFO(pCtx), 1, 1); +// +// return TSDB_CODE_SUCCESS; +//} +// +//int32_t avgInvertFunction(SqlFunctionCtx* pCtx) { +// int32_t numOfElem = 0; +// +// // Only the pre-computing information loaded and actual data does not loaded +// SInputColumnInfoData* pInput = &pCtx->input; +// int32_t type = pInput->pData[0]->info.type; +// +// SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); +// +// // computing based on the true data block +// SColumnInfoData* pCol = pInput->pData[0]; +// +// int32_t start = pInput->startRowIndex; +// int32_t numOfRows = pInput->numOfRows; +// +// switch (type) { +// case TSDB_DATA_TYPE_TINYINT: { +// LIST_AVG_N(pAvgRes->sum.isum, int8_t); +// break; +// } +// case TSDB_DATA_TYPE_SMALLINT: { +// LIST_AVG_N(pAvgRes->sum.isum, int16_t); +// break; +// } +// case TSDB_DATA_TYPE_INT: { +// LIST_AVG_N(pAvgRes->sum.isum, int32_t); +// break; +// } +// case TSDB_DATA_TYPE_BIGINT: { +// LIST_AVG_N(pAvgRes->sum.isum, int64_t); +// break; +// } +// case TSDB_DATA_TYPE_UTINYINT: { +// LIST_AVG_N(pAvgRes->sum.usum, uint8_t); +// break; +// } +// case TSDB_DATA_TYPE_USMALLINT: { +// LIST_AVG_N(pAvgRes->sum.usum, uint16_t); +// break; +// } +// case TSDB_DATA_TYPE_UINT: { +// LIST_AVG_N(pAvgRes->sum.usum, uint32_t); +// break; +// } +// case TSDB_DATA_TYPE_UBIGINT: { +// LIST_AVG_N(pAvgRes->sum.usum, uint64_t); +// break; +// } +// case TSDB_DATA_TYPE_FLOAT: { +// LIST_AVG_N(pAvgRes->sum.dsum, float); +// break; +// } +// case TSDB_DATA_TYPE_DOUBLE: { +// LIST_AVG_N(pAvgRes->sum.dsum, double); +// break; +// } +// default: +// break; +// } +// +// // data in the check operation are all null, not output +// SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1); +// return TSDB_CODE_SUCCESS; +//} +// +//int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { +// SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx); +// SAvgRes* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo); +// +// SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx); +// SAvgRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo); +// int16_t type = pDBuf->type == TSDB_DATA_TYPE_NULL ? pSBuf->type : pDBuf->type; +// +// if (IS_SIGNED_NUMERIC_TYPE(type)) { +// pDBuf->sum.isum += pSBuf->sum.isum; +// } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { +// pDBuf->sum.usum += pSBuf->sum.usum; +// } else { +// pDBuf->sum.dsum += pSBuf->sum.dsum; +// } +// pDBuf->count += pSBuf->count; +// +// return TSDB_CODE_SUCCESS; +//} +// +//int32_t avgFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { +// SInputColumnInfoData* pInput = &pCtx->input; +// +// SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); +// int32_t type = pAvgRes->type; +// +// if (IS_SIGNED_NUMERIC_TYPE(type)) { +// pAvgRes->result = pAvgRes->sum.isum / ((double)pAvgRes->count); +// } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { +// pAvgRes->result = pAvgRes->sum.usum / ((double)pAvgRes->count); +// } else { +// pAvgRes->result = pAvgRes->sum.dsum / ((double)pAvgRes->count); +// } +// +// // check for overflow +// if (isinf(pAvgRes->result) || isnan(pAvgRes->result)) { +// GET_RES_INFO(pCtx)->numOfRes = 0; +// } +// +// return functionFinalize(pCtx, pBlock); +//} +// +//int32_t avgPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { +// SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); +// SAvgRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); +// int32_t resultBytes = getAvgInfoSize(); +// char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char)); +// +// memcpy(varDataVal(res), pInfo, resultBytes); +// varDataSetLen(res, resultBytes); +// +// int32_t slotId = pCtx->pExpr->base.resSchema.slotId; +// SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); +// +// colDataAppend(pCol, pBlock->info.rows, res, false); +// +// taosMemoryFree(res); +// return pResInfo->numOfRes; +//} EFuncDataRequired statisDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWindow) { return FUNC_DATA_REQUIRED_SMA_LOAD; @@ -3117,8 +3108,7 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) { int32_t round = pInput->numOfRows >> 2; int32_t reminder = pInput->numOfRows & 0x03; - int32_t tick = 0; - for (int32_t i = pInput->startRowIndex; tick < round; i += 4, tick += 1) { + for (int32_t i = pInput->startRowIndex, tick = 0; tick < round; i += 4, tick += 1) { int64_t cts = pts[i]; int32_t chosen = i; @@ -3153,7 +3143,7 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) { } } else { for (int32_t i = pInput->startRowIndex; i < pInput->startRowIndex + pInput->numOfRows; ++i) { - if (pInputCol->hasNull && colDataIsNull(pInputCol, pInput->totalRows, i, pColAgg)) { + if (colDataIsNull(pInputCol, pInput->totalRows, i, pColAgg)) { continue; } diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c new file mode 100644 index 0000000000..431e169346 --- /dev/null +++ b/source/libs/function/src/detail/tavgfunction.c @@ -0,0 +1,482 @@ +/* + * 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 . + */ + +#include +#include "builtinsimpl.h" +#include "function.h" +#include "tdatablock.h" +#include "tfunctionInt.h" +#include "tglobal.h" + +#define SET_VAL(_info, numOfElem, res) \ + do { \ + if ((numOfElem) <= 0) { \ + break; \ + } \ + (_info)->numOfRes = (res); \ + } while (0) + +#define LIST_AVG_N(sumT, T) \ + do { \ + T* plist = (T*)pCol->pData; \ + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { \ + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { \ + continue; \ + } \ + \ + numOfElem += 1; \ + pAvgRes->count -= 1; \ + sumT -= plist[i]; \ + } \ + } while (0) + +typedef struct SAvgRes { + double result; + SSumRes sum; + int64_t count; + int16_t type; // store the original input type, used in merge function +} SAvgRes; + +static int32_t handleFloatCols(const SColumnInfoData* pCol, const SInputColumnInfoData* pInput, SAvgRes* pRes) { + int32_t numOfElems = 0; + float* plist = (float*)pCol->pData; + + if (pCol->hasNull || pInput->numOfRows < 8) { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.dsum += plist[i]; + } + } else { // no null values exist + numOfElems = pInput->numOfRows; + pRes->count += pInput->numOfRows; + + // 1. an software version to speedup the process by using loop unwinding. + + + + // 2. if both the CPU and OS support SSE4.2, let's try the faster version by using SSE4.2 SIMD + + + + // 3. If both the CPU and OS support AVX, let's employ AVX instruction to speedup this loop + // 3.1 find the start position that are aligned to 32bytes address in memory + int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); + int32_t i = 0; + + int32_t bitWidth = 8; + + int32_t remain = (pInput->numOfRows - startElem) % bitWidth; + int32_t rounds = (pInput->numOfRows - startElem) / bitWidth; + const float* p = &plist[startElem]; + + __m256 loadVal; + __m256 sum = _mm256_setzero_ps(); + + for(; i < rounds; ++i) { + loadVal = _mm256_loadu_ps(p); + sum = _mm256_add_ps(sum, loadVal); + p += bitWidth; + } + + // let sum up the final results + const float* q = (const float*)∑ + pRes->sum.dsum += q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7]; + + // calculate the front and the reminder items in array list + for(int32_t j = 0; j < startElem; ++j) { + pRes->sum.dsum += plist[j]; + } + + startElem += rounds * bitWidth; + for(int32_t j = 0; j < remain; ++j) { + pRes->sum.dsum += plist[j + startElem]; + } + } + + return numOfElems; +} + +int32_t getAvgInfoSize() { return (int32_t)sizeof(SAvgRes); } + +bool getAvgFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { + pEnv->calcMemSize = sizeof(SAvgRes); + return true; +} + +bool avgFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) { + if (!functionSetup(pCtx, pResultInfo)) { + return false; + } + + SAvgRes* pRes = GET_ROWCELL_INTERBUF(pResultInfo); + memset(pRes, 0, sizeof(SAvgRes)); + return true; +} + +int32_t avgFunction(SqlFunctionCtx* pCtx) { + int32_t numOfElem = 0; + + SInputColumnInfoData* pInput = &pCtx->input; + SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0]; + int32_t type = pInput->pData[0]->info.type; + + SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + pAvgRes->type = type; + + // computing based on the true data block + SColumnInfoData* pCol = pInput->pData[0]; + + int32_t start = pInput->startRowIndex; + int32_t numOfRows = pInput->numOfRows; + + if (IS_NULL_TYPE(type)) { + numOfElem = 0; + goto _avg_over; + } + + if (pInput->colDataAggIsSet) { + numOfElem = numOfRows - pAgg->numOfNull; + ASSERT(numOfElem >= 0); + + pAvgRes->count += numOfElem; + if (IS_SIGNED_NUMERIC_TYPE(type)) { + pAvgRes->sum.isum += pAgg->sum; + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + pAvgRes->sum.usum += pAgg->sum; + } else if (IS_FLOAT_TYPE(type)) { + pAvgRes->sum.dsum += GET_DOUBLE_VAL((const char*)&(pAgg->sum)); + } + } else { // computing based on the true data block + switch (type) { + case TSDB_DATA_TYPE_TINYINT: { + int8_t* plist = (int8_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.isum += plist[i]; + } + + break; + } + + case TSDB_DATA_TYPE_SMALLINT: { + int16_t* plist = (int16_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.isum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_INT: { + int32_t* plist = (int32_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.isum += plist[i]; + } + + break; + } + + case TSDB_DATA_TYPE_BIGINT: { + int64_t* plist = (int64_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.isum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_UTINYINT: { + uint8_t* plist = (uint8_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.usum += plist[i]; + } + + break; + } + + case TSDB_DATA_TYPE_USMALLINT: { + uint16_t* plist = (uint16_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.usum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_UINT: { + uint32_t* plist = (uint32_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.usum += plist[i]; + } + + break; + } + + case TSDB_DATA_TYPE_UBIGINT: { + uint64_t* plist = (uint64_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.usum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_FLOAT: { + numOfElem = handleFloatCols(pCol, pInput, pAvgRes); +// float* plist = (float*)pCol->pData; +// // float val = 0; +// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { +// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// numOfElem += 1; +// pAvgRes->count += 1; +// pAvgRes->sum.dsum += plist[i]; +// } + // pAvgRes->sum.dsum = val; + break; + } + + case TSDB_DATA_TYPE_DOUBLE: { + double* plist = (double*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.dsum += plist[i]; + } + break; + } + + default: + break; + } + } + +_avg_over: + // data in the check operation are all null, not output + SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1); + return TSDB_CODE_SUCCESS; +} + +static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) { + pOutput->type = pInput->type; + if (IS_SIGNED_NUMERIC_TYPE(pOutput->type)) { + pOutput->sum.isum += pInput->sum.isum; + } else if (IS_UNSIGNED_NUMERIC_TYPE(pOutput->type)) { + pOutput->sum.usum += pInput->sum.usum; + } else { + pOutput->sum.dsum += pInput->sum.dsum; + } + + pOutput->count += pInput->count; +} + +int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) { + SInputColumnInfoData* pInput = &pCtx->input; + SColumnInfoData* pCol = pInput->pData[0]; + ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY); + + SAvgRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + + int32_t start = pInput->startRowIndex; + + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); + SAvgRes* pInputInfo = (SAvgRes*)varDataVal(data); + avgTransferInfo(pInputInfo, pInfo); + } + + SET_VAL(GET_RES_INFO(pCtx), 1, 1); + + return TSDB_CODE_SUCCESS; +} + +int32_t avgInvertFunction(SqlFunctionCtx* pCtx) { + int32_t numOfElem = 0; + + // Only the pre-computing information loaded and actual data does not loaded + SInputColumnInfoData* pInput = &pCtx->input; + int32_t type = pInput->pData[0]->info.type; + + SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + + // computing based on the true data block + SColumnInfoData* pCol = pInput->pData[0]; + + int32_t start = pInput->startRowIndex; + int32_t numOfRows = pInput->numOfRows; + + switch (type) { + case TSDB_DATA_TYPE_TINYINT: { + LIST_AVG_N(pAvgRes->sum.isum, int8_t); + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + LIST_AVG_N(pAvgRes->sum.isum, int16_t); + break; + } + case TSDB_DATA_TYPE_INT: { + LIST_AVG_N(pAvgRes->sum.isum, int32_t); + break; + } + case TSDB_DATA_TYPE_BIGINT: { + LIST_AVG_N(pAvgRes->sum.isum, int64_t); + break; + } + case TSDB_DATA_TYPE_UTINYINT: { + LIST_AVG_N(pAvgRes->sum.usum, uint8_t); + break; + } + case TSDB_DATA_TYPE_USMALLINT: { + LIST_AVG_N(pAvgRes->sum.usum, uint16_t); + break; + } + case TSDB_DATA_TYPE_UINT: { + LIST_AVG_N(pAvgRes->sum.usum, uint32_t); + break; + } + case TSDB_DATA_TYPE_UBIGINT: { + LIST_AVG_N(pAvgRes->sum.usum, uint64_t); + break; + } + case TSDB_DATA_TYPE_FLOAT: { + LIST_AVG_N(pAvgRes->sum.dsum, float); + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + LIST_AVG_N(pAvgRes->sum.dsum, double); + break; + } + default: + break; + } + + // data in the check operation are all null, not output + SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1); + return TSDB_CODE_SUCCESS; +} + +int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { + SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx); + SAvgRes* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo); + + SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx); + SAvgRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo); + int16_t type = pDBuf->type == TSDB_DATA_TYPE_NULL ? pSBuf->type : pDBuf->type; + + if (IS_SIGNED_NUMERIC_TYPE(type)) { + pDBuf->sum.isum += pSBuf->sum.isum; + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + pDBuf->sum.usum += pSBuf->sum.usum; + } else { + pDBuf->sum.dsum += pSBuf->sum.dsum; + } + pDBuf->count += pSBuf->count; + + return TSDB_CODE_SUCCESS; +} + +int32_t avgFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { + SInputColumnInfoData* pInput = &pCtx->input; + + SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + int32_t type = pAvgRes->type; + + if (IS_SIGNED_NUMERIC_TYPE(type)) { + pAvgRes->result = pAvgRes->sum.isum / ((double)pAvgRes->count); + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + pAvgRes->result = pAvgRes->sum.usum / ((double)pAvgRes->count); + } else { + pAvgRes->result = pAvgRes->sum.dsum / ((double)pAvgRes->count); + } + + // check for overflow + if (isinf(pAvgRes->result) || isnan(pAvgRes->result)) { + GET_RES_INFO(pCtx)->numOfRes = 0; + } + + return functionFinalize(pCtx, pBlock); +} + +int32_t avgPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { + SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); + SAvgRes* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + int32_t resultBytes = getAvgInfoSize(); + char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char)); + + memcpy(varDataVal(res), pInfo, resultBytes); + varDataSetLen(res, resultBytes); + + int32_t slotId = pCtx->pExpr->base.resSchema.slotId; + SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); + + colDataAppend(pCol, pBlock->info.rows, res, false); + + taosMemoryFree(res); + return pResInfo->numOfRes; +} \ No newline at end of file From ea83ae239e263310e9032e55567a79172d6c80c8 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 10 Nov 2022 18:58:10 +0800 Subject: [PATCH 02/66] refactor: do some internal refactor. --- cmake/cmake.define | 2 +- source/libs/function/inc/builtinsimpl.h | 15 + source/libs/function/src/builtinsimpl.c | 1064 ++++++++--------- .../libs/function/src/detail/tavgfunction.c | 25 +- source/libs/function/src/detail/tminmax.c | 820 +++++++++++++ 5 files changed, 1381 insertions(+), 545 deletions(-) create mode 100644 source/libs/function/src/detail/tminmax.c diff --git a/cmake/cmake.define b/cmake/cmake.define index c7ad766a91..dbd6f30b27 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -125,7 +125,7 @@ ELSE () MESSAGE("System processor ID: ${CMAKE_SYSTEM_PROCESSOR}") IF (TD_INTEL_64 OR TD_INTEL_32) - ADD_DEFINITIONS("-msse4.2 -mavx") + ADD_DEFINITIONS("-msse4.2 -mavx -mavx2") IF("${FMA_SUPPORT}" MATCHES "true") MESSAGE(STATUS "turn fma function support on") ADD_DEFINITIONS("-mfma") diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h index c0b1f62fda..2ec882d1de 100644 --- a/source/libs/function/inc/builtinsimpl.h +++ b/source/libs/function/inc/builtinsimpl.h @@ -32,6 +32,21 @@ typedef struct SSumRes { int16_t type; } SSumRes; +typedef struct SMinmaxResInfo { + bool assign; // assign the first value or not + int64_t v; + STuplePos tuplePos; + + STuplePos nullTuplePos; + bool nullTupleSaved; + int16_t type; +} SMinmaxResInfo; +int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc); + +STuplePos saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, const STupleKey* pKey); +int32_t updateTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos); +const char* loadTupleData(SqlFunctionCtx* pCtx, const STuplePos* pPos); + bool functionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo); int32_t functionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); int32_t functionFinalizeWithResultBuf(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, char* finalResult); diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index fc9c62c68f..26f9c3ad0b 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -48,15 +48,15 @@ // int16_t type; // store the original input type, used in merge function //} SAvgRes; -typedef struct SMinmaxResInfo { - bool assign; // assign the first value or not - int64_t v; - STuplePos tuplePos; - - STuplePos nullTuplePos; - bool nullTupleSaved; - int16_t type; -} SMinmaxResInfo; +//typedef struct SMinmaxResInfo { +// bool assign; // assign the first value or not +// int64_t v; +// STuplePos tuplePos; +// +// STuplePos nullTuplePos; +// bool nullTupleSaved; +// int16_t type; +//} SMinmaxResInfo; typedef struct STopBotResItem { SVariant v; @@ -1124,529 +1124,529 @@ bool getMinmaxFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { return true; } -static STuplePos saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, - const STupleKey* pKey); -static int32_t updateTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos); -static const char* loadTupleData(SqlFunctionCtx* pCtx, const STuplePos* pPos); +//static STuplePos saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, +// const STupleKey* pKey); +//static int32_t updateTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos); +//static const char* loadTupleData(SqlFunctionCtx* pCtx, const STuplePos* pPos); -static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, const char* tval) { - // the data is loaded, not only the block SMA value - for (int32_t i = start; i < num + start; ++i) { - char* p = colDataGetData(pCol, i); - if (memcmp((void*)tval, p, pCol->info.bytes) == 0) { - return i; - } - } +//static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, const char* tval) { +// // the data is loaded, not only the block SMA value +// for (int32_t i = start; i < num + start; ++i) { +// char* p = colDataGetData(pCol, i); +// if (memcmp((void*)tval, p, pCol->info.bytes) == 0) { +// return i; +// } +// } +// +// // if reach here means real data of block SMA is not set in pCtx->input. +// return -1; +//} - // if reach here means real data of block SMA is not set in pCtx->input. - return -1; -} - -int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { - int32_t numOfElems = 0; - - SInputColumnInfoData* pInput = &pCtx->input; - SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0]; - - SColumnInfoData* pCol = pInput->pData[0]; - int32_t type = pCol->info.type; - - SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); - SMinmaxResInfo* pBuf = GET_ROWCELL_INTERBUF(pResInfo); - pBuf->type = type; - - if (IS_NULL_TYPE(type)) { - numOfElems = 0; - goto _min_max_over; - } - - // data in current data block are qualified to the query - if (pInput->colDataAggIsSet) { - numOfElems = pInput->numOfRows - pAgg->numOfNull; - ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0); - if (numOfElems == 0) { - return numOfElems; - } - - void* tval = NULL; - int16_t index = 0; - - if (isMinFunc) { - tval = &pInput->pColumnDataAgg[0]->min; - } else { - tval = &pInput->pColumnDataAgg[0]->max; - } - - if (!pBuf->assign) { - pBuf->v = *(int64_t*)tval; - if (pCtx->subsidiaries.num > 0) { - index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); - if (index >= 0) { - pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); - } - } - } else { - if (IS_SIGNED_NUMERIC_TYPE(type)) { - int64_t prev = 0; - GET_TYPED_DATA(prev, int64_t, type, &pBuf->v); - - int64_t val = GET_INT64_VAL(tval); - if ((prev < val) ^ isMinFunc) { - *(int64_t*)&pBuf->v = val; - if (pCtx->subsidiaries.num > 0) { - index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); - if (index >= 0) { - pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); - } - } - } - } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - uint64_t prev = 0; - GET_TYPED_DATA(prev, uint64_t, type, &pBuf->v); - - uint64_t val = GET_UINT64_VAL(tval); - if ((prev < val) ^ isMinFunc) { - *(uint64_t*)&pBuf->v = val; - if (pCtx->subsidiaries.num > 0) { - index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); - if (index >= 0) { - pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); - } - } - } - } else if (type == TSDB_DATA_TYPE_DOUBLE) { - double prev = 0; - GET_TYPED_DATA(prev, double, type, &pBuf->v); - - double val = GET_DOUBLE_VAL(tval); - if ((prev < val) ^ isMinFunc) { - *(double*)&pBuf->v = val; - if (pCtx->subsidiaries.num > 0) { - index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); - if (index >= 0) { - pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); - } - } - } - } else if (type == TSDB_DATA_TYPE_FLOAT) { - float prev = 0; - GET_TYPED_DATA(prev, float, type, &pBuf->v); - - float val = GET_DOUBLE_VAL(tval); - if ((prev < val) ^ isMinFunc) { - *(float*)&pBuf->v = val; - } - - if (pCtx->subsidiaries.num > 0) { - index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); - if (index >= 0) { - pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); - } - } - } - } - - pBuf->assign = true; - return numOfElems; - } - - int32_t start = pInput->startRowIndex; - int32_t numOfRows = pInput->numOfRows; - - if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) { - if (type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_BOOL) { - int8_t* pData = (int8_t*)pCol->pData; - int8_t* val = (int8_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } else if (type == TSDB_DATA_TYPE_SMALLINT) { - int16_t* pData = (int16_t*)pCol->pData; - int16_t* val = (int16_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } else if (type == TSDB_DATA_TYPE_INT) { - int32_t* pData = (int32_t*)pCol->pData; - int32_t* val = (int32_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } else if (type == TSDB_DATA_TYPE_BIGINT) { - int64_t* pData = (int64_t*)pCol->pData; - int64_t* val = (int64_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } - } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - if (type == TSDB_DATA_TYPE_UTINYINT) { - uint8_t* pData = (uint8_t*)pCol->pData; - uint8_t* val = (uint8_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } else if (type == TSDB_DATA_TYPE_USMALLINT) { - uint16_t* pData = (uint16_t*)pCol->pData; - uint16_t* val = (uint16_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } else if (type == TSDB_DATA_TYPE_UINT) { - uint32_t* pData = (uint32_t*)pCol->pData; - uint32_t* val = (uint32_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } else if (type == TSDB_DATA_TYPE_UBIGINT) { - uint64_t* pData = (uint64_t*)pCol->pData; - uint64_t* val = (uint64_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } - } else if (type == TSDB_DATA_TYPE_DOUBLE) { - double* pData = (double*)pCol->pData; - double* val = (double*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } else if (type == TSDB_DATA_TYPE_FLOAT) { - float* pData = (float*)pCol->pData; - float* val = (float*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { -#if 0 - if ((*val) == pData[i]) { - continue; - } - - if ((*val < pData[i]) ^ isMinFunc) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } -#endif - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } - } - -_min_max_over: - if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { - pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); - pBuf->nullTupleSaved = true; - } - return numOfElems; -} +//int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { +// int32_t numOfElems = 0; +// +// SInputColumnInfoData* pInput = &pCtx->input; +// SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0]; +// +// SColumnInfoData* pCol = pInput->pData[0]; +// int32_t type = pCol->info.type; +// +// SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); +// SMinmaxResInfo* pBuf = GET_ROWCELL_INTERBUF(pResInfo); +// pBuf->type = type; +// +// if (IS_NULL_TYPE(type)) { +// numOfElems = 0; +// goto _min_max_over; +// } +// +// // data in current data block are qualified to the query +// if (pInput->colDataAggIsSet) { +// numOfElems = pInput->numOfRows - pAgg->numOfNull; +// ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0); +// if (numOfElems == 0) { +// return numOfElems; +// } +// +// void* tval = NULL; +// int16_t index = 0; +// +// if (isMinFunc) { +// tval = &pInput->pColumnDataAgg[0]->min; +// } else { +// tval = &pInput->pColumnDataAgg[0]->max; +// } +// +// if (!pBuf->assign) { +// pBuf->v = *(int64_t*)tval; +// if (pCtx->subsidiaries.num > 0) { +// index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); +// if (index >= 0) { +// pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); +// } +// } +// } else { +// if (IS_SIGNED_NUMERIC_TYPE(type)) { +// int64_t prev = 0; +// GET_TYPED_DATA(prev, int64_t, type, &pBuf->v); +// +// int64_t val = GET_INT64_VAL(tval); +// if ((prev < val) ^ isMinFunc) { +// *(int64_t*)&pBuf->v = val; +// if (pCtx->subsidiaries.num > 0) { +// index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); +// if (index >= 0) { +// pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); +// } +// } +// } +// } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { +// uint64_t prev = 0; +// GET_TYPED_DATA(prev, uint64_t, type, &pBuf->v); +// +// uint64_t val = GET_UINT64_VAL(tval); +// if ((prev < val) ^ isMinFunc) { +// *(uint64_t*)&pBuf->v = val; +// if (pCtx->subsidiaries.num > 0) { +// index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); +// if (index >= 0) { +// pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); +// } +// } +// } +// } else if (type == TSDB_DATA_TYPE_DOUBLE) { +// double prev = 0; +// GET_TYPED_DATA(prev, double, type, &pBuf->v); +// +// double val = GET_DOUBLE_VAL(tval); +// if ((prev < val) ^ isMinFunc) { +// *(double*)&pBuf->v = val; +// if (pCtx->subsidiaries.num > 0) { +// index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); +// if (index >= 0) { +// pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); +// } +// } +// } +// } else if (type == TSDB_DATA_TYPE_FLOAT) { +// float prev = 0; +// GET_TYPED_DATA(prev, float, type, &pBuf->v); +// +// float val = GET_DOUBLE_VAL(tval); +// if ((prev < val) ^ isMinFunc) { +// *(float*)&pBuf->v = val; +// } +// +// if (pCtx->subsidiaries.num > 0) { +// index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); +// if (index >= 0) { +// pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); +// } +// } +// } +// } +// +// pBuf->assign = true; +// return numOfElems; +// } +// +// int32_t start = pInput->startRowIndex; +// int32_t numOfRows = pInput->numOfRows; +// +// if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) { +// if (type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_BOOL) { +// int8_t* pData = (int8_t*)pCol->pData; +// int8_t* val = (int8_t*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } else if (type == TSDB_DATA_TYPE_SMALLINT) { +// int16_t* pData = (int16_t*)pCol->pData; +// int16_t* val = (int16_t*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } else if (type == TSDB_DATA_TYPE_INT) { +// int32_t* pData = (int32_t*)pCol->pData; +// int32_t* val = (int32_t*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } else if (type == TSDB_DATA_TYPE_BIGINT) { +// int64_t* pData = (int64_t*)pCol->pData; +// int64_t* val = (int64_t*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } +// } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { +// if (type == TSDB_DATA_TYPE_UTINYINT) { +// uint8_t* pData = (uint8_t*)pCol->pData; +// uint8_t* val = (uint8_t*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } else if (type == TSDB_DATA_TYPE_USMALLINT) { +// uint16_t* pData = (uint16_t*)pCol->pData; +// uint16_t* val = (uint16_t*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } else if (type == TSDB_DATA_TYPE_UINT) { +// uint32_t* pData = (uint32_t*)pCol->pData; +// uint32_t* val = (uint32_t*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } else if (type == TSDB_DATA_TYPE_UBIGINT) { +// uint64_t* pData = (uint64_t*)pCol->pData; +// uint64_t* val = (uint64_t*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } +// } else if (type == TSDB_DATA_TYPE_DOUBLE) { +// double* pData = (double*)pCol->pData; +// double* val = (double*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +// // ignore the equivalent data value +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } else if (type == TSDB_DATA_TYPE_FLOAT) { +// float* pData = (float*)pCol->pData; +// float* val = (float*)&pBuf->v; +// +// for (int32_t i = start; i < start + numOfRows; ++i) { +// if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { +// continue; +// } +// +// if (!pBuf->assign) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); +// } +// pBuf->assign = true; +// } else { +//#if 0 +// if ((*val) == pData[i]) { +// continue; +// } +// +// if ((*val < pData[i]) ^ isMinFunc) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +//#endif +// // NOTE: An faster version to avoid one additional comparison with FPU. +// if (isMinFunc) { // min +// if (*val > pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } else { // max +// if (*val < pData[i]) { +// *val = pData[i]; +// if (pCtx->subsidiaries.num > 0) { +// updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); +// } +// } +// } +// } +// +// numOfElems += 1; +// } +// } +// +//_min_max_over: +// if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { +// pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); +// pBuf->nullTupleSaved = true; +// } +// return numOfElems; +//} int32_t minFunction(SqlFunctionCtx* pCtx) { int32_t numOfElems = doMinMaxHelper(pCtx, 1); @@ -3844,7 +3844,7 @@ static int32_t doUpdateTupleData(SSerializeDataHandle* pHandle, const void* pBuf return TSDB_CODE_SUCCESS; } -static int32_t updateTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) { +int32_t updateTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) { char* buf = serializeTupleData(pSrcBlock, rowIndex, &pCtx->subsidiaries, pCtx->subsidiaries.buf); doUpdateTupleData(&pCtx->saveHandle, buf, pCtx->subsidiaries.rowLen, pPos); return TSDB_CODE_SUCCESS; @@ -3864,7 +3864,7 @@ static char* doLoadTupleData(SSerializeDataHandle* pHandle, const STuplePos* pPo } } -static const char* loadTupleData(SqlFunctionCtx* pCtx, const STuplePos* pPos) { +const char* loadTupleData(SqlFunctionCtx* pCtx, const STuplePos* pPos) { return doLoadTupleData(&pCtx->saveHandle, pPos); } diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 431e169346..50a69a4241 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -282,19 +282,20 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { } case TSDB_DATA_TYPE_FLOAT: { +#if 1 numOfElem = handleFloatCols(pCol, pInput, pAvgRes); -// float* plist = (float*)pCol->pData; -// // float val = 0; -// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { -// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { -// continue; -// } -// -// numOfElem += 1; -// pAvgRes->count += 1; -// pAvgRes->sum.dsum += plist[i]; -// } - // pAvgRes->sum.dsum = val; +#else + float* plist = (float*)pCol->pData; + for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { + if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElem += 1; + pAvgRes->count += 1; + pAvgRes->sum.dsum += plist[i]; + } +#endif break; } diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c new file mode 100644 index 0000000000..7814a41f4f --- /dev/null +++ b/source/libs/function/src/detail/tminmax.c @@ -0,0 +1,820 @@ +/* + * 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 . + */ + +#include +#include "builtinsimpl.h" +#include "function.h" +#include "tdatablock.h" +#include "tfunctionInt.h" +#include "tglobal.h" + +static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, + SMinmaxResInfo* pBuf, bool isMinFunc) { + int32_t* pData = (int32_t*)pCol->pData; + int32_t* val = (int32_t*)&pBuf->v; + + int32_t numOfElems = 0; + if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { + if (isMinFunc) { // min + for (int32_t i = start; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + + numOfElems += 1; + } + } else { // max function + for (int32_t i = start; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + + numOfElems += 1; + } + } + } else { // not has null value + // 1. software version + + + + + // 3. AVX2 version to speedup the loop + int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); + int32_t i = 0; + + int32_t bitWidth = 8; + int32_t v = 0; + + int32_t remain = (numOfRows - startElem) % bitWidth; + int32_t rounds = (numOfRows - startElem) / bitWidth; + const int32_t* p = &pData[startElem]; + + __m256i next; + __m256i initialVal = _mm256_loadu_si256((__m256i*)p); + p += bitWidth; + + if (!isMinFunc) { // max function + for (; i < rounds; ++i) { + next = _mm256_loadu_si256((__m256i*)p); + initialVal = _mm256_max_epi32(initialVal, next); + p += bitWidth; + } + + // let sum up the final results + const int32_t* q = (const int32_t*)&initialVal; + + v = TMAX(q[0], q[1]); + v = TMAX(v, q[2]); + v = TMAX(v, q[3]); + v = TMAX(v, q[4]); + v = TMAX(v, q[5]); + v = TMAX(v, q[6]); + v = TMAX(v, q[7]); + + // calculate the front and the reminder items in array list + startElem += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + startElem]) { + v = p[j + startElem]; + } + } + } else { // min function + for (; i < rounds; ++i) { + next = _mm256_loadu_si256((__m256i*)p); + initialVal = _mm256_min_epi32(initialVal, next); + p += bitWidth; + } + + // let sum up the final results + const int32_t* q = (const int32_t*)&initialVal; + + v = TMIN(q[0], q[1]); + v = TMIN(v, q[2]); + v = TMIN(v, q[3]); + v = TMIN(v, q[4]); + v = TMIN(v, q[5]); + v = TMIN(v, q[6]); + v = TMIN(v, q[7]); + + // calculate the front and the reminder items in array list + startElem += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + startElem]) { + v = p[j + startElem]; + } + } + } + + *val = v; + numOfElems = numOfRows; + } + + return numOfElems; +} + +static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, + SMinmaxResInfo* pBuf, bool isMinFunc) { + float* pData = (float*)pCol->pData; + double* val = (double*)&pBuf->v; + + int32_t numOfElems = 0; + if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { + if (isMinFunc) { // min + for (int32_t i = start; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + + numOfElems += 1; + } + } else { // max function + for (int32_t i = start; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + + numOfElems += 1; + } + } + } else { // not has null value + // 1. software version + + + + + // 3. AVX2 version to speedup the loop + int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); + int32_t i = 0; + + int32_t bitWidth = 8; + float v = 0; + + int32_t remain = (numOfRows - startElem) % bitWidth; + int32_t rounds = (numOfRows - startElem) / bitWidth; + const float* p = &pData[startElem]; + + __m256 next; + __m256 initialVal = _mm256_loadu_ps(p); + p += bitWidth; + + if (!isMinFunc) { // max function + for (; i < rounds; ++i) { + next = _mm256_loadu_ps(p); + initialVal = _mm256_max_ps(initialVal, next); + p += bitWidth; + } + + // let sum up the final results + const float* q = (const float*)&initialVal; + + v = TMAX(q[0], q[1]); + v = TMAX(v, q[2]); + v = TMAX(v, q[3]); + v = TMAX(v, q[4]); + v = TMAX(v, q[5]); + v = TMAX(v, q[6]); + v = TMAX(v, q[7]); + + // calculate the front and the reminder items in array list + startElem += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + startElem]) { + v = p[j + startElem]; + } + } + } else { // min function + for (; i < rounds; ++i) { + next = _mm256_loadu_ps(p); + initialVal = _mm256_min_ps(initialVal, next); + p += bitWidth; + } + + // let sum up the final results + const float* q = (const float*)&initialVal; + + v = TMIN(q[0], q[1]); + v = TMIN(v, q[2]); + v = TMIN(v, q[3]); + v = TMIN(v, q[4]); + v = TMIN(v, q[5]); + v = TMIN(v, q[6]); + v = TMIN(v, q[7]); + + // calculate the front and the reminder items in array list + startElem += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + startElem]) { + v = p[j + startElem]; + } + } + } + + *val = v; + numOfElems = numOfRows; + } + + return numOfElems; +} + +static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, const char* tval) { + // the data is loaded, not only the block SMA value + for (int32_t i = start; i < num + start; ++i) { + char* p = colDataGetData(pCol, i); + if (memcmp((void*)tval, p, pCol->info.bytes) == 0) { + return i; + } + } + + // if reach here means real data of block SMA is not set in pCtx->input. + return -1; +} + +int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { + int32_t numOfElems = 0; + + SInputColumnInfoData* pInput = &pCtx->input; + SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0]; + + SColumnInfoData* pCol = pInput->pData[0]; + int32_t type = pCol->info.type; + + SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); + SMinmaxResInfo* pBuf = GET_ROWCELL_INTERBUF(pResInfo); + pBuf->type = type; + + if (IS_NULL_TYPE(type)) { + numOfElems = 0; + goto _min_max_over; + } + + // data in current data block are qualified to the query + if (pInput->colDataAggIsSet) { + numOfElems = pInput->numOfRows - pAgg->numOfNull; + ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0); + if (numOfElems == 0) { + return numOfElems; + } + + void* tval = NULL; + int16_t index = 0; + + if (isMinFunc) { + tval = &pInput->pColumnDataAgg[0]->min; + } else { + tval = &pInput->pColumnDataAgg[0]->max; + } + + if (!pBuf->assign) { + pBuf->v = *(int64_t*)tval; + if (pCtx->subsidiaries.num > 0) { + index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); + if (index >= 0) { + pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); + } + } + } else { + if (IS_SIGNED_NUMERIC_TYPE(type)) { + int64_t prev = 0; + GET_TYPED_DATA(prev, int64_t, type, &pBuf->v); + + int64_t val = GET_INT64_VAL(tval); + if ((prev < val) ^ isMinFunc) { + *(int64_t*)&pBuf->v = val; + if (pCtx->subsidiaries.num > 0) { + index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); + if (index >= 0) { + pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); + } + } + } + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + uint64_t prev = 0; + GET_TYPED_DATA(prev, uint64_t, type, &pBuf->v); + + uint64_t val = GET_UINT64_VAL(tval); + if ((prev < val) ^ isMinFunc) { + *(uint64_t*)&pBuf->v = val; + if (pCtx->subsidiaries.num > 0) { + index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); + if (index >= 0) { + pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); + } + } + } + } else if (type == TSDB_DATA_TYPE_DOUBLE) { + double prev = 0; + GET_TYPED_DATA(prev, double, type, &pBuf->v); + + double val = GET_DOUBLE_VAL(tval); + if ((prev < val) ^ isMinFunc) { + *(double*)&pBuf->v = val; + if (pCtx->subsidiaries.num > 0) { + index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); + if (index >= 0) { + pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); + } + } + } + } else if (type == TSDB_DATA_TYPE_FLOAT) { + float prev = 0; + GET_TYPED_DATA(prev, float, type, &pBuf->v); + + float val = GET_DOUBLE_VAL(tval); + if ((prev < val) ^ isMinFunc) { + *(float*)&pBuf->v = val; + } + + if (pCtx->subsidiaries.num > 0) { + index = findRowIndex(pInput->startRowIndex, pInput->numOfRows, pCol, tval); + if (index >= 0) { + pBuf->tuplePos = saveTupleData(pCtx, index, pCtx->pSrcBlock, NULL); + } + } + } + } + + pBuf->assign = true; + return numOfElems; + } + + int32_t start = pInput->startRowIndex; + int32_t numOfRows = pInput->numOfRows; + + if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) { + if (type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_BOOL) { + int8_t* pData = (int8_t*)pCol->pData; + int8_t* val = (int8_t*)&pBuf->v; + + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } + } else if (type == TSDB_DATA_TYPE_SMALLINT) { + int16_t* pData = (int16_t*)pCol->pData; + int16_t* val = (int16_t*)&pBuf->v; + + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } + } else if (type == TSDB_DATA_TYPE_INT) { + int32_t* pData = (int32_t*)pCol->pData; + int32_t* val = (int32_t*)&pBuf->v; + + numOfElems = handleInt32Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); +#if 0 + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } +#endif + + } else if (type == TSDB_DATA_TYPE_BIGINT) { + int64_t* pData = (int64_t*)pCol->pData; + int64_t* val = (int64_t*)&pBuf->v; + + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } + } + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + if (type == TSDB_DATA_TYPE_UTINYINT) { + uint8_t* pData = (uint8_t*)pCol->pData; + uint8_t* val = (uint8_t*)&pBuf->v; + + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } + } else if (type == TSDB_DATA_TYPE_USMALLINT) { + uint16_t* pData = (uint16_t*)pCol->pData; + uint16_t* val = (uint16_t*)&pBuf->v; + + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } + } else if (type == TSDB_DATA_TYPE_UINT) { + uint32_t* pData = (uint32_t*)pCol->pData; + uint32_t* val = (uint32_t*)&pBuf->v; + + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } + } else if (type == TSDB_DATA_TYPE_UBIGINT) { + uint64_t* pData = (uint64_t*)pCol->pData; + uint64_t* val = (uint64_t*)&pBuf->v; + + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } + } + } else if (type == TSDB_DATA_TYPE_DOUBLE) { + double* pData = (double*)pCol->pData; + double* val = (double*)&pBuf->v; + + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } + } else if (type == TSDB_DATA_TYPE_FLOAT) { + float* pData = (float*)pCol->pData; + float* val = (float*)&pBuf->v; + + numOfElems = handleFloatCol(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); +#if 0 + for (int32_t i = start; i < start + numOfRows; ++i) { + if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (!pBuf->assign) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + } else { +#if 0 + if ((*val) == pData[i]) { + continue; + } + + if ((*val < pData[i]) ^ isMinFunc) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } +#endif + // NOTE: An faster version to avoid one additional comparison with FPU. + if (isMinFunc) { // min + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } else { // max + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + } + } + + numOfElems += 1; + } +#endif + + } + +_min_max_over: + if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { + pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); + pBuf->nullTupleSaved = true; + } + return numOfElems; +} \ No newline at end of file From b83f89572655c5c7229231146aeda060c31a5821 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 11 Nov 2022 14:16:13 +0800 Subject: [PATCH 03/66] refactor: do some internal refactor. --- cmake/cmake.define | 14 +- cmake/cmake.platform | 18 +- cmake/cmake.version | 8 +- include/os/os.h | 7 + include/os/osDef.h | 32 +- include/os/osEnv.h | 5 + include/os/osSysinfo.h | 1 + source/common/src/tglobal.c | 10 +- .../libs/function/src/detail/tavgfunction.c | 87 ++--- source/libs/function/src/detail/tminmax.c | 313 ++++++++++-------- source/os/src/osEnv.c | 8 +- source/os/src/osFile.c | 2 + source/os/src/osLocale.c | 5 +- source/os/src/osSysinfo.c | 71 +++- source/os/src/osTime.c | 5 +- source/util/src/tconfig.c | 8 +- source/util/src/tcrc32c.c | 1 - 17 files changed, 359 insertions(+), 236 deletions(-) diff --git a/cmake/cmake.define b/cmake/cmake.define index dbd6f30b27..3b6024efc8 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -123,14 +123,20 @@ ELSE () SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-literal-suffix -Werror=return-type -fPIC -gdwarf-2 -g3 -Wformat=2 -Wno-format-nonliteral -Wno-format-truncation -Wno-format-y2k") ENDIF () - MESSAGE("System processor ID: ${CMAKE_SYSTEM_PROCESSOR}") IF (TD_INTEL_64 OR TD_INTEL_32) - ADD_DEFINITIONS("-msse4.2 -mavx -mavx2") + ADD_DEFINITIONS("-msse4.2") IF("${FMA_SUPPORT}" MATCHES "true") - MESSAGE(STATUS "turn fma function support on") + MESSAGE(STATUS "fma function supported") ADD_DEFINITIONS("-mfma") ELSE () - MESSAGE(STATUS "turn fma function support off") + MESSAGE(STATUS "fma function NOT supported") + ENDIF() + + IF("${SIMD_SUPPORT}" MATCHES "true") + ADD_DEFINITIONS("-mavx -mavx2") + MESSAGE(STATUS "cpu simd instruction AVX/AVX2 supported") + ELSE() + MESSAGE(STATUS "cpu simd instruction AVX/AVX2 NOT supported") ENDIF() ENDIF () diff --git a/cmake/cmake.platform b/cmake/cmake.platform index 3e239d2e0c..c3680e0de4 100644 --- a/cmake/cmake.platform +++ b/cmake/cmake.platform @@ -1,20 +1,17 @@ cmake_minimum_required(VERSION 3.0) -MESSAGE("Current system is ${CMAKE_SYSTEM_NAME}") - # init SET(TD_LINUX FALSE) SET(TD_WINDOWS FALSE) SET(TD_DARWIN FALSE) -MESSAGE("Compiler ID: ${CMAKE_CXX_COMPILER_ID}") if(CMAKE_COMPILER_IS_GNUCXX MATCHES 1) set(CXX_COMPILER_IS_GNU TRUE) else() set(CXX_COMPILER_IS_GNU FALSE) endif() -MESSAGE("Current system name is ${CMAKE_SYSTEM_NAME}.") +MESSAGE("Current system: ${CMAKE_SYSTEM_NAME}") IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") @@ -26,6 +23,8 @@ IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS} -undefined dynamic_lookup") ENDIF () + MESSAGE("Current system processor: ${CMAKE_SYSTEM_PROCESSOR}") + IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux") SET(TD_LINUX TRUE) @@ -44,7 +43,6 @@ IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin SET(OSTYPE "macOS") ADD_DEFINITIONS("-DDARWIN -Wno-tautological-pointer-compare") - MESSAGE("Current system processor is ${CMAKE_SYSTEM_PROCESSOR}.") IF (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64") MESSAGE("Current system arch is arm64") SET(TD_DARWIN_64 TRUE) @@ -80,24 +78,22 @@ ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Windows") ENDIF() IF ("${CPUTYPE}" STREQUAL "") - MESSAGE(STATUS "The current platform " ${CMAKE_SYSTEM_PROCESSOR} " is detected") - IF (CMAKE_SYSTEM_PROCESSOR MATCHES "(amd64)|(AMD64)") - MESSAGE(STATUS "The current platform is amd64") + MESSAGE(STATUS "Current platform is amd64") SET(PLATFORM_ARCH_STR "amd64") SET(TD_INTEL_64 TRUE) ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)") - MESSAGE(STATUS "The current platform is x86") + MESSAGE(STATUS "Current platform is x86") SET(PLATFORM_ARCH_STR "i386") SET(TD_INTEL_32 TRUE) ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "armv7l") - MESSAGE(STATUS "The current platform is aarch32") + MESSAGE(STATUS "Current platform is aarch32") SET(PLATFORM_ARCH_STR "arm") SET(TD_ARM_32 TRUE) ADD_DEFINITIONS("-D_TD_ARM_") ADD_DEFINITIONS("-D_TD_ARM_32") ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(arm64)") - MESSAGE(STATUS "The current platform is aarch64") + MESSAGE(STATUS "Current platform is aarch64") SET(PLATFORM_ARCH_STR "arm64") SET(TD_ARM_64 TRUE) ADD_DEFINITIONS("-D_TD_ARM_") diff --git a/cmake/cmake.version b/cmake/cmake.version index 03598519ed..0447f284f1 100644 --- a/cmake/cmake.version +++ b/cmake/cmake.version @@ -26,7 +26,7 @@ ELSEIF (HAVE_GIT) SET(TD_VER_GIT "no git commit id") ENDIF () ELSE () - message(STATUS "no git cmd") + message(STATUS "no git found") SET(TD_VER_GIT "no git commit id") ENDIF () @@ -70,9 +70,9 @@ MESSAGE(STATUS "compatible: " ${TD_VER_COMPATIBLE}) MESSAGE(STATUS "commit id: " ${TD_VER_GIT}) MESSAGE(STATUS "build date: " ${TD_VER_DATE}) MESSAGE(STATUS "build type: " ${CMAKE_BUILD_TYPE}) -MESSAGE(STATUS "type: " ${TD_VER_VERTYPE}) -MESSAGE(STATUS "cpu: " ${TD_VER_CPUTYPE}) -MESSAGE(STATUS "os: " ${TD_VER_OSTYPE}) +MESSAGE(STATUS "type: " ${TD_VER_VERTYPE}) +MESSAGE(STATUS "cpu: " ${TD_VER_CPUTYPE}) +MESSAGE(STATUS "os: " ${TD_VER_OSTYPE}) MESSAGE(STATUS "============= compile version parameter information end ============= ") STRING(REPLACE "." "_" TD_LIB_VER_NUMBER ${TD_VER_NUMBER}) diff --git a/include/os/os.h b/include/os/os.h index e780611c41..0334cd4d95 100644 --- a/include/os/os.h +++ b/include/os/os.h @@ -81,6 +81,13 @@ extern "C" { #include #include #include +#include + +#if __AVX__ +#include +#elif __SSE4_2__ +#include +#endif #include "osThread.h" diff --git a/include/os/osDef.h b/include/os/osDef.h index 297d19e21a..0bf9c6184e 100644 --- a/include/os/osDef.h +++ b/include/os/osDef.h @@ -168,22 +168,22 @@ void syslog(int unused, const char *format, ...); } \ } while (0) -#define DEFAULT_DOUBLE_COMP(x, y) \ - do { \ - if (isnan(x) && isnan(y)) { \ - return 0; \ - } \ - if (isnan(x)) { \ - return -1; \ - } \ - if (isnan(y)) { \ - return 1; \ - } \ - if ((x) == (y)) { \ - return 0; \ - } else { \ - return (x) < (y) ? -1 : 1; \ - } \ +#define DEFAULT_DOUBLE_COMP(x, y) \ + do { \ + if (isnan(x) && isnan(y)) { \ + return 0; \ + } \ + if (isnan(x)) { \ + return -1; \ + } \ + if (isnan(y)) { \ + return 1; \ + } \ + if (fabs((x) - (y)) <= DBL_EPSILON) { \ + return 0; \ + } else { \ + return (x) < (y) ? -1 : 1; \ + } \ } while (0) #define DEFAULT_FLOAT_COMP(x, y) DEFAULT_DOUBLE_COMP(x, y) diff --git a/include/os/osEnv.h b/include/os/osEnv.h index c1fdc9e404..a3bd209693 100644 --- a/include/os/osEnv.h +++ b/include/os/osEnv.h @@ -36,6 +36,11 @@ extern int64_t tsStreamMax; extern float tsNumOfCores; extern int64_t tsTotalMemoryKB; extern char *tsProcPath; +extern char tsSIMDEnable; +extern char tsSSE42Enable; +extern char tsAVXEnable; +extern char tsAVX2Enable; +extern char tsFMAEnable; extern char configDir[]; extern char tsDataDir[]; diff --git a/include/os/osSysinfo.h b/include/os/osSysinfo.h index 47cdb02a6f..7765a60f88 100644 --- a/include/os/osSysinfo.h +++ b/include/os/osSysinfo.h @@ -40,6 +40,7 @@ int32_t taosGetOsReleaseName(char *releaseName, int32_t maxLen); int32_t taosGetCpuInfo(char *cpuModel, int32_t maxLen, float *numOfCores); int32_t taosGetCpuCores(float *numOfCores); void taosGetCpuUsage(double *cpu_system, double *cpu_engine); +int32_t taosGetCpuInstructions(char* sse42, char* avx, char* avx2, char* fma); int32_t taosGetTotalMemory(int64_t *totalKB); int32_t taosGetProcMemory(int64_t *usedKB); int32_t taosGetSysMemory(int64_t *usedKB); diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 1be77077b6..50b2c976fd 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -15,7 +15,6 @@ #define _DEFAULT_SOURCE #include "tglobal.h" -#include "tcompare.h" #include "tconfig.h" #include "tdatablock.h" #include "tgrant.h" @@ -312,7 +311,14 @@ static int32_t taosAddSystemCfg(SConfig *pCfg) { if (cfgAddLocale(pCfg, "locale", tsLocale) != 0) return -1; if (cfgAddCharset(pCfg, "charset", tsCharset) != 0) return -1; if (cfgAddBool(pCfg, "enableCoreFile", 1, 1) != 0) return -1; - if (cfgAddFloat(pCfg, "numOfCores", tsNumOfCores, 0, 100000, 1) != 0) return -1; + if (cfgAddFloat(pCfg, "numOfCores", tsNumOfCores, 1, 100000, 1) != 0) return -1; + + if (cfgAddBool(pCfg, "SSE42", tsSSE42Enable, 0) != 0) return -1; + if (cfgAddBool(pCfg, "AVX", tsAVXEnable, 0) != 0) return -1; + if (cfgAddBool(pCfg, "AVX2", tsAVX2Enable, 0) != 0) return -1; + if (cfgAddBool(pCfg, "FMA", tsFMAEnable, 0) != 0) return -1; + if (cfgAddBool(pCfg, "SIMD-Supported", tsSIMDEnable, 0) != 0) return -1; + if (cfgAddInt64(pCfg, "openMax", tsOpenMax, 0, INT64_MAX, 1) != 0) return -1; if (cfgAddInt64(pCfg, "streamMax", tsStreamMax, 0, INT64_MAX, 1) != 0) return -1; if (cfgAddInt32(pCfg, "pageSizeKB", tsPageSizeKB, 0, INT64_MAX, 1) != 0) return -1; diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 50a69a4241..01e0a499eb 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -13,7 +13,6 @@ * along with this program. If not, see . */ -#include #include "builtinsimpl.h" #include "function.h" #include "tdatablock.h" @@ -49,11 +48,48 @@ typedef struct SAvgRes { int16_t type; // store the original input type, used in merge function } SAvgRes; +static void floatVectorSumAVX(const SInputColumnInfoData* pInput, const float* plist, SAvgRes* pRes) { +#if __AVX__ + // find the start position that are aligned to 32bytes address in memory + int32_t startIndex = 0; //((uint64_t)plist) & ((1<<8u)-1); + int32_t bitWidth = 8; + + int32_t remain = (pInput->numOfRows - startIndex) % bitWidth; + int32_t rounds = (pInput->numOfRows - startIndex) / bitWidth; + const float* p = &plist[startIndex]; + + __m256 val; + __m256 sum = _mm256_setzero_ps(); + + for (int32_t i = 0; i < rounds; ++i) { + val = _mm256_loadu_ps(p); + sum = _mm256_add_ps(sum, val); + p += bitWidth; + } + + // let sum up the final results + const float* q = (const float*)∑ + pRes->sum.dsum += q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7]; + + // calculate the front and the reminder items in array list + for (int32_t j = 0; j < startIndex; ++j) { + pRes->sum.dsum += plist[j]; + } + + startIndex += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + pRes->sum.dsum += plist[j + startIndex]; + } +#endif +} + static int32_t handleFloatCols(const SColumnInfoData* pCol, const SInputColumnInfoData* pInput, SAvgRes* pRes) { int32_t numOfElems = 0; float* plist = (float*)pCol->pData; - if (pCol->hasNull || pInput->numOfRows < 8) { + const int32_t THRESHOLD_SIZE = 8; + + if (pCol->hasNull || pInput->numOfRows <= THRESHOLD_SIZE) { for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { if (colDataIsNull_f(pCol->nullbitmap, i)) { continue; @@ -67,46 +103,13 @@ static int32_t handleFloatCols(const SColumnInfoData* pCol, const SInputColumnIn numOfElems = pInput->numOfRows; pRes->count += pInput->numOfRows; - // 1. an software version to speedup the process by using loop unwinding. - - - - // 2. if both the CPU and OS support SSE4.2, let's try the faster version by using SSE4.2 SIMD - - - - // 3. If both the CPU and OS support AVX, let's employ AVX instruction to speedup this loop - // 3.1 find the start position that are aligned to 32bytes address in memory - int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); - int32_t i = 0; - - int32_t bitWidth = 8; - - int32_t remain = (pInput->numOfRows - startElem) % bitWidth; - int32_t rounds = (pInput->numOfRows - startElem) / bitWidth; - const float* p = &plist[startElem]; - - __m256 loadVal; - __m256 sum = _mm256_setzero_ps(); - - for(; i < rounds; ++i) { - loadVal = _mm256_loadu_ps(p); - sum = _mm256_add_ps(sum, loadVal); - p += bitWidth; - } - - // let sum up the final results - const float* q = (const float*)∑ - pRes->sum.dsum += q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7]; - - // calculate the front and the reminder items in array list - for(int32_t j = 0; j < startElem; ++j) { - pRes->sum.dsum += plist[j]; - } - - startElem += rounds * bitWidth; - for(int32_t j = 0; j < remain; ++j) { - pRes->sum.dsum += plist[j + startElem]; + // 3. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (tsAVXEnable && tsSIMDEnable) { + floatVectorSumAVX(pInput, plist, pRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pRes->sum.dsum += plist[i]; + } } } diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index 7814a41f4f..074e5ef428 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -13,20 +13,163 @@ * along with this program. If not, see . */ -#include #include "builtinsimpl.h" #include "function.h" #include "tdatablock.h" #include "tfunctionInt.h" #include "tglobal.h" +static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool isMinFunc) { + int32_t v = 0; + +#if __AVX2__ + int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); + int32_t bitWidth = 8; + + int32_t remain = (numOfRows - startElem) % bitWidth; + int32_t rounds = (numOfRows - startElem) / bitWidth; + const int32_t* p = &pData[startElem]; + + __m256i next; + __m256i initialVal = _mm256_loadu_si256((__m256i*)p); + p += bitWidth; + + if (!isMinFunc) { // max function + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_loadu_si256((__m256i*)p); + initialVal = _mm256_max_epi32(initialVal, next); + p += bitWidth; + } + + // let sum up the final results + const int32_t* q = (const int32_t*)&initialVal; + + v = TMAX(q[0], q[1]); + v = TMAX(v, q[2]); + v = TMAX(v, q[3]); + v = TMAX(v, q[4]); + v = TMAX(v, q[5]); + v = TMAX(v, q[6]); + v = TMAX(v, q[7]); + + // calculate the front and the reminder items in array list + startElem += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + startElem]) { + v = p[j + startElem]; + } + } + } else { // min function + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_loadu_si256((__m256i*)p); + initialVal = _mm256_min_epi32(initialVal, next); + p += bitWidth; + } + + // let sum up the final results + const int32_t* q = (const int32_t*)&initialVal; + + v = TMIN(q[0], q[1]); + v = TMIN(v, q[2]); + v = TMIN(v, q[3]); + v = TMIN(v, q[4]); + v = TMIN(v, q[5]); + v = TMIN(v, q[6]); + v = TMIN(v, q[7]); + + // calculate the front and the remainder items in array list + startElem += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + startElem]) { + v = p[j + startElem]; + } + } + } +#endif + + return v; +} + +static float floatVectorCmpAVX(const float* pData, int32_t numOfRows, bool isMinFunc) { + float v = 0; + +#if __AVX__ + int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); + int32_t i = 0; + + int32_t bitWidth = 8; + + int32_t remain = (numOfRows - startElem) % bitWidth; + int32_t rounds = (numOfRows - startElem) / bitWidth; + const float* p = &pData[startElem]; + + __m256 next; + __m256 initialVal = _mm256_loadu_ps(p); + p += bitWidth; + + if (!isMinFunc) { // max function + for (; i < rounds; ++i) { + next = _mm256_loadu_ps(p); + initialVal = _mm256_max_ps(initialVal, next); + p += bitWidth; + } + + // let sum up the final results + const float* q = (const float*)&initialVal; + + v = TMAX(q[0], q[1]); + v = TMAX(v, q[2]); + v = TMAX(v, q[3]); + v = TMAX(v, q[4]); + v = TMAX(v, q[5]); + v = TMAX(v, q[6]); + v = TMAX(v, q[7]); + + // calculate the front and the reminder items in array list + startElem += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + startElem]) { + v = p[j + startElem]; + } + } + } else { // min function + for (; i < rounds; ++i) { + next = _mm256_loadu_ps(p); + initialVal = _mm256_min_ps(initialVal, next); + p += bitWidth; + } + + // let sum up the final results + const float* q = (const float*)&initialVal; + + v = TMIN(q[0], q[1]); + v = TMIN(v, q[2]); + v = TMIN(v, q[3]); + v = TMIN(v, q[4]); + v = TMIN(v, q[5]); + v = TMIN(v, q[6]); + v = TMIN(v, q[7]); + + // calculate the front and the reminder items in array list + startElem += rounds * bitWidth; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + startElem]) { + v = p[j + startElem]; + } + } + } +#endif + + return v; +} + static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, bool isMinFunc) { int32_t* pData = (int32_t*)pCol->pData; int32_t* val = (int32_t*)&pBuf->v; int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { + if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { if (isMinFunc) { // min for (int32_t i = start; i < start + numOfRows; ++i) { if (colDataIsNull_f(pCol->nullbitmap, i)) { @@ -77,79 +220,30 @@ static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numO } } } else { // not has null value - // 1. software version - - - - - // 3. AVX2 version to speedup the loop - int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); - int32_t i = 0; - - int32_t bitWidth = 8; - int32_t v = 0; - - int32_t remain = (numOfRows - startElem) % bitWidth; - int32_t rounds = (numOfRows - startElem) / bitWidth; - const int32_t* p = &pData[startElem]; - - __m256i next; - __m256i initialVal = _mm256_loadu_si256((__m256i*)p); - p += bitWidth; - - if (!isMinFunc) { // max function - for (; i < rounds; ++i) { - next = _mm256_loadu_si256((__m256i*)p); - initialVal = _mm256_max_epi32(initialVal, next); - p += bitWidth; + // AVX2 version to speedup the loop + if (tsAVX2Enable && tsSIMDEnable) { + *val = i32VectorCmpAVX2(pData, numOfRows, isMinFunc); + } else { + if (!pBuf->assign) { + *val = pData[0]; + pBuf->assign = true; } - // let sum up the final results - const int32_t* q = (const int32_t*)&initialVal; - - v = TMAX(q[0], q[1]); - v = TMAX(v, q[2]); - v = TMAX(v, q[3]); - v = TMAX(v, q[4]); - v = TMAX(v, q[5]); - v = TMAX(v, q[6]); - v = TMAX(v, q[7]); - - // calculate the front and the reminder items in array list - startElem += rounds * bitWidth; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + startElem]) { - v = p[j + startElem]; + if (isMinFunc) { // min + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val > pData[i]) { + *val = pData[i]; + } } - } - } else { // min function - for (; i < rounds; ++i) { - next = _mm256_loadu_si256((__m256i*)p); - initialVal = _mm256_min_epi32(initialVal, next); - p += bitWidth; - } - - // let sum up the final results - const int32_t* q = (const int32_t*)&initialVal; - - v = TMIN(q[0], q[1]); - v = TMIN(v, q[2]); - v = TMIN(v, q[3]); - v = TMIN(v, q[4]); - v = TMIN(v, q[5]); - v = TMIN(v, q[6]); - v = TMIN(v, q[7]); - - // calculate the front and the reminder items in array list - startElem += rounds * bitWidth; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + startElem]) { - v = p[j + startElem]; + } else { // max + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val < pData[i]) { + *val = pData[i]; + } } } } - *val = v; numOfElems = numOfRows; } @@ -213,79 +307,30 @@ static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numO } } } else { // not has null value - // 1. software version - - - - - // 3. AVX2 version to speedup the loop - int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); - int32_t i = 0; - - int32_t bitWidth = 8; - float v = 0; - - int32_t remain = (numOfRows - startElem) % bitWidth; - int32_t rounds = (numOfRows - startElem) / bitWidth; - const float* p = &pData[startElem]; - - __m256 next; - __m256 initialVal = _mm256_loadu_ps(p); - p += bitWidth; - - if (!isMinFunc) { // max function - for (; i < rounds; ++i) { - next = _mm256_loadu_ps(p); - initialVal = _mm256_max_ps(initialVal, next); - p += bitWidth; + // AVX version to speedup the loop + if (tsAVXEnable && tsSIMDEnable) { + *val = (double) floatVectorCmpAVX(pData, numOfRows, isMinFunc); + } else { + if (!pBuf->assign) { + *val = pData[0]; + pBuf->assign = true; } - // let sum up the final results - const float* q = (const float*)&initialVal; - - v = TMAX(q[0], q[1]); - v = TMAX(v, q[2]); - v = TMAX(v, q[3]); - v = TMAX(v, q[4]); - v = TMAX(v, q[5]); - v = TMAX(v, q[6]); - v = TMAX(v, q[7]); - - // calculate the front and the reminder items in array list - startElem += rounds * bitWidth; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + startElem]) { - v = p[j + startElem]; + if (isMinFunc) { // min + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val > pData[i]) { + *val = pData[i]; + } } - } - } else { // min function - for (; i < rounds; ++i) { - next = _mm256_loadu_ps(p); - initialVal = _mm256_min_ps(initialVal, next); - p += bitWidth; - } - - // let sum up the final results - const float* q = (const float*)&initialVal; - - v = TMIN(q[0], q[1]); - v = TMIN(v, q[2]); - v = TMIN(v, q[3]); - v = TMIN(v, q[4]); - v = TMIN(v, q[5]); - v = TMIN(v, q[6]); - v = TMIN(v, q[7]); - - // calculate the front and the reminder items in array list - startElem += rounds * bitWidth; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + startElem]) { - v = p[j + startElem]; + } else { // max + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val < pData[i]) { + *val = pData[i]; + } } } } - *val = v; numOfElems = numOfRows; } diff --git a/source/os/src/osEnv.c b/source/os/src/osEnv.c index ac1881fc6d..7063d1f574 100644 --- a/source/os/src/osEnv.c +++ b/source/os/src/osEnv.c @@ -37,6 +37,12 @@ float tsNumOfCores = 0; int64_t tsTotalMemoryKB = 0; char *tsProcPath = NULL; +char tsSIMDEnable = 0; +char tsSSE42Enable = 0; +char tsAVXEnable = 0; +char tsAVX2Enable = 0; +char tsFMAEnable = 0; + void osDefaultInit() { taosSeedRand(taosSafeRand()); taosGetSystemLocale(tsLocale, tsCharset); @@ -99,7 +105,7 @@ bool osDataSpaceSufficient() { return tsDataSpace.size.avail > tsDataSpace.reser bool osTempSpaceSufficient() { return tsTempSpace.size.avail > tsTempSpace.reserved; } -void osSetTimezone(const char *timezone) { taosSetSystemTimezone(timezone, tsTimezoneStr, &tsDaylight, &tsTimezone); } +void osSetTimezone(const char *tz) { taosSetSystemTimezone(tz, tsTimezoneStr, &tsDaylight, &tsTimezone); } void osSetSystemLocale(const char *inLocale, const char *inCharSet) { memcpy(tsLocale, inLocale, strlen(inLocale) + 1); diff --git a/source/os/src/osFile.c b/source/os/src/osFile.c index 94a10322ed..9b42a7ea44 100644 --- a/source/os/src/osFile.c +++ b/source/os/src/osFile.c @@ -775,6 +775,7 @@ int64_t taosGetLineFile(TdFilePtr pFile, char **__restrict ptrBuf) { return getline(ptrBuf, &len, pFile->fp); #endif } + int64_t taosGetsFile(TdFilePtr pFile, int32_t maxSize, char *__restrict buf) { if (pFile == NULL || buf == NULL) { return -1; @@ -785,6 +786,7 @@ int64_t taosGetsFile(TdFilePtr pFile, int32_t maxSize, char *__restrict buf) { } return strlen(buf); } + int32_t taosEOFFile(TdFilePtr pFile) { if (pFile == NULL) { return 0; diff --git a/source/os/src/osLocale.c b/source/os/src/osLocale.c index 89216ecaf4..7319181a77 100644 --- a/source/os/src/osLocale.c +++ b/source/os/src/osLocale.c @@ -67,6 +67,9 @@ char *taosCharsetReplace(char *charsetstr) { } /** + * TODO: here we may employ the systemctl API to set/get the correct locale on the Linux. In some cases, the setlocale + * seems does not response as expected. + * * In some Linux systems, setLocale(LC_CTYPE, "") may return NULL, in which case the launch of * both the TDengine Server and the Client may be interrupted. * @@ -148,7 +151,7 @@ void taosGetSystemLocale(char *outLocale, char *outCharset) { * * example: en_US.UTF-8, zh_CN.GB18030, zh_CN.UTF-8, * - * if user does not specify the locale in taos.cfg the program use default LC_CTYPE as system locale. + * If user does not specify the locale in taos.cfg, the program then uses default LC_CTYPE as system locale. * * In case of some CentOS systems, their default locale is "en_US.utf8", which is not valid code_page * for libiconv that is employed to convert string in this system. This program will automatically use diff --git a/source/os/src/osSysinfo.c b/source/os/src/osSysinfo.c index e5ca9faacb..51fff3a04f 100644 --- a/source/os/src/osSysinfo.c +++ b/source/os/src/osSysinfo.c @@ -155,8 +155,8 @@ static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) { } char line[1024]; - ssize_t _bytes = taosGetsFile(pFile, sizeof(line), line); - if ((_bytes < 0) || (line == NULL)) { + ssize_t bytes = taosGetsFile(pFile, sizeof(line), line); + if (bytes < 0) { taosCloseFile(&pFile); return -1; } @@ -193,9 +193,9 @@ static int32_t taosGetProcCpuInfo(ProcCpuInfo *cpuInfo) { return -1; } - char line[1024]; - ssize_t _bytes = taosGetsFile(pFile, sizeof(line), line); - if ((_bytes < 0) || (line == NULL)) { + char line[1024] = {0}; + ssize_t bytes = taosGetsFile(pFile, sizeof(line), line); + if (bytes < 0) { taosCloseFile(&pFile); return -1; } @@ -239,6 +239,7 @@ void taosGetSystemInfo() { taosGetCpuCores(&tsNumOfCores); taosGetTotalMemory(&tsTotalMemoryKB); taosGetCpuUsage(NULL, NULL); + taosGetCpuInstructions(&tsSSE42Enable, &tsAVXEnable, &tsAVX2Enable, &tsFMAEnable); #endif } @@ -366,7 +367,7 @@ int32_t taosGetCpuInfo(char *cpuModel, int32_t maxLen, float *numOfCores) { return code; #else - char line[1024]; + char line[1024] = {0}; size_t size = 0; int32_t done = 0; int32_t code = -1; @@ -468,6 +469,46 @@ void taosGetCpuUsage(double *cpu_system, double *cpu_engine) { } } +#define __cpuid_fix(level, a, b, c, d) \ + __asm__("xor %%ecx, %%ecx\n" \ + "cpuid\n" \ + : "=a"(a), "=b"(b), "=c"(c), "=d"(d) \ + : "0"(level)) + +// todo add for windows and mac +int32_t taosGetCpuInstructions(char* sse42, char* avx, char* avx2, char* fma) { +#ifdef WINDOWS +#elif defined(_TD_DARWIN_64) +#else + + // Since the compiler is not support avx/avx2 instructions, the global variables always need to be + // set to be false +#if __AVX__ || __AVX2__ + tsSIMDEnable = true; +#else + tsSIMDEnable = false; +#endif + + uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; + + int32_t ret = __get_cpuid(1, &eax, &ebx, &ecx, &edx); + if (ret == 0) { + return -1; // failed to get the cpuid info + } + + *sse42 = (char) ((ecx & bit_SSE4_2) == bit_SSE4_2); + *avx = (char) ((ecx & bit_AVX) == bit_AVX); + *fma = (char) ((ecx & bit_FMA) == bit_FMA); + + // work around a bug in GCC. + // Ref to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77756 + __cpuid_fix(7u, eax, ebx, ecx, edx); + *avx2 = (char) ((ebx & bit_AVX2) == bit_AVX2); + return 0; + +#endif +} + int32_t taosGetTotalMemory(int64_t *totalKB) { #ifdef WINDOWS MEMORYSTATUSEX memsStat; @@ -511,11 +552,11 @@ int32_t taosGetProcMemory(int64_t *usedKB) { return -1; } - ssize_t _bytes = 0; - char line[1024]; + ssize_t bytes = 0; + char line[1024] = {0}; while (!taosEOFFile(pFile)) { - _bytes = taosGetsFile(pFile, sizeof(line), line); - if ((_bytes < 0) || (line == NULL)) { + bytes = taosGetsFile(pFile, sizeof(line), line); + if (bytes < 0) { break; } if (strstr(line, "VmRSS:") != NULL) { @@ -523,7 +564,7 @@ int32_t taosGetProcMemory(int64_t *usedKB) { } } - if (line == NULL) { + if (strlen(line) < 0) { // printf("read file:%s failed", tsProcMemFile); taosCloseFile(&pFile); return -1; @@ -624,14 +665,14 @@ int32_t taosGetProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, int TdFilePtr pFile = taosOpenFile(tsProcIOFile, TD_FILE_READ | TD_FILE_STREAM); if (pFile == NULL) return -1; - ssize_t _bytes = 0; - char line[1024]; + ssize_t bytes = 0; + char line[1024] = {0}; char tmp[24]; int readIndex = 0; while (!taosEOFFile(pFile)) { - _bytes = taosGetsFile(pFile, sizeof(line), line); - if (_bytes < 10 || line == NULL) { + bytes = taosGetsFile(pFile, sizeof(line), line); + if (bytes < 10) { break; } if (strstr(line, "rchar:") != NULL) { diff --git a/source/os/src/osTime.c b/source/os/src/osTime.c index 58a09565f9..2771c8064f 100644 --- a/source/os/src/osTime.c +++ b/source/os/src/osTime.c @@ -339,7 +339,7 @@ char *taosStrpTime(const char *buf, const char *fmt, struct tm *tm) { #endif } -FORCE_INLINE int32_t taosGetTimeOfDay(struct timeval *tv) { +int32_t taosGetTimeOfDay(struct timeval *tv) { #ifdef WINDOWS time_t t; t = taosGetTimestampSec(); @@ -455,6 +455,7 @@ static int isLeapYear(time_t year) { else return 1; } + struct tm *taosLocalTimeNolock(struct tm *result, const time_t *timep, int dst) { if (result == NULL) { return localtime(timep); @@ -542,7 +543,9 @@ struct tm *taosLocalTimeNolock(struct tm *result, const time_t *timep, int dst) #endif return result; } + int32_t taosGetTimestampSec() { return (int32_t)time(NULL); } + int32_t taosClockGetTime(int clock_id, struct timespec *pTS) { #ifdef WINDOWS LARGE_INTEGER t; diff --git a/source/util/src/tconfig.c b/source/util/src/tconfig.c index c1fee37610..9949d9e4f1 100644 --- a/source/util/src/tconfig.c +++ b/source/util/src/tconfig.c @@ -561,13 +561,13 @@ void cfgDumpCfg(SConfig *pCfg, bool tsc, bool dump) { if (dump && strcmp(pItem->name, "scriptDir") == 0) continue; if (dump && strcmp(pItem->name, "simDebugFlag") == 0) continue; tstrncpy(src, cfgStypeStr(pItem->stype), CFG_SRC_PRINT_LEN); - for (int32_t i = 0; i < CFG_SRC_PRINT_LEN; ++i) { - if (src[i] == 0) src[i] = ' '; + for (int32_t j = 0; j < CFG_SRC_PRINT_LEN; ++j) { + if (src[j] == 0) src[j] = ' '; } tstrncpy(name, pItem->name, CFG_NAME_PRINT_LEN); - for (int32_t i = 0; i < CFG_NAME_PRINT_LEN; ++i) { - if (name[i] == 0) name[i] = ' '; + for (int32_t j = 0; j < CFG_NAME_PRINT_LEN; ++j) { + if (name[j] == 0) name[j] = ' '; } switch (pItem->dtype) { diff --git a/source/util/src/tcrc32c.c b/source/util/src/tcrc32c.c index bd662fa02c..795fe9dc4f 100644 --- a/source/util/src/tcrc32c.c +++ b/source/util/src/tcrc32c.c @@ -24,7 +24,6 @@ #endif #include "tcrc32c.h" -#include "tdef.h" #define POLY 0x82f63b78 #define LONG_SHIFT 8192 From f3be4454125a1d9683bb668ad4610a2fe9613eb1 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 11 Nov 2022 18:09:38 +0800 Subject: [PATCH 04/66] refactor: do some internal refactor. --- source/libs/executor/src/cachescanoperator.c | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/source/libs/executor/src/cachescanoperator.c b/source/libs/executor/src/cachescanoperator.c index 6f9084ce52..5707c7cde0 100644 --- a/source/libs/executor/src/cachescanoperator.c +++ b/source/libs/executor/src/cachescanoperator.c @@ -30,6 +30,8 @@ static void destroyLastrowScanOperator(void* param); static int32_t extractCacheScanSlotId(const SArray* pColMatchInfo, SExecTaskInfo* pTaskInfo, int32_t** pSlotIds); static int32_t removeRedundantTsCol(SLastRowScanPhysiNode* pScanNode, SColMatchInfo* pColMatchInfo); +#define SCAN_ROW_TYPE(_t) ((_t)? CACHESCAN_RETRIEVE_LAST : CACHESCAN_RETRIEVE_LAST_ROW) + SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SReadHandle* readHandle, SExecTaskInfo* pTaskInfo) { int32_t code = TSDB_CODE_SUCCESS; @@ -61,14 +63,14 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe STableListInfo* pTableList = pTaskInfo->pTableInfoList; - initResultSizeInfo(&pOperator->resultInfo, 4096); - blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); + int32_t totalTables = tableListGetSize(pTableList); + int32_t capacity = 0; + pInfo->pUidList = taosArrayInit(4, sizeof(int64_t)); - // partition by tbname, todo opt perf - if (oneTableForEachGroup(pTableList) || (tableListGetSize(pTableList) == 1)) { - pInfo->retrieveType = - CACHESCAN_RETRIEVE_TYPE_ALL | (pScanNode->ignoreNull ? CACHESCAN_RETRIEVE_LAST : CACHESCAN_RETRIEVE_LAST_ROW); + // partition by tbname + if (oneTableForEachGroup(pTableList) || (totalTables == 1)) { + pInfo->retrieveType = CACHESCAN_RETRIEVE_TYPE_ALL | SCAN_ROW_TYPE(pScanNode->ignoreNull); STableKeyInfo* pList = tableListGetInfo(pTableList, 0); @@ -80,13 +82,18 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe goto _error; } + capacity = TMIN(totalTables, 4096); + pInfo->pBufferredRes = createOneDataBlock(pInfo->pRes, false); - blockDataEnsureCapacity(pInfo->pBufferredRes, pOperator->resultInfo.capacity); + blockDataEnsureCapacity(pInfo->pBufferredRes, capacity); } else { // by tags - pInfo->retrieveType = CACHESCAN_RETRIEVE_TYPE_SINGLE | - (pScanNode->ignoreNull ? CACHESCAN_RETRIEVE_LAST : CACHESCAN_RETRIEVE_LAST_ROW); + pInfo->retrieveType = CACHESCAN_RETRIEVE_TYPE_SINGLE | SCAN_ROW_TYPE(pScanNode->ignoreNull); + capacity = 1; // only one row output } + initResultSizeInfo(&pOperator->resultInfo, capacity); + blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); + if (pScanNode->scan.pScanPseudoCols != NULL) { SExprSupp* p = &pInfo->pseudoExprSup; p->pExprInfo = createExprInfo(pScanNode->scan.pScanPseudoCols, NULL, &p->numOfExprs); From 6ae82b071e85c1d0902f72d65eff7e8c68f8f8e6 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 11 Nov 2022 18:28:16 +0800 Subject: [PATCH 05/66] refactor: do some internal refactor. --- source/libs/executor/src/sortoperator.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c index fc53623d44..9a5f6a031d 100644 --- a/source/libs/executor/src/sortoperator.c +++ b/source/libs/executor/src/sortoperator.c @@ -536,6 +536,7 @@ typedef struct SMultiwayMergeOperatorInfo { SSortHandle* pSortHandle; SColMatchInfo matchInfo; SSDataBlock* pInputBlock; + SSDataBlock* pIntermediateBlock; // to hold the intermediate result int64_t startTs; // sort start time bool groupSort; bool hasGroupId; @@ -635,12 +636,19 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; blockDataCleanup(pDataBlock); - SSDataBlock* p = tsortGetSortedDataBlock(pHandle); - if (p == NULL) { - return NULL; + if (pInfo->pIntermediateBlock == NULL) { + pInfo->pIntermediateBlock = tsortGetSortedDataBlock(pHandle); + if (pInfo->pIntermediateBlock == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return NULL; + } + blockDataEnsureCapacity(pInfo->pIntermediateBlock, capacity); + } else { + blockDataCleanup(pInfo->pIntermediateBlock); } - blockDataEnsureCapacity(p, capacity); + SSDataBlock* p = pInfo->pIntermediateBlock; + while (1) { doGetSortedBlockData(pInfo, pHandle, capacity, p); if (p->info.rows == 0) { @@ -670,7 +678,6 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData pDataBlock->info.groupId = pInfo->groupId; } - blockDataDestroy(p); qDebug("%s get sorted block, groupId:0x%" PRIx64 " rows:%d", GET_TASKID(pTaskInfo), pDataBlock->info.groupId, pDataBlock->info.rows); @@ -704,6 +711,7 @@ void destroyMultiwayMergeOperatorInfo(void* param) { SMultiwayMergeOperatorInfo* pInfo = (SMultiwayMergeOperatorInfo*)param; pInfo->binfo.pRes = blockDataDestroy(pInfo->binfo.pRes); pInfo->pInputBlock = blockDataDestroy(pInfo->pInputBlock); + pInfo->pIntermediateBlock = blockDataDestroy(pInfo->pIntermediateBlock); tsortDestroySortHandle(pInfo->pSortHandle); taosArrayDestroy(pInfo->pSortInfo); From ab52d28cb04558b29b3a72cf9c2e9c2ab9141396 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 11 Nov 2022 22:18:06 +0800 Subject: [PATCH 06/66] refactor: do some internal refactor. --- source/libs/executor/inc/executorimpl.h | 7 ++-- source/libs/executor/src/cachescanoperator.c | 3 +- source/libs/executor/src/exchangeoperator.c | 43 ++++++++++++-------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 62146b6048..e70cf37c63 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -254,17 +254,18 @@ typedef struct SExchangeInfo { SArray* pSourceDataInfo; tsem_t ready; void* pTransporter; + // SArray, result block list, used to keep the multi-block that // passed by downstream operator - SArray* pResultBlockList; - int32_t rspBlockIndex; // indicate the return block index in pResultBlockList + SArray* pReadyBlocks; + SArray* pRecycledBlocks;// build a pool for small data block to avoid to repeatly create and then destroy. SSDataBlock* pDummyBlock; // dummy block, not keep data bool seqLoadData; // sequential load data or not, false by default int32_t current; SLoadRemoteDataInfo loadInfo; uint64_t self; SLimitInfo limitInfo; - int64_t openedTs; // start exec time stamp + int64_t openedTs; // start exec time stamp, todo: move to SLoadRemoteDataInfo } SExchangeInfo; typedef struct SScanInfo { diff --git a/source/libs/executor/src/cachescanoperator.c b/source/libs/executor/src/cachescanoperator.c index 5707c7cde0..bbd46502ce 100644 --- a/source/libs/executor/src/cachescanoperator.c +++ b/source/libs/executor/src/cachescanoperator.c @@ -74,9 +74,8 @@ SOperatorInfo* createCacherowsScanOperator(SLastRowScanPhysiNode* pScanNode, SRe STableKeyInfo* pList = tableListGetInfo(pTableList, 0); - size_t num = tableListGetSize(pTableList); uint64_t suid = tableListGetSuid(pTableList); - code = tsdbCacherowsReaderOpen(pInfo->readHandle.vnode, pInfo->retrieveType, pList, num, + code = tsdbCacherowsReaderOpen(pInfo->readHandle.vnode, pInfo->retrieveType, pList, totalTables, taosArrayGetSize(pInfo->matchInfo.pList), suid, &pInfo->pLastrowReader); if (code != TSDB_CODE_SUCCESS) { goto _error; diff --git a/source/libs/executor/src/exchangeoperator.c b/source/libs/executor/src/exchangeoperator.c index 049de727df..4151018636 100644 --- a/source/libs/executor/src/exchangeoperator.c +++ b/source/libs/executor/src/exchangeoperator.c @@ -100,14 +100,23 @@ static void concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeIn int32_t index = 0; char* pStart = pRetrieveRsp->data; while (index++ < pRetrieveRsp->numOfBlocks) { - SSDataBlock* pb = createOneDataBlock(pExchangeInfo->pDummyBlock, false); + SSDataBlock* pb = NULL; + + void* p = taosArrayPop(pExchangeInfo->pRecycledBlocks); + if (p != NULL) { + pb = *(SSDataBlock**) p; + blockDataCleanup(pb); + } else { + pb = createOneDataBlock(pExchangeInfo->pDummyBlock, false); + } + code = extractDataBlockFromFetchRsp(pb, pStart, NULL, &pStart); if (code != 0) { taosMemoryFreeClear(pDataInfo->pRsp); goto _error; } - taosArrayPush(pExchangeInfo->pResultBlockList, &pb); + taosArrayPush(pExchangeInfo->pReadyBlocks, &pb); } updateLoadRemoteInfo(pLoadInfo, pRetrieveRsp->numOfRows, pRetrieveRsp->compLen, pExchangeInfo->openedTs, pOperator); @@ -170,23 +179,26 @@ static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) { return NULL; } - size_t size = taosArrayGetSize(pExchangeInfo->pResultBlockList); - if (size == 0 || pExchangeInfo->rspBlockIndex >= size) { - pExchangeInfo->rspBlockIndex = 0; - taosArrayClearEx(pExchangeInfo->pResultBlockList, freeBlock); + // we have buffered retrieved datablock, return it directly + SSDataBlock** p = taosArrayPop(pExchangeInfo->pReadyBlocks); + if (p != NULL) { + taosArrayPush(pExchangeInfo->pRecycledBlocks, p); + return *p; + } else { if (pExchangeInfo->seqLoadData) { seqLoadRemoteData(pOperator); } else { concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo); } - if (taosArrayGetSize(pExchangeInfo->pResultBlockList) == 0) { + if (taosArrayGetSize(pExchangeInfo->pReadyBlocks) == 0) { return NULL; + } else { + p = taosArrayPop(pExchangeInfo->pReadyBlocks); + taosArrayPush(pExchangeInfo->pRecycledBlocks, p); + return *p; } } - - // we have buffered retrieved datablock, return it directly - return taosArrayGetP(pExchangeInfo->pResultBlockList, pExchangeInfo->rspBlockIndex++); } static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator) { @@ -284,7 +296,8 @@ SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, SExchangePhysiNode tsem_init(&pInfo->ready, 0, 0); pInfo->pDummyBlock = createResDataBlock(pExNode->node.pOutputDataBlockDesc); - pInfo->pResultBlockList = taosArrayInit(1, POINTER_BYTES); + pInfo->pReadyBlocks = taosArrayInit(64, POINTER_BYTES); + pInfo->pRecycledBlocks = taosArrayInit(64, POINTER_BYTES); pInfo->seqLoadData = false; pInfo->pTransporter = pTransporter; @@ -326,11 +339,9 @@ void doDestroyExchangeOperatorInfo(void* param) { taosArrayDestroy(pExInfo->pSources); taosArrayDestroyEx(pExInfo->pSourceDataInfo, freeSourceDataInfo); - if (pExInfo->pResultBlockList != NULL) { - taosArrayDestroyEx(pExInfo->pResultBlockList, freeBlock); - pExInfo->pResultBlockList = NULL; - } - + taosArrayDestroyEx(pExInfo->pReadyBlocks, freeBlock); + taosArrayDestroyEx(pExInfo->pRecycledBlocks, freeBlock); + blockDataDestroy(pExInfo->pDummyBlock); tsem_destroy(&pExInfo->ready); From 7b53b8142e40c1750eb82ad2b76116e467ae50e4 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 12 Nov 2022 16:03:47 +0800 Subject: [PATCH 07/66] refactor: do some internal refactor. --- source/common/src/tdatablock.c | 1 + source/libs/executor/inc/executorimpl.h | 18 +++++++++--------- source/libs/executor/src/executor.c | 16 ++++++++++++++-- source/libs/executor/src/executorimpl.c | 7 +++++++ source/libs/qworker/src/qworker.c | 7 +------ 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 536cbed33e..f5dba35440 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -1306,6 +1306,7 @@ int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src) { colDataAssign(pDst, pSrc, src->info.rows, &src->info); } + uint32_t cap = dst->info.capacity; dst->info = src->info; dst->info.capacity = cap; diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index e70cf37c63..a2e269dd51 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -153,14 +153,13 @@ typedef struct { SSchemaWrapper* qsw; } SSchemaInfo; -typedef struct SExecTaskInfo { - STaskIdInfo id; - uint32_t status; - STimeWindow window; - STaskCostInfo cost; - int64_t owner; // if it is in execution - int32_t code; - +struct SExecTaskInfo { + STaskIdInfo id; + uint32_t status; + STimeWindow window; + STaskCostInfo cost; + int64_t owner; // if it is in execution + int32_t code; int64_t version; // used for stream to record wal version SStreamTaskInfo streamInfo; SSchemaInfo schemaInfo; @@ -171,7 +170,8 @@ typedef struct SExecTaskInfo { SSubplan* pSubplan; struct SOperatorInfo* pRoot; SLocalFetch localFetch; -} SExecTaskInfo; + SArray* pResultBlockList;// result block list +}; enum { OP_NOT_OPENED = 0x0, diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 1aa9a3c613..0163a389ef 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -536,7 +536,7 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo memcpy(&pTaskInfo->localFetch, pLocal, sizeof(*pLocal)); } - taosArrayClearEx(pResList, freeBlock); + taosArrayClear(pResList); int64_t curOwner = 0; if ((curOwner = atomic_val_compare_exchange_64(&pTaskInfo->owner, 0, threadId)) != 0) { @@ -574,8 +574,20 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo int64_t st = taosGetTimestampUs(); + int32_t blockIndex = 0; while ((pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot)) != NULL) { - SSDataBlock* p = createOneDataBlock(pRes, true); + SSDataBlock* p = NULL; + if (blockIndex >= taosArrayGetSize(pTaskInfo->pResultBlockList)) { + SSDataBlock* p1 = createOneDataBlock(pRes, true); + taosArrayPush(pTaskInfo->pResultBlockList, &p1); + p = p1; + } else { + p = *(SSDataBlock**) taosArrayGet(pTaskInfo->pResultBlockList, blockIndex); + copyDataBlock(p, pRes); + } + + blockIndex += 1; + current += p->info.rows; ASSERT(p->info.rows > 0); taosArrayPush(pResList, &p); diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 709e981a1f..f164622687 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -2600,6 +2600,7 @@ static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPT pTaskInfo->id.queryId = queryId; pTaskInfo->execModel = model; pTaskInfo->pTableInfoList = tableListCreate(); + pTaskInfo->pResultBlockList = taosArrayInit(128, POINTER_BYTES); char* p = taosMemoryCalloc(1, 128); snprintf(p, 128, "TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, queryId); @@ -3201,6 +3202,11 @@ _complete: return terrno; } +static void freeBlock(void* pParam) { + SSDataBlock* pBlock = *(SSDataBlock**)pParam; + blockDataDestroy(pBlock); +} + void doDestroyTask(SExecTaskInfo* pTaskInfo) { qDebug("%s execTask is freed", GET_TASKID(pTaskInfo)); @@ -3213,6 +3219,7 @@ void doDestroyTask(SExecTaskInfo* pTaskInfo) { nodesDestroyNode((SNode*)pTaskInfo->pSubplan); } + taosArrayDestroyEx(pTaskInfo->pResultBlockList, freeBlock); taosMemoryFreeClear(pTaskInfo->sql); taosMemoryFreeClear(pTaskInfo->id.str); taosMemoryFreeClear(pTaskInfo); diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index a7cd3db824..2606556838 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -18,11 +18,6 @@ SQWorkerMgmt gQwMgmt = { .qwNum = 0, }; -static void freeBlock(void *param) { - SSDataBlock *pBlock = *(SSDataBlock **)param; - blockDataDestroy(pBlock); -} - int32_t qwProcessHbLinkBroken(SQWorker *mgmt, SQWMsg *qwMsg, SSchedulerHbReq *req) { int32_t code = 0; SSchedulerHbRsp rsp = {0}; @@ -193,7 +188,7 @@ int32_t qwExecTask(QW_FPARAMS_DEF, SQWTaskCtx *ctx, bool *queryStop) { } _return: - taosArrayDestroyEx(pResList, freeBlock); + taosArrayDestroy(pResList); QW_RET(code); } From c888cbf068dd09103256a4e8061fa5d57290078e Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Nov 2022 14:14:24 +0800 Subject: [PATCH 08/66] refactor: do some internal refactor. --- include/libs/function/function.h | 2 +- source/libs/executor/src/executorimpl.c | 16 +- source/libs/function/src/builtinsimpl.c | 30 +- .../libs/function/src/detail/tavgfunction.c | 300 ++++++++++++++++-- source/libs/function/src/detail/tminmax.c | 6 +- 5 files changed, 304 insertions(+), 50 deletions(-) diff --git a/include/libs/function/function.h b/include/libs/function/function.h index 6f2a675466..240772bfc2 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -115,7 +115,7 @@ typedef struct SInputColumnInfoData { int32_t startRowIndex; // handle started row index int32_t numOfRows; // the number of rows needs to be handled int32_t numOfInputCols; // PTS is not included - bool colDataAggIsSet; // if agg is set or not + bool colDataSMAIsSet; // if agg is set or not SColumnInfoData *pPTS; // primary timestamp column SColumnInfoData **pData; SColumnDataAgg **pColumnDataAgg; diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index f164622687..5031d75231 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -349,13 +349,13 @@ typedef struct { } SFunctionCtxStatus; static void functionCtxSave(SqlFunctionCtx* pCtx, SFunctionCtxStatus* pStatus) { - pStatus->hasAgg = pCtx->input.colDataAggIsSet; + pStatus->hasAgg = pCtx->input.colDataSMAIsSet; pStatus->numOfRows = pCtx->input.numOfRows; pStatus->startOffset = pCtx->input.startRowIndex; } static void functionCtxRestore(SqlFunctionCtx* pCtx, SFunctionCtxStatus* pStatus) { - pCtx->input.colDataAggIsSet = pStatus->hasAgg; + pCtx->input.colDataSMAIsSet = pStatus->hasAgg; pCtx->input.numOfRows = pStatus->numOfRows; pCtx->input.startRowIndex = pStatus->startOffset; } @@ -372,8 +372,8 @@ void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, SColumnInfo // not a whole block involved in query processing, statistics data can not be used // NOTE: the original value of isSet have been changed here - if (pCtx[k].input.colDataAggIsSet && forwardStep < numOfTotal) { - pCtx[k].input.colDataAggIsSet = false; + if (pCtx[k].input.colDataSMAIsSet && forwardStep < numOfTotal) { + pCtx[k].input.colDataSMAIsSet = false; } if (fmIsWindowPseudoColumnFunc(pCtx[k].functionId)) { @@ -486,7 +486,7 @@ static int32_t doSetInputDataBlock(SExprSupp* pExprSup, SSDataBlock* pBlock, int SInputColumnInfoData* pInput = &pCtx[i].input; pInput->uid = pBlock->info.uid; - pInput->colDataAggIsSet = false; + pInput->colDataSMAIsSet = false; SExprInfo* pOneExpr = &pExprSup->pExprInfo[i]; for (int32_t j = 0; j < pOneExpr->base.numOfParams; ++j) { @@ -798,7 +798,7 @@ void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pB pInput->totalRows = numOfRows; if (pBlock->pBlockAgg != NULL) { - pInput->colDataAggIsSet = true; + pInput->colDataSMAIsSet = true; for (int32_t j = 0; j < pExprInfo->base.numOfParams; ++j) { SFunctParam* pFuncParam = &pExprInfo->base.pParam[j]; @@ -807,7 +807,7 @@ void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pB int32_t slotId = pFuncParam->pCol->slotId; pInput->pColumnDataAgg[j] = pBlock->pBlockAgg[slotId]; if (pInput->pColumnDataAgg[j] == NULL) { - pInput->colDataAggIsSet = false; + pInput->colDataSMAIsSet = false; } // Here we set the column info data since the data type for each column data is required, but @@ -818,7 +818,7 @@ void setBlockSMAInfo(SqlFunctionCtx* pCtx, SExprInfo* pExprInfo, SSDataBlock* pB } } } else { - pInput->colDataAggIsSet = false; + pInput->colDataSMAIsSet = false; } } diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 26f9c3ad0b..bf79cb5191 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -498,13 +498,13 @@ static int32_t getNumOfElems(SqlFunctionCtx* pCtx) { int32_t numOfElem = 0; /* - * 1. column data missing (schema modified) causes pInputCol->hasNull == true. pInput->colDataAggIsSet == true; - * 2. for general non-primary key columns, pInputCol->hasNull may be true or false, pInput->colDataAggIsSet == true; - * 3. for primary key column, pInputCol->hasNull always be false, pInput->colDataAggIsSet == false; + * 1. column data missing (schema modified) causes pInputCol->hasNull == true. pInput->colDataSMAIsSet == true; + * 2. for general non-primary key columns, pInputCol->hasNull may be true or false, pInput->colDataSMAIsSet == true; + * 3. for primary key column, pInputCol->hasNull always be false, pInput->colDataSMAIsSet == false; */ SInputColumnInfoData* pInput = &pCtx->input; SColumnInfoData* pInputCol = pInput->pData[0]; - if (pInput->colDataAggIsSet && pInput->totalRows == pInput->numOfRows) { + if (pInput->colDataSMAIsSet && pInput->totalRows == pInput->numOfRows) { numOfElem = pInput->numOfRows - pInput->pColumnDataAgg[0]->numOfNull; ASSERT(numOfElem >= 0); } else { @@ -593,7 +593,7 @@ int32_t sumFunction(SqlFunctionCtx* pCtx) { goto _sum_over; } - if (pInput->colDataAggIsSet) { + if (pInput->colDataSMAIsSet) { numOfElem = pInput->numOfRows - pAgg->numOfNull; ASSERT(numOfElem >= 0); @@ -658,7 +658,7 @@ int32_t sumInvertFunction(SqlFunctionCtx* pCtx) { SSumRes* pSumRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - if (pInput->colDataAggIsSet) { + if (pInput->colDataSMAIsSet) { numOfElem = pInput->numOfRows - pAgg->numOfNull; ASSERT(numOfElem >= 0); @@ -770,7 +770,7 @@ bool getSumFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { // goto _avg_over; // } // -// if (pInput->colDataAggIsSet) { +// if (pInput->colDataSMAIsSet) { // numOfElem = numOfRows - pAgg->numOfNull; // ASSERT(numOfElem >= 0); // @@ -1161,7 +1161,7 @@ bool getMinmaxFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { // } // // // data in current data block are qualified to the query -// if (pInput->colDataAggIsSet) { +// if (pInput->colDataSMAIsSet) { // numOfElems = pInput->numOfRows - pAgg->numOfNull; // ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0); // if (numOfElems == 0) { @@ -2471,7 +2471,7 @@ int32_t percentileFunction(SqlFunctionCtx* pCtx) { // the first stage, only acquire the min/max value if (pInfo->stage == 0) { - if (pCtx->input.colDataAggIsSet) { + if (pCtx->input.colDataSMAIsSet) { double tmin = 0.0, tmax = 0.0; if (IS_SIGNED_NUMERIC_TYPE(type)) { tmin = (double)GET_INT64_VAL(&pAgg->min); @@ -2933,14 +2933,14 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) { pInfo->bytes = pInputCol->info.bytes; // All null data column, return directly. - if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) { + if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) { ASSERT(pInputCol->hasNull == true); // save selectivity value for column consisted of all null values firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo); return 0; } - SColumnDataAgg* pColAgg = (pInput->colDataAggIsSet) ? pInput->pColumnDataAgg[0] : NULL; + SColumnDataAgg* pColAgg = (pInput->colDataSMAIsSet) ? pInput->pColumnDataAgg[0] : NULL; TSKEY startKey = getRowPTs(pInput->pPTS, 0); TSKEY endKey = getRowPTs(pInput->pPTS, pInput->totalRows - 1); @@ -3037,14 +3037,14 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) { pInfo->bytes = bytes; // All null data column, return directly. - if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) { + if (pInput->colDataSMAIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) { ASSERT(pInputCol->hasNull == true); // save selectivity value for column consisted of all null values firstlastSaveTupleData(pCtx->pSrcBlock, pInput->startRowIndex, pCtx, pInfo); return 0; } - SColumnDataAgg* pColAgg = (pInput->colDataAggIsSet) ? pInput->pColumnDataAgg[0] : NULL; + SColumnDataAgg* pColAgg = (pInput->colDataSMAIsSet) ? pInput->pColumnDataAgg[0] : NULL; TSKEY startKey = getRowPTs(pInput->pPTS, 0); TSKEY endKey = getRowPTs(pInput->pPTS, pInput->totalRows - 1); @@ -3988,7 +3988,7 @@ int32_t spreadFunction(SqlFunctionCtx* pCtx) { SSpreadInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - if (pInput->colDataAggIsSet) { + if (pInput->colDataSMAIsSet) { numOfElems = pInput->numOfRows - pAgg->numOfNull; if (numOfElems == 0) { goto _spread_over; @@ -4163,7 +4163,7 @@ int32_t elapsedFunction(SqlFunctionCtx* pCtx) { goto _elapsed_over; } - if (pInput->colDataAggIsSet) { + if (pInput->colDataSMAIsSet) { if (pInfo->min == TSKEY_MAX) { pInfo->min = GET_INT64_VAL(&pAgg->min); pInfo->max = GET_INT64_VAL(&pAgg->max); diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 01e0a499eb..9c3b9cf573 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -48,15 +48,14 @@ typedef struct SAvgRes { int16_t type; // store the original input type, used in merge function } SAvgRes; -static void floatVectorSumAVX(const SInputColumnInfoData* pInput, const float* plist, SAvgRes* pRes) { +static void floatVectorSumAVX(const float* plist, int32_t numOfRows, SAvgRes* pRes) { #if __AVX__ // find the start position that are aligned to 32bytes address in memory - int32_t startIndex = 0; //((uint64_t)plist) & ((1<<8u)-1); int32_t bitWidth = 8; + int32_t remainder = numOfRows % bitWidth; + int32_t rounds = numOfRows / bitWidth; - int32_t remain = (pInput->numOfRows - startIndex) % bitWidth; - int32_t rounds = (pInput->numOfRows - startIndex) / bitWidth; - const float* p = &plist[startIndex]; + const float* p = plist; __m256 val; __m256 sum = _mm256_setzero_ps(); @@ -71,18 +70,126 @@ static void floatVectorSumAVX(const SInputColumnInfoData* pInput, const float* p const float* q = (const float*)∑ pRes->sum.dsum += q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7]; - // calculate the front and the reminder items in array list - for (int32_t j = 0; j < startIndex; ++j) { - pRes->sum.dsum += plist[j]; + int32_t startIndex = rounds * bitWidth; + for (int32_t j = 0; j < remainder; ++j) { + pRes->sum.dsum += plist[j + startIndex]; + } +#endif +} + +static void doubleVectorSumAVX(const double* plist, int32_t numOfRows, SAvgRes* pRes) { +#if __AVX__ + // find the start position that are aligned to 32bytes address in memory + int32_t bitWidth = 4; + int32_t remainder = numOfRows % bitWidth; + int32_t rounds = numOfRows / bitWidth; + + const double* p = plist; + + __m256d val; + __m256d sum = _mm256_setzero_pd(); + + for (int32_t i = 0; i < rounds; ++i) { + val = _mm256_loadu_pd(p); + sum = _mm256_add_pd(sum, val); + p += bitWidth; } - startIndex += rounds * bitWidth; - for (int32_t j = 0; j < remain; ++j) { + // let sum up the final results + const double* q = (const double*)∑ + pRes->sum.dsum += q[0] + q[1] + q[2] + q[3]; + + int32_t startIndex = rounds * bitWidth; + for (int32_t j = 0; j < remainder; ++j) { pRes->sum.dsum += plist[j + startIndex]; } #endif } +static void i8VectorSumAVX2(const int8_t* plist, int32_t numOfRows, SAvgRes* pRes) { +#if __AVX2__ + // find the start position that are aligned to 32bytes address in memory + int32_t bitWidth = 16; + int32_t remainder = numOfRows % bitWidth; + int32_t rounds = numOfRows / bitWidth; + + const int8_t* p = plist; + + __m256i sum = _mm256_setzero_si256(); + + for (int32_t i = 0; i < rounds; ++i) { + __m256i val = _mm256_lddqu_si256((__m256i*)p); +// __m256i extVal = _mm256_cvtepi8_epi64(val); + sum = _mm256_add_epi8(sum, val); + p += bitWidth; + } + + // let sum up the final results + const int8_t* q = (const int8_t*)∑ + pRes->sum.isum += q[0] + q[1] + q[2] + q[3]; + + int32_t startIndex = rounds * bitWidth; + for (int32_t j = 0; j < remainder; ++j) { + pRes->sum.isum += plist[j + startIndex]; + } +#endif +} + +static void i32VectorSumAVX2(const int32_t* plist, int32_t numOfRows, SAvgRes* pRes) { +#if __AVX2__ + // find the start position that are aligned to 32bytes address in memory + int32_t bitWidth = 8; + int32_t remainder = numOfRows % bitWidth; + int32_t rounds = numOfRows / bitWidth; + + const int32_t* p = plist; + + __m256i sum = _mm256_setzero_si256(); + for (int32_t i = 0; i < rounds; ++i) { + __m256i val = _mm256_lddqu_si256((__m256i*)p); + sum = _mm256_add_epi32(sum, val); + p += bitWidth; + } + + // let sum up the final results + const int64_t* q = (const int64_t*)∑ + pRes->sum.isum += q[0] + q[1] + q[2] + q[3]; + + int32_t startIndex = rounds * bitWidth; + for (int32_t j = 0; j < remainder; ++j) { + pRes->sum.isum += plist[j + startIndex]; + } +#endif +} + +static void i64VectorSumAVX2(const int64_t* plist, int32_t numOfRows, SAvgRes* pRes) { +#if __AVX2__ + // find the start position that are aligned to 32bytes address in memory + int32_t bitWidth = 4; + int32_t remainder = numOfRows % bitWidth; + int32_t rounds = numOfRows / bitWidth; + + const int64_t* p = plist; + + __m256i sum = _mm256_setzero_si256(); + + for (int32_t i = 0; i < rounds; ++i) { + __m256i val = _mm256_lddqu_si256((__m256i*)p); + sum = _mm256_add_epi64(sum, val); + p += bitWidth; + } + + // let sum up the final results + const int64_t* q = (const int64_t*)∑ + pRes->sum.isum += q[0] + q[1] + q[2] + q[3]; + + int32_t startIndex = rounds * bitWidth; + for (int32_t j = 0; j < remainder; ++j) { + pRes->sum.isum += plist[j + startIndex]; + } +#endif +} + static int32_t handleFloatCols(const SColumnInfoData* pCol, const SInputColumnInfoData* pInput, SAvgRes* pRes) { int32_t numOfElems = 0; float* plist = (float*)pCol->pData; @@ -105,7 +212,7 @@ static int32_t handleFloatCols(const SColumnInfoData* pCol, const SInputColumnIn // 3. If the CPU supports AVX, let's employ AVX instructions to speedup this loop if (tsAVXEnable && tsSIMDEnable) { - floatVectorSumAVX(pInput, plist, pRes); + floatVectorSumAVX(plist, pInput->numOfRows, pRes); } else { for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { pRes->sum.dsum += plist[i]; @@ -133,8 +240,25 @@ bool avgFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) { return true; } +static int32_t calculateAvgBySMAInfo(SAvgRes* pRes, int32_t numOfRows, int32_t type, const SColumnDataAgg* pAgg) { + int32_t numOfElem = numOfRows - pAgg->numOfNull; + ASSERT(numOfElem >= 0); + + pRes->count += numOfElem; + if (IS_SIGNED_NUMERIC_TYPE(type)) { + pRes->sum.isum += pAgg->sum; + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + pRes->sum.usum += pAgg->sum; + } else if (IS_FLOAT_TYPE(type)) { + pRes->sum.dsum += GET_DOUBLE_VAL((const char*)&(pAgg->sum)); + } + + return numOfElem; +} + int32_t avgFunction(SqlFunctionCtx* pCtx) { - int32_t numOfElem = 0; + int32_t numOfElem = 0; + const int32_t THRESHOLD_SIZE = 8; SInputColumnInfoData* pInput = &pCtx->input; SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0]; @@ -154,19 +278,149 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { goto _avg_over; } - if (pInput->colDataAggIsSet) { - numOfElem = numOfRows - pAgg->numOfNull; - ASSERT(numOfElem >= 0); + if (pInput->colDataSMAIsSet) { // try to use SMA if available + numOfElem = calculateAvgBySMAInfo(pAvgRes, numOfRows, type, pAgg); + } else if (!pCol->hasNull) { // try to employ the simd instructions to speed up the loop + numOfElem = pInput->numOfRows; + pAvgRes->count += pInput->numOfRows; - pAvgRes->count += numOfElem; - if (IS_SIGNED_NUMERIC_TYPE(type)) { - pAvgRes->sum.isum += pAgg->sum; - } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - pAvgRes->sum.usum += pAgg->sum; - } else if (IS_FLOAT_TYPE(type)) { - pAvgRes->sum.dsum += GET_DOUBLE_VAL((const char*)&(pAgg->sum)); + bool simdAvaiable = tsAVXEnable && tsSIMDEnable && (numOfRows > THRESHOLD_SIZE); + + switch(type) { + case TSDB_DATA_TYPE_TINYINT: { + const int8_t* plist = (const int8_t*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + i8VectorSumAVX2(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.isum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + const double* plist = (const double*)pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + doubleVectorSumAVX(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.isum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_INT: { + const int32_t* plist = (const int32_t*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + i32VectorSumAVX2(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.isum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_BIGINT: { + const int64_t* plist = (const int64_t*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + i64VectorSumAVX2(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.isum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_FLOAT: { + const float* plist = (const float*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + floatVectorSumAVX(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.dsum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + const double* plist = (const double*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + doubleVectorSumAVX(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.dsum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_UTINYINT: { + const double* plist = (const double*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + doubleVectorSumAVX(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.usum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_USMALLINT: { + const double* plist = (const double*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + doubleVectorSumAVX(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.usum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_UINT: { + const double* plist = (const double*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + doubleVectorSumAVX(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.usum += plist[i]; + } + } + break; + } + case TSDB_DATA_TYPE_UBIGINT: { + const double* plist = (const double*) pCol->pData; + + // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop + if (simdAvaiable) { + doubleVectorSumAVX(plist, numOfRows, pAvgRes); + } else { + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { + pAvgRes->sum.usum += plist[i]; + } + } + break; + } + default: + ASSERT(0); } - } else { // computing based on the true data block + } else { switch (type) { case TSDB_DATA_TYPE_TINYINT: { int8_t* plist = (int8_t*)pCol->pData; diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index 074e5ef428..d239315e0e 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -36,7 +36,7 @@ static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool is if (!isMinFunc) { // max function for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_loadu_si256((__m256i*)p); + next = _mm256_lddqu_si256((__m256i*)p); initialVal = _mm256_max_epi32(initialVal, next); p += bitWidth; } @@ -61,7 +61,7 @@ static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool is } } else { // min function for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_loadu_si256((__m256i*)p); + next = _mm256_lddqu_si256((__m256i*)p); initialVal = _mm256_min_epi32(initialVal, next); p += bitWidth; } @@ -369,7 +369,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { } // data in current data block are qualified to the query - if (pInput->colDataAggIsSet) { + if (pInput->colDataSMAIsSet) { numOfElems = pInput->numOfRows - pAgg->numOfNull; ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0); if (numOfElems == 0) { From 618b4ab8810ea883224d869035c75a6af8bf542b Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Nov 2022 14:15:48 +0800 Subject: [PATCH 09/66] refactor: do some internal refactor. --- source/libs/function/src/detail/tavgfunction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 9c3b9cf573..8c26886329 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -152,8 +152,8 @@ static void i32VectorSumAVX2(const int32_t* plist, int32_t numOfRows, SAvgRes* p } // let sum up the final results - const int64_t* q = (const int64_t*)∑ - pRes->sum.isum += q[0] + q[1] + q[2] + q[3]; + const int32_t* q = (const int32_t*)∑ + pRes->sum.isum += q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7]; int32_t startIndex = rounds * bitWidth; for (int32_t j = 0; j < remainder; ++j) { From c35f668c17efc567a1e6d25fb13bd7bc0cdfcb91 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 14 Nov 2022 14:37:28 +0800 Subject: [PATCH 10/66] refactor: increase the initial buffer size. --- source/libs/executor/src/executil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index f0db51dc9d..44390ca2e5 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1770,7 +1770,7 @@ STableListInfo* tableListCreate() { goto _error; } - pListInfo->map = taosHashInit(32, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK); + pListInfo->map = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK); if (pListInfo->map == NULL) { goto _error; } From 8b0b351d3915bdeff511d02bfd74e38f99e680e2 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 15 Nov 2022 09:59:20 +0800 Subject: [PATCH 11/66] refactor: do some internal refactor. --- cmake/cmake.define | 4 +- cmake/cmake.platform | 4 +- include/util/thash.h | 2 +- .../libs/function/src/detail/tavgfunction.c | 564 ++++++++++-------- source/util/src/thash.c | 6 +- 5 files changed, 311 insertions(+), 269 deletions(-) diff --git a/cmake/cmake.define b/cmake/cmake.define index 3b6024efc8..e34785cba6 100644 --- a/cmake/cmake.define +++ b/cmake/cmake.define @@ -134,9 +134,9 @@ ELSE () IF("${SIMD_SUPPORT}" MATCHES "true") ADD_DEFINITIONS("-mavx -mavx2") - MESSAGE(STATUS "cpu simd instruction AVX/AVX2 supported") + MESSAGE(STATUS "SIMD instructions (AVX/AVX2) is ACTIVATED") ELSE() - MESSAGE(STATUS "cpu simd instruction AVX/AVX2 NOT supported") + MESSAGE(STATUS "SIMD instruction (AVX/AVX2)is NOT ACTIVATED") ENDIF() ENDIF () diff --git a/cmake/cmake.platform b/cmake/cmake.platform index c3680e0de4..3623925a2b 100644 --- a/cmake/cmake.platform +++ b/cmake/cmake.platform @@ -135,5 +135,5 @@ ENDIF () MESSAGE(STATUS "platform arch:" ${PLATFORM_ARCH_STR}) -MESSAGE("C Compiler ID: ${CMAKE_C_COMPILER_ID}") -MESSAGE("CXX Compiler ID: ${CMAKE_CXX_COMPILER_ID}") +MESSAGE("C Compiler: ${CMAKE_C_COMPILER} (${CMAKE_C_COMPILER_ID}, ${CMAKE_C_COMPILER_VERSION})") +MESSAGE("CXX Compiler: ${CMAKE_CXX_COMPILER} (${CMAKE_C_COMPILER_ID}, ${CMAKE_CXX_COMPILER_VERSION})") diff --git a/include/util/thash.h b/include/util/thash.h index 08caad495d..a04f78a3d1 100644 --- a/include/util/thash.h +++ b/include/util/thash.h @@ -213,7 +213,7 @@ void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp); */ void taosHashSetFreeFp(SHashObj *pHashObj, _hash_free_fn_t fp); -int64_t taosHashGetCompTimes(SHashObj *pHashObj); +//int64_t taosHashGetCompTimes(SHashObj *pHashObj); #ifdef __cplusplus } diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 8c26886329..d7ef73b08e 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -49,11 +49,14 @@ typedef struct SAvgRes { } SAvgRes; static void floatVectorSumAVX(const float* plist, int32_t numOfRows, SAvgRes* pRes) { + const int32_t bitWidth = 256; + #if __AVX__ // find the start position that are aligned to 32bytes address in memory - int32_t bitWidth = 8; - int32_t remainder = numOfRows % bitWidth; - int32_t rounds = numOfRows / bitWidth; + int32_t width = (bitWidth>>3u) / sizeof(float); + + int32_t remainder = numOfRows % width; + int32_t rounds = numOfRows / width; const float* p = plist; @@ -63,14 +66,14 @@ static void floatVectorSumAVX(const float* plist, int32_t numOfRows, SAvgRes* pR for (int32_t i = 0; i < rounds; ++i) { val = _mm256_loadu_ps(p); sum = _mm256_add_ps(sum, val); - p += bitWidth; + p += width; } // let sum up the final results const float* q = (const float*)∑ pRes->sum.dsum += q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7]; - int32_t startIndex = rounds * bitWidth; + int32_t startIndex = rounds * width; for (int32_t j = 0; j < remainder; ++j) { pRes->sum.dsum += plist[j + startIndex]; } @@ -78,11 +81,14 @@ static void floatVectorSumAVX(const float* plist, int32_t numOfRows, SAvgRes* pR } static void doubleVectorSumAVX(const double* plist, int32_t numOfRows, SAvgRes* pRes) { + const int32_t bitWidth = 256; + #if __AVX__ // find the start position that are aligned to 32bytes address in memory - int32_t bitWidth = 4; - int32_t remainder = numOfRows % bitWidth; - int32_t rounds = numOfRows / bitWidth; + int32_t width = (bitWidth>>3u) / sizeof(int64_t); + + int32_t remainder = numOfRows % width; + int32_t rounds = numOfRows / width; const double* p = plist; @@ -92,70 +98,143 @@ static void doubleVectorSumAVX(const double* plist, int32_t numOfRows, SAvgRes* for (int32_t i = 0; i < rounds; ++i) { val = _mm256_loadu_pd(p); sum = _mm256_add_pd(sum, val); - p += bitWidth; + p += width; } // let sum up the final results const double* q = (const double*)∑ pRes->sum.dsum += q[0] + q[1] + q[2] + q[3]; - int32_t startIndex = rounds * bitWidth; + int32_t startIndex = rounds * width; for (int32_t j = 0; j < remainder; ++j) { pRes->sum.dsum += plist[j + startIndex]; } #endif } -static void i8VectorSumAVX2(const int8_t* plist, int32_t numOfRows, SAvgRes* pRes) { +static void i8VectorSumAVX2(const int8_t* plist, int32_t numOfRows, int32_t type, SAvgRes* pRes) { + const int32_t bitWidth = 256; + #if __AVX2__ // find the start position that are aligned to 32bytes address in memory - int32_t bitWidth = 16; - int32_t remainder = numOfRows % bitWidth; - int32_t rounds = numOfRows / bitWidth; + int32_t width = (bitWidth>>3u) / sizeof(int64_t); - const int8_t* p = plist; + int32_t remainder = numOfRows % width; + int32_t rounds = numOfRows / width; __m256i sum = _mm256_setzero_si256(); - for (int32_t i = 0; i < rounds; ++i) { - __m256i val = _mm256_lddqu_si256((__m256i*)p); -// __m256i extVal = _mm256_cvtepi8_epi64(val); - sum = _mm256_add_epi8(sum, val); - p += bitWidth; + if (type == TSDB_DATA_TYPE_TINYINT) { + const int8_t* p = plist; + + for (int32_t i = 0; i < rounds; ++i) { + __m128i val = _mm_lddqu_si128((__m128i*)p); + __m256i extVal = _mm256_cvtepi8_epi64(val); // only four items will be converted into __m256i + sum = _mm256_add_epi64(sum, extVal); + p += width; + } + } else { + const uint8_t* p = (const uint8_t*)plist; + + for(int32_t i = 0; i < rounds; ++i) { + __m128i val = _mm_lddqu_si128((__m128i*)p); + __m256i extVal = _mm256_cvtepu8_epi64(val); // only four items will be converted into __m256i + sum = _mm256_add_epi64(sum, extVal); + p += width; + } } // let sum up the final results - const int8_t* q = (const int8_t*)∑ + const int64_t* q = (const int64_t*)∑ pRes->sum.isum += q[0] + q[1] + q[2] + q[3]; - int32_t startIndex = rounds * bitWidth; + int32_t startIndex = rounds * width; for (int32_t j = 0; j < remainder; ++j) { pRes->sum.isum += plist[j + startIndex]; } #endif } -static void i32VectorSumAVX2(const int32_t* plist, int32_t numOfRows, SAvgRes* pRes) { +static void i16VectorSumAVX2(const int16_t* plist, int32_t numOfRows, int32_t type, SAvgRes* pRes) { + const int32_t bitWidth = 256; + #if __AVX2__ // find the start position that are aligned to 32bytes address in memory - int32_t bitWidth = 8; - int32_t remainder = numOfRows % bitWidth; - int32_t rounds = numOfRows / bitWidth; + int32_t width = (bitWidth>>3u) / sizeof(int64_t); - const int32_t* p = plist; + int32_t remainder = numOfRows % width; + int32_t rounds = numOfRows / width; __m256i sum = _mm256_setzero_si256(); - for (int32_t i = 0; i < rounds; ++i) { - __m256i val = _mm256_lddqu_si256((__m256i*)p); - sum = _mm256_add_epi32(sum, val); - p += bitWidth; + + if (type == TSDB_DATA_TYPE_SMALLINT) { + const int16_t* p = plist; + + for (int32_t i = 0; i < rounds; ++i) { + __m128i val = _mm_lddqu_si128((__m128i*)p); + __m256i extVal = _mm256_cvtepi16_epi64(val); // only four items will be converted into __m256i + sum = _mm256_add_epi64(sum, extVal); + p += width; + } + } else { + const uint8_t* p = (const uint8_t*)plist; + + for(int32_t i = 0; i < rounds; ++i) { + __m128i val = _mm_lddqu_si128((__m128i*)p); + __m256i extVal = _mm256_cvtepu16_epi64(val); // only four items will be converted into __m256i + sum = _mm256_add_epi64(sum, extVal); + p += width; + } } // let sum up the final results - const int32_t* q = (const int32_t*)∑ - pRes->sum.isum += q[0] + q[1] + q[2] + q[3] + q[4] + q[5] + q[6] + q[7]; + const int64_t* q = (const int64_t*)∑ + pRes->sum.isum += q[0] + q[1] + q[2] + q[3]; - int32_t startIndex = rounds * bitWidth; + int32_t startIndex = rounds * width; + for (int32_t j = 0; j < remainder; ++j) { + pRes->sum.isum += plist[j + startIndex]; + } +#endif +} + +static void i32VectorSumAVX2(const int32_t* plist, int32_t numOfRows, int32_t type, SAvgRes* pRes) { + const int32_t bitWidth = 256; + +#if __AVX2__ + // find the start position that are aligned to 32bytes address in memory + int32_t width = (bitWidth>>3u) / sizeof(int64_t); + + int32_t remainder = numOfRows % width; + int32_t rounds = numOfRows / width; + + __m256i sum = _mm256_setzero_si256(); + + if (type == TSDB_DATA_TYPE_INT) { + const int32_t* p = plist; + + for (int32_t i = 0; i < rounds; ++i) { + __m128i val = _mm_lddqu_si128((__m128i*)p); + __m256i extVal = _mm256_cvtepi32_epi64(val); // only four items will be converted into __m256i + sum = _mm256_add_epi64(sum, extVal); + p += width; + } + } else { + const uint32_t* p = (const uint32_t*)plist; + + for(int32_t i = 0; i < rounds; ++i) { + __m128i val = _mm_lddqu_si128((__m128i*)p); + __m256i extVal = _mm256_cvtepu32_epi64(val); // only four items will be converted into __m256i + sum = _mm256_add_epi64(sum, extVal); + p += width; + } + } + + // let sum up the final results + const int64_t* q = (const int64_t*)∑ + pRes->sum.isum += q[0] + q[1] + q[2] + q[3]; + + int32_t startIndex = rounds * width; for (int32_t j = 0; j < remainder; ++j) { pRes->sum.isum += plist[j + startIndex]; } @@ -163,27 +242,30 @@ static void i32VectorSumAVX2(const int32_t* plist, int32_t numOfRows, SAvgRes* p } static void i64VectorSumAVX2(const int64_t* plist, int32_t numOfRows, SAvgRes* pRes) { + const int32_t bitWidth = 256; + #if __AVX2__ // find the start position that are aligned to 32bytes address in memory - int32_t bitWidth = 4; - int32_t remainder = numOfRows % bitWidth; - int32_t rounds = numOfRows / bitWidth; + int32_t width = (bitWidth>>3u) / sizeof(int64_t); - const int64_t* p = plist; + int32_t remainder = numOfRows % width; + int32_t rounds = numOfRows / width; __m256i sum = _mm256_setzero_si256(); + const int64_t* p = plist; + for (int32_t i = 0; i < rounds; ++i) { __m256i val = _mm256_lddqu_si256((__m256i*)p); sum = _mm256_add_epi64(sum, val); - p += bitWidth; + p += width; } // let sum up the final results const int64_t* q = (const int64_t*)∑ pRes->sum.isum += q[0] + q[1] + q[2] + q[3]; - int32_t startIndex = rounds * bitWidth; + int32_t startIndex = rounds * width; for (int32_t j = 0; j < remainder; ++j) { pRes->sum.isum += plist[j + startIndex]; } @@ -256,6 +338,163 @@ static int32_t calculateAvgBySMAInfo(SAvgRes* pRes, int32_t numOfRows, int32_t t return numOfElem; } +static int32_t doAddNumericVector(SColumnInfoData* pCol, int32_t type, SInputColumnInfoData *pInput, SAvgRes* pRes) { + int32_t start = pInput->startRowIndex; + int32_t numOfRows = pInput->numOfRows; + int32_t numOfElems = 0; + + switch (type) { + case TSDB_DATA_TYPE_TINYINT: { + int8_t* plist = (int8_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.isum += plist[i]; + } + + break; + } + + case TSDB_DATA_TYPE_SMALLINT: { + int16_t* plist = (int16_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.isum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_INT: { + int32_t* plist = (int32_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.isum += plist[i]; + } + + break; + } + + case TSDB_DATA_TYPE_BIGINT: { + int64_t* plist = (int64_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.isum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_UTINYINT: { + uint8_t* plist = (uint8_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.usum += plist[i]; + } + + break; + } + + case TSDB_DATA_TYPE_USMALLINT: { + uint16_t* plist = (uint16_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.usum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_UINT: { + uint32_t* plist = (uint32_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.usum += plist[i]; + } + + break; + } + + case TSDB_DATA_TYPE_UBIGINT: { + uint64_t* plist = (uint64_t*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.usum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_FLOAT: { + float* plist = (float*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.dsum += plist[i]; + } + break; + } + + case TSDB_DATA_TYPE_DOUBLE: { + double* plist = (double*)pCol->pData; + for (int32_t i = start; i < numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + numOfElems += 1; + pRes->count += 1; + pRes->sum.dsum += plist[i]; + } + break; + } + + default: + break; + } + + return numOfElems; +} + int32_t avgFunction(SqlFunctionCtx* pCtx) { int32_t numOfElem = 0; const int32_t THRESHOLD_SIZE = 8; @@ -274,8 +513,7 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { int32_t numOfRows = pInput->numOfRows; if (IS_NULL_TYPE(type)) { - numOfElem = 0; - goto _avg_over; + goto _over; } if (pInput->colDataSMAIsSet) { // try to use SMA if available @@ -284,28 +522,31 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { numOfElem = pInput->numOfRows; pAvgRes->count += pInput->numOfRows; - bool simdAvaiable = tsAVXEnable && tsSIMDEnable && (numOfRows > THRESHOLD_SIZE); + bool simdAvailable = tsAVXEnable && tsSIMDEnable && (numOfRows > THRESHOLD_SIZE); switch(type) { + case TSDB_DATA_TYPE_UTINYINT: case TSDB_DATA_TYPE_TINYINT: { - const int8_t* plist = (const int8_t*) pCol->pData; + const int8_t* plist = (const int8_t*) &pCol->pData[start]; // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { - i8VectorSumAVX2(plist, numOfRows, pAvgRes); + if (simdAvailable) { + i8VectorSumAVX2(plist, numOfRows, type, pAvgRes); } else { for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { - pAvgRes->sum.isum += plist[i]; + pAvgRes->sum.usum += plist[i]; } } break; } + + case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_SMALLINT: { - const double* plist = (const double*)pCol->pData; + const int16_t* plist = (const int16_t*)pCol->pData; // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { - doubleVectorSumAVX(plist, numOfRows, pAvgRes); + if (simdAvailable) { + i16VectorSumAVX2(plist, numOfRows, type, pAvgRes); } else { for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { pAvgRes->sum.isum += plist[i]; @@ -313,12 +554,14 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { } break; } + + case TSDB_DATA_TYPE_UINT: case TSDB_DATA_TYPE_INT: { const int32_t* plist = (const int32_t*) pCol->pData; // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { - i32VectorSumAVX2(plist, numOfRows, pAvgRes); + if (simdAvailable) { + i32VectorSumAVX2(plist, numOfRows, type, pAvgRes); } else { for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { pAvgRes->sum.isum += plist[i]; @@ -326,11 +569,13 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { } break; } + + case TSDB_DATA_TYPE_UBIGINT: case TSDB_DATA_TYPE_BIGINT: { const int64_t* plist = (const int64_t*) pCol->pData; // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { + if (simdAvailable) { i64VectorSumAVX2(plist, numOfRows, pAvgRes); } else { for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { @@ -343,7 +588,7 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { const float* plist = (const float*) pCol->pData; // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { + if (simdAvailable) { floatVectorSumAVX(plist, numOfRows, pAvgRes); } else { for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { @@ -353,10 +598,10 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { break; } case TSDB_DATA_TYPE_DOUBLE: { - const double* plist = (const double*) pCol->pData; + const double* plist = (const double*)pCol->pData; // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { + if (simdAvailable) { doubleVectorSumAVX(plist, numOfRows, pAvgRes); } else { for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { @@ -365,217 +610,14 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { } break; } - case TSDB_DATA_TYPE_UTINYINT: { - const double* plist = (const double*) pCol->pData; - - // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { - doubleVectorSumAVX(plist, numOfRows, pAvgRes); - } else { - for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { - pAvgRes->sum.usum += plist[i]; - } - } - break; - } - case TSDB_DATA_TYPE_USMALLINT: { - const double* plist = (const double*) pCol->pData; - - // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { - doubleVectorSumAVX(plist, numOfRows, pAvgRes); - } else { - for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { - pAvgRes->sum.usum += plist[i]; - } - } - break; - } - case TSDB_DATA_TYPE_UINT: { - const double* plist = (const double*) pCol->pData; - - // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { - doubleVectorSumAVX(plist, numOfRows, pAvgRes); - } else { - for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { - pAvgRes->sum.usum += plist[i]; - } - } - break; - } - case TSDB_DATA_TYPE_UBIGINT: { - const double* plist = (const double*) pCol->pData; - - // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (simdAvaiable) { - doubleVectorSumAVX(plist, numOfRows, pAvgRes); - } else { - for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { - pAvgRes->sum.usum += plist[i]; - } - } - break; - } default: ASSERT(0); } } else { - switch (type) { - case TSDB_DATA_TYPE_TINYINT: { - int8_t* plist = (int8_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.isum += plist[i]; - } - - break; - } - - case TSDB_DATA_TYPE_SMALLINT: { - int16_t* plist = (int16_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.isum += plist[i]; - } - break; - } - - case TSDB_DATA_TYPE_INT: { - int32_t* plist = (int32_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.isum += plist[i]; - } - - break; - } - - case TSDB_DATA_TYPE_BIGINT: { - int64_t* plist = (int64_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.isum += plist[i]; - } - break; - } - - case TSDB_DATA_TYPE_UTINYINT: { - uint8_t* plist = (uint8_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.usum += plist[i]; - } - - break; - } - - case TSDB_DATA_TYPE_USMALLINT: { - uint16_t* plist = (uint16_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.usum += plist[i]; - } - break; - } - - case TSDB_DATA_TYPE_UINT: { - uint32_t* plist = (uint32_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.usum += plist[i]; - } - - break; - } - - case TSDB_DATA_TYPE_UBIGINT: { - uint64_t* plist = (uint64_t*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.usum += plist[i]; - } - break; - } - - case TSDB_DATA_TYPE_FLOAT: { -#if 1 - numOfElem = handleFloatCols(pCol, pInput, pAvgRes); -#else - float* plist = (float*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.dsum += plist[i]; - } -#endif - break; - } - - case TSDB_DATA_TYPE_DOUBLE: { - double* plist = (double*)pCol->pData; - for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElem += 1; - pAvgRes->count += 1; - pAvgRes->sum.dsum += plist[i]; - } - break; - } - - default: - break; - } + numOfElem = doAddNumericVector(pCol, type, pInput, pAvgRes); } -_avg_over: +_over: // data in the check operation are all null, not output SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1); return TSDB_CODE_SUCCESS; diff --git a/source/util/src/thash.c b/source/util/src/thash.c index c3d4668e11..c542aa81a8 100644 --- a/source/util/src/thash.c +++ b/source/util/src/thash.c @@ -67,7 +67,7 @@ struct SHashObj { bool enableUpdate; // enable update SArray *pMemBlock; // memory block allocated for SHashEntry _hash_before_fn_t callbackFp; // function invoked before return the value to caller - int64_t compTimes; +// int64_t compTimes; }; /* @@ -147,7 +147,7 @@ static FORCE_INLINE SHashNode *doSearchInEntryList(SHashObj *pHashObj, SHashEntr uint32_t hashVal) { SHashNode *pNode = pe->next; while (pNode) { - atomic_add_fetch_64(&pHashObj->compTimes, 1); +// atomic_add_fetch_64(&pHashObj->compTimes, 1); if ((pNode->keyLen == keyLen) && ((*(pHashObj->equalFp))(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0) && pNode->removed == 0) { assert(pNode->hashVal == hashVal); @@ -889,4 +889,4 @@ void *taosHashAcquire(SHashObj *pHashObj, const void *key, size_t keyLen) { void taosHashRelease(SHashObj *pHashObj, void *p) { taosHashCancelIterate(pHashObj, p); } -int64_t taosHashGetCompTimes(SHashObj *pHashObj) { return atomic_load_64(&pHashObj->compTimes); } +//int64_t taosHashGetCompTimes(SHashObj *pHashObj) { return atomic_load_64(&pHashObj->compTimes); } From ba5244d1b66a2ac301fe73e26cf7a10be6ad4939 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 15 Nov 2022 16:06:29 +0800 Subject: [PATCH 12/66] refactor: add tag filter results cache. --- source/dnode/vnode/src/inc/meta.h | 1 + source/dnode/vnode/src/meta/metaCache.c | 89 +++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/source/dnode/vnode/src/inc/meta.h b/source/dnode/vnode/src/inc/meta.h index 9e2fe4aaf0..17fdaa9815 100644 --- a/source/dnode/vnode/src/inc/meta.h +++ b/source/dnode/vnode/src/inc/meta.h @@ -70,6 +70,7 @@ int32_t metaCacheDrop(SMeta* pMeta, int64_t uid); int32_t metaStatsCacheUpsert(SMeta* pMeta, SMetaStbStats* pInfo); int32_t metaStatsCacheDrop(SMeta* pMeta, int64_t uid); int32_t metaStatsCacheGet(SMeta* pMeta, int64_t uid, SMetaStbStats* pInfo); +int32_t metaUidFilterCacheGet(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, LRUHandle** pHandle); struct SMeta { TdThreadRwlock lock; diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 356aa78c22..98bd9626e7 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -31,6 +31,12 @@ typedef struct SMetaStbStatsEntry { SMetaStbStats info; } SMetaStbStatsEntry; +typedef struct STagFilterResEntry { + uint64_t suid; // uid for super table + SList* pList; // the linked list of md5 digest, extracted from the serialized tag query condition + uint32_t qTimes;// queried times for current super table +} STagFilterResEntry; + struct SMetaCache { // child, normal, super, table entry cache struct SEntryCache { @@ -47,6 +53,10 @@ struct SMetaCache { } sStbStatsCache; // query cache + struct STagFilterResCache { + SHashObj* pTableEntry; + SLRUCache* pUidResCache; + } sTagFilterResCache; }; static void entryCacheClose(SMeta* pMeta) { @@ -388,3 +398,82 @@ int32_t metaStatsCacheGet(SMeta* pMeta, int64_t uid, SMetaStbStats* pInfo) { return code; } + +int32_t metaUidFilterCacheGet(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, LRUHandle** pHandle) { + // generate the composed key for LRU cache + char* p = taosMemoryMalloc(keyLen + sizeof(uint64_t)); + *(uint64_t*) p = suid; + memcpy(p + sizeof(suid), pKey, keyLen); + + int32_t len = keyLen + sizeof(uint64_t); + *pHandle = taosLRUCacheLookup(pMeta->pCache->sTagFilterResCache.pUidResCache, p, len); + if (*pHandle == NULL) { + taosMemoryFree(p); + return TSDB_CODE_SUCCESS; + } else { // do some book mark work after acquiring the filter result from cache + STagFilterResEntry* pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); + ASSERT(pEntry != NULL); + + pEntry->qTimes += 1; + + // check if scanning all items are necessary or not + if (pEntry->qTimes > 5000 && TD_DLIST_NELES(pEntry->pList) > 10) { + SArray* pList = taosArrayInit(64, POINTER_BYTES); + + SListIter iter = {0}; + tdListInitIter(pEntry->pList, &iter, TD_LIST_FORWARD); + + SListNode* pNode = NULL; + while ((pNode = tdListNext(&iter)) != NULL) { + memcpy(p + sizeof(suid), pNode->data, keyLen); + + // check whether it is existed in LRU cache, and remove it from linked list if not. + void* pRes = taosLRUCacheLookup(pMeta->pCache->sTagFilterResCache.pUidResCache, p, len); + if (pRes == NULL) { // remove the item in the linked list + taosArrayPush(pList, &pNode); + } + } + + // remove the keys, of which query uid lists have been replaced already. + size_t s = taosArrayGetSize(pList); + for(int32_t i = 0; i < s; ++i) { + SListNode** p1 = taosArrayGet(pList, i); + tdListPopNode(pEntry->pList, *p1); + } + } + + taosMemoryFree(p); + } + + return TSDB_CODE_SUCCESS; +} + +// check both the payload size and selectivity ratio +int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload) { + + return TSDB_CODE_SUCCESS; +} + +// remove the lru cache that are expired due to the tags value update, or creating, or dropping, of child tables +int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) { + STagFilterResEntry* pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); + if (pEntry == NULL) { + return TSDB_CODE_SUCCESS; + } + + int32_t keyLen = sizeof(uint64_t) + 128; + char* p = taosMemoryMalloc(keyLen); + *(uint64_t*)p = pEntry->suid; + + SListIter iter = {0}; + tdListInitIter(pEntry->pList, &iter, TD_LIST_FORWARD); + + SListNode* pNode = NULL; + while ((pNode = tdListNext(&iter)) != NULL) { + memcpy(p + sizeof(suid), pNode->data, 128); + taosLRUCacheErase(pMeta->pCache->sTagFilterResCache.pUidResCache, p, keyLen); + } + + return TSDB_CODE_SUCCESS; +} + From 7d00b7a6c4f19b6a21562b95dfbca67e132be622 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 14:23:12 +0800 Subject: [PATCH 13/66] refactor: add tag filter cache. --- include/common/tglobal.h | 2 + include/util/tlist.h | 2 +- source/common/src/tglobal.c | 3 + source/dnode/vnode/inc/vnode.h | 3 + source/dnode/vnode/src/meta/metaCache.c | 99 +++++++++++++++++++------ source/libs/executor/src/executil.c | 50 ++++++++++--- source/util/src/tlist.c | 2 +- 7 files changed, 127 insertions(+), 34 deletions(-) diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 681d1beb79..48886584d2 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -44,6 +44,8 @@ extern int32_t tsCompatibleModel; extern bool tsPrintAuth; extern int64_t tsTickPerMin[3]; extern int32_t tsCountAlwaysReturnValue; +extern float tsSelectivityRatio; +extern int32_t tsTagFilterResCacheSize; // queue & threads extern int32_t tsNumOfRpcThreads; diff --git a/include/util/tlist.h b/include/util/tlist.h index 1954bda145..3dbdb72f9e 100644 --- a/include/util/tlist.h +++ b/include/util/tlist.h @@ -225,7 +225,7 @@ void *tdListFree(SList *list); void tdListPrependNode(SList *list, SListNode *node); void tdListAppendNode(SList *list, SListNode *node); int32_t tdListPrepend(SList *list, void *data); -int32_t tdListAppend(SList *list, void *data); +int32_t tdListAppend(SList *list, const void *data); SListNode *tdListPopHead(SList *list); SListNode *tdListPopTail(SList *list); SListNode *tdListGetHead(SList *list); diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 50b2c976fd..41be026a4c 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -119,6 +119,9 @@ int32_t tsMinIntervalTime = 1; // maximum memory allowed to be allocated for a single csv load (in MB) int32_t tsMaxMemUsedByInsert = 1024; +float tsSelectivityRatio = 1.0; +int32_t tsTagFilterResCacheSize = 4096; + // the maximum allowed query buffer size during query processing for each data node. // -1 no limit (default) // 0 no query allowed, queries are disabled diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 0b58959822..d09724ffc4 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -108,6 +108,9 @@ int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName); int metaGetTableUidByName(void *meta, char *tbName, uint64_t *uid); int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType); bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid); +int32_t metaGetCachedTableUidList(SMeta *pMeta, tb_uid_t suid, const uint8_t *key, int32_t keyLen, SArray *pList, bool* acquired); +int32_t metaUidFilterCachePut(SMeta *pMeta, uint64_t suid, const void *pKey, int32_t keyLen, void *pPayload, + int32_t payloadLen, double selectivityRatio); typedef struct SMetaFltParam { tb_uid_t suid; diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 98bd9626e7..e448c6e7c6 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -33,7 +33,7 @@ typedef struct SMetaStbStatsEntry { typedef struct STagFilterResEntry { uint64_t suid; // uid for super table - SList* pList; // the linked list of md5 digest, extracted from the serialized tag query condition + SList list; // the linked list of md5 digest, extracted from the serialized tag query condition uint32_t qTimes;// queried times for current super table } STagFilterResEntry; @@ -56,6 +56,7 @@ struct SMetaCache { struct STagFilterResCache { SHashObj* pTableEntry; SLRUCache* pUidResCache; + uint64_t keyBuf[3]; } sTagFilterResCache; }; @@ -119,9 +120,19 @@ int32_t metaCacheOpen(SMeta* pMeta) { goto _err2; } - pMeta->pCache = pCache; + pCache->sTagFilterResCache.pUidResCache = taosLRUCacheInit(5*1024*1024, -1, 0.5); + if (pCache->sTagFilterResCache.pUidResCache == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err2; + } -_exit: + pCache->sTagFilterResCache.pTableEntry = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), false, HASH_NO_LOCK); + if (pCache->sTagFilterResCache.pTableEntry == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err2; + } + + pMeta->pCache = pCache; return code; _err2: @@ -129,7 +140,6 @@ _err2: _err: taosMemoryFree(pCache); - metaError("vgId:%d, meta open cache failed since %s", TD_VID(pMeta->pVnode), tstrerror(code)); return code; } @@ -138,6 +148,11 @@ void metaCacheClose(SMeta* pMeta) { if (pMeta->pCache) { entryCacheClose(pMeta); statsCacheClose(pMeta); + + taosHashCleanup(pMeta->pCache->sTagFilterResCache.pTableEntry); + taosLRUCacheCleanup(pMeta->pCache->sTagFilterResCache.pUidResCache); + + taosMemoryFree(pMeta->pCache->sTagFilterResCache.keyBuf); taosMemoryFree(pMeta->pCache); pMeta->pCache = NULL; } @@ -399,38 +414,48 @@ int32_t metaStatsCacheGet(SMeta* pMeta, int64_t uid, SMetaStbStats* pInfo) { return code; } -int32_t metaUidFilterCacheGet(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, LRUHandle** pHandle) { +int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pKey, int32_t keyLen, SArray* pList1, bool* acquireRes) { + uint64_t* pBuf = pMeta->pCache->sTagFilterResCache.keyBuf; + // generate the composed key for LRU cache - char* p = taosMemoryMalloc(keyLen + sizeof(uint64_t)); - *(uint64_t*) p = suid; - memcpy(p + sizeof(suid), pKey, keyLen); + SLRUCache* pCache = pMeta->pCache->sTagFilterResCache.pUidResCache; + + pBuf[0] = suid; + memcpy(&pBuf[1], pKey, keyLen); int32_t len = keyLen + sizeof(uint64_t); - *pHandle = taosLRUCacheLookup(pMeta->pCache->sTagFilterResCache.pUidResCache, p, len); - if (*pHandle == NULL) { - taosMemoryFree(p); + LRUHandle *pHandle = taosLRUCacheLookup(pCache, pBuf, len); + if (pHandle == NULL) { + *acquireRes = 0; return TSDB_CODE_SUCCESS; } else { // do some book mark work after acquiring the filter result from cache STagFilterResEntry* pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); ASSERT(pEntry != NULL); + *acquireRes = 1; + + const char* p = taosLRUCacheValue(pMeta->pCache->sTagFilterResCache.pUidResCache, pHandle); + int32_t size = *(int32_t*) p; + taosArrayAddBatch(pList1, p + sizeof(int32_t), size); pEntry->qTimes += 1; // check if scanning all items are necessary or not - if (pEntry->qTimes > 5000 && TD_DLIST_NELES(pEntry->pList) > 10) { + if (pEntry->qTimes >= 5000 && TD_DLIST_NELES(&pEntry->list) > 10) { SArray* pList = taosArrayInit(64, POINTER_BYTES); SListIter iter = {0}; - tdListInitIter(pEntry->pList, &iter, TD_LIST_FORWARD); + tdListInitIter(&pEntry->list, &iter, TD_LIST_FORWARD); SListNode* pNode = NULL; while ((pNode = tdListNext(&iter)) != NULL) { - memcpy(p + sizeof(suid), pNode->data, keyLen); + memcpy(pBuf + sizeof(suid), pNode->data, keyLen); // check whether it is existed in LRU cache, and remove it from linked list if not. - void* pRes = taosLRUCacheLookup(pMeta->pCache->sTagFilterResCache.pUidResCache, p, len); + LRUHandle* pRes = taosLRUCacheLookup(pCache, pBuf, len); if (pRes == NULL) { // remove the item in the linked list taosArrayPush(pList, &pNode); + } else { + taosLRUCacheRelease(pCache, pRes, false); } } @@ -438,19 +463,49 @@ int32_t metaUidFilterCacheGet(SMeta* pMeta, uint64_t suid, const void* pKey, int size_t s = taosArrayGetSize(pList); for(int32_t i = 0; i < s; ++i) { SListNode** p1 = taosArrayGet(pList, i); - tdListPopNode(pEntry->pList, *p1); + tdListPopNode(&pEntry->list, *p1); } - } - taosMemoryFree(p); + pEntry->qTimes = 0; // reset the query times + } } return TSDB_CODE_SUCCESS; } // check both the payload size and selectivity ratio -int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload) { +int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload, int32_t payloadLen, double selectivityRatio) { + if (selectivityRatio > tsSelectivityRatio) { + return TSDB_CODE_SUCCESS; + } + if (payloadLen > tsTagFilterResCacheSize) { + return TSDB_CODE_SUCCESS; + } + + SLRUCache* pCache = pMeta->pCache->sTagFilterResCache.pUidResCache; + SHashObj* pTableEntry = pMeta->pCache->sTagFilterResCache.pTableEntry; + + void* pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); + if (pEntry == NULL) { + STagFilterResEntry* p = taosMemoryMalloc(sizeof(STagFilterResEntry)); + p->qTimes = 0; + tdListInit(&p->list, keyLen); + taosHashPut(pTableEntry, &suid, sizeof(uint64_t), pEntry, POINTER_BYTES); + + pEntry = &p; + } + + tdListAppend(&(*(STagFilterResEntry**)pEntry)->list, pKey); + + uint64_t* pBuf = pMeta->pCache->sTagFilterResCache.keyBuf; + pBuf[0] = suid; + + memcpy(&pBuf[1], pKey, keyLen); + ASSERT(sizeof(uint64_t) + keyLen == 24); + + // add to cache. + taosLRUCacheInsert(pCache, pBuf, sizeof(uint64_t) + keyLen, pPayload, payloadLen, NULL, NULL, TAOS_LRU_PRIORITY_LOW); return TSDB_CODE_SUCCESS; } @@ -466,7 +521,7 @@ int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) { *(uint64_t*)p = pEntry->suid; SListIter iter = {0}; - tdListInitIter(pEntry->pList, &iter, TD_LIST_FORWARD); + tdListInitIter(&pEntry->list, &iter, TD_LIST_FORWARD); SListNode* pNode = NULL; while ((pNode = tdListNext(&iter)) != NULL) { @@ -474,6 +529,8 @@ int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) { taosLRUCacheErase(pMeta->pCache->sTagFilterResCache.pUidResCache, p, keyLen); } + pEntry->qTimes = 0; + tdListEmpty(&pEntry->list); + return TSDB_CODE_SUCCESS; } - diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 44390ca2e5..8604fd4db9 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -973,19 +973,47 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, SArray* res = taosArrayInit(8, sizeof(uint64_t)); if (pScanNode->tableType == TSDB_SUPER_TABLE) { - if (pTagIndexCond) { - SIndexMetaArg metaArg = { - .metaEx = metaHandle, .idx = tsdbGetIdx(metaHandle), .ivtIdx = tsdbGetIvtIdx(metaHandle), .suid = tableUid}; + // try to retrieve the result from meta cache + // generate the cache key + T_MD5_CTX context = {0}; - // int64_t stt = taosGetTimestampUs(); - SIdxFltStatus status = SFLT_NOT_INDEX; - code = doFilterTag(pTagIndexCond, &metaArg, res, &status); - if (code != 0 || status == SFLT_NOT_INDEX) { - qError("failed to get tableIds from index, reason:%s, suid:%" PRIu64, tstrerror(code), tableUid); - code = TDB_CODE_SUCCESS; + if (pTagIndexCond) { + char* payload = NULL; + int32_t len = 0; + nodesNodeToMsg(pTagCond, &payload, &len); + + tMD5Init(&context); + tMD5Update(&context, (uint8_t*)payload, (uint32_t)len); + tMD5Final(&context); + } + + bool acquired = false; + metaGetCachedTableUidList(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), res, &acquired); + if (!acquired) { + // failed to find the result in the cache, let try to calculate the results + if (pTagIndexCond) { + SIndexMetaArg metaArg = { + .metaEx = metaHandle, .idx = tsdbGetIdx(metaHandle), .ivtIdx = tsdbGetIvtIdx(metaHandle), .suid = tableUid}; + + SIdxFltStatus status = SFLT_NOT_INDEX; + code = doFilterTag(pTagIndexCond, &metaArg, res, &status); + if (code != 0 || status == SFLT_NOT_INDEX) { + qError("failed to get tableIds from index, reason:%s, suid:%" PRIu64, tstrerror(code), tableUid); + code = TDB_CODE_SUCCESS; + } + } else if (!pTagCond) { + vnodeGetCtbIdList(pVnode, pScanNode->suid, res); } - } else if (!pTagCond) { - vnodeGetCtbIdList(pVnode, pScanNode->suid, res); + + // let's add the filter results into meta-cache + size_t numOfTables = taosArrayGetSize(res); + size_t size = numOfTables * sizeof(uint64_t) + sizeof(int32_t); + char* pPayload = taosMemoryMalloc(size); + *(int32_t*)pPayload = numOfTables; + memcpy(pPayload + sizeof(int32_t), taosArrayGet(res, 0), numOfTables * sizeof(uint64_t)); + + metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, + size, 1); } } else { // Create one table group. if (metaIsTableExist(metaHandle, tableUid)) { diff --git a/source/util/src/tlist.c b/source/util/src/tlist.c index b1c0188051..1b12ea0cdd 100644 --- a/source/util/src/tlist.c +++ b/source/util/src/tlist.c @@ -60,7 +60,7 @@ int32_t tdListPrepend(SList *list, void *data) { return 0; } -int32_t tdListAppend(SList *list, void *data) { +int32_t tdListAppend(SList *list, const void *data) { SListNode *node = (SListNode *)taosMemoryCalloc(1, sizeof(SListNode) + list->eleSize); if (node == NULL) return -1; From 2320c0d2bd2863a0a08845893545e6e30e9db3d6 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 14:40:39 +0800 Subject: [PATCH 14/66] refactor: update some logs. --- source/libs/executor/src/executil.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 8604fd4db9..17e41b3a08 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1942,13 +1942,15 @@ int32_t createScanTableListInfo(SScanPhysiNode* pScanNode, SNodeList* pGroupTags return code; } + int32_t numOfTables = taosArrayGetSize(pTableListInfo->pTableList); ASSERT(pTableListInfo->numOfOuputGroups == 1); int64_t st1 = taosGetTimestampUs(); pTaskInfo->cost.extractListTime = (st1 - st) / 1000.0; - qDebug("extract queried table list completed, elapsed time:%.2f ms %s", pTaskInfo->cost.extractListTime, idStr); + qDebug("extract queried table list completed, %d tables, elapsed time:%.2f ms %s", numOfTables, + pTaskInfo->cost.extractListTime, idStr); - if (taosArrayGetSize(pTableListInfo->pTableList) == 0) { + if (numOfTables == 0) { qDebug("no table qualified for query, %s" PRIx64, idStr); return TSDB_CODE_SUCCESS; } From 47a7664e2c8fe67aee5ed371703e78a96e803fe9 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 14:52:38 +0800 Subject: [PATCH 15/66] refactor: add some logs. --- source/common/src/tglobal.c | 2 +- source/dnode/vnode/src/meta/metaCache.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 41be026a4c..0db3e99863 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -120,7 +120,7 @@ int32_t tsMinIntervalTime = 1; int32_t tsMaxMemUsedByInsert = 1024; float tsSelectivityRatio = 1.0; -int32_t tsTagFilterResCacheSize = 4096; +int32_t tsTagFilterResCacheSize = 1024*10; // the maximum allowed query buffer size during query processing for each data node. // -1 no limit (default) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index e448c6e7c6..17c99e34bf 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -476,10 +476,16 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK // check both the payload size and selectivity ratio int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload, int32_t payloadLen, double selectivityRatio) { if (selectivityRatio > tsSelectivityRatio) { + metaDebug("vgId:%d, suid:%" PRIu64 + " failed to add to uid list cache, due to selectivity ratio %.2f less than threshold %.2f", + TD_VID(pMeta->pVnode), suid, selectivityRatio, tsSelectivityRatio); return TSDB_CODE_SUCCESS; } if (payloadLen > tsTagFilterResCacheSize) { + metaDebug("vgId:%d, suid:%" PRIu64 + " failed to add to uid list cache, due to payload length %d greater than threshold %d", + TD_VID(pMeta->pVnode), suid, payloadLen, tsTagFilterResCacheSize); return TSDB_CODE_SUCCESS; } @@ -506,6 +512,9 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int // add to cache. taosLRUCacheInsert(pCache, pBuf, sizeof(uint64_t) + keyLen, pPayload, payloadLen, NULL, NULL, TAOS_LRU_PRIORITY_LOW); + metaDebug("vgId:%d, suid:%"PRIu64" list cache added into cache, total:%d, tables:%d", TD_VID(pMeta->pVnode), + suid, (int32_t) taosLRUCacheGetUsage(pCache), taosHashGetSize(pTableEntry)); + return TSDB_CODE_SUCCESS; } From 23da7bc5e98b26708cae61f5b246babcb3d79169 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 15:13:38 +0800 Subject: [PATCH 16/66] refactor: add some logs. --- source/libs/executor/src/executil.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 17e41b3a08..28afa7a41e 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1014,6 +1014,8 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, size, 1); + } else { + qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t) taosArrayGetSize(res)) } } else { // Create one table group. if (metaIsTableExist(metaHandle, tableUid)) { From 82f22e407d04013d686219122a5836d49d856975 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 15:13:54 +0800 Subject: [PATCH 17/66] refactor: do some internal refactor. --- source/libs/executor/src/executil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 28afa7a41e..7de93780b3 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1015,7 +1015,7 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, size, 1); } else { - qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t) taosArrayGetSize(res)) + qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t) taosArrayGetSize(res)); } } else { // Create one table group. if (metaIsTableExist(metaHandle, tableUid)) { From fade0507fa103313e00ff745749cd4015d4434cd Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 15:17:13 +0800 Subject: [PATCH 18/66] refactor: do some internal refactor. --- source/libs/executor/src/executil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 7de93780b3..68f4319bf4 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1064,7 +1064,7 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, return TSDB_CODE_OUT_OF_MEMORY; } - qDebug("tagfilter get uid:%" PRIu64 "", info.uid); + qTrace("tagfilter get uid:%" PRIu64 "", info.uid); } taosArrayDestroy(res); From 2ee5fa87d0441f35f646a04ba0801c7257682486 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 15:19:15 +0800 Subject: [PATCH 19/66] refactor: do some internal refactor. --- source/libs/executor/src/executil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 68f4319bf4..cebed9c3f4 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -988,7 +988,7 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, } bool acquired = false; - metaGetCachedTableUidList(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), res, &acquired); +// metaGetCachedTableUidList(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), res, &acquired); if (!acquired) { // failed to find the result in the cache, let try to calculate the results if (pTagIndexCond) { From 819235dd3b735bbaac6be2620b2f838c5a27ca6d Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 15:21:33 +0800 Subject: [PATCH 20/66] refactor: do some internal refactor. --- source/libs/executor/src/executil.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index cebed9c3f4..b774b48726 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1006,6 +1006,7 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, } // let's add the filter results into meta-cache +#if 0 size_t numOfTables = taosArrayGetSize(res); size_t size = numOfTables * sizeof(uint64_t) + sizeof(int32_t); char* pPayload = taosMemoryMalloc(size); @@ -1014,6 +1015,8 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, size, 1); +#endif + } else { qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t) taosArrayGetSize(res)); } From 42f8abcc0e0f2ec7281345ea797002a2400fb8f8 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 15:24:30 +0800 Subject: [PATCH 21/66] refactor: do some internal refactor. --- source/libs/executor/src/executil.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index b774b48726..68f4319bf4 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -988,7 +988,7 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, } bool acquired = false; -// metaGetCachedTableUidList(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), res, &acquired); + metaGetCachedTableUidList(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), res, &acquired); if (!acquired) { // failed to find the result in the cache, let try to calculate the results if (pTagIndexCond) { @@ -1006,7 +1006,6 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, } // let's add the filter results into meta-cache -#if 0 size_t numOfTables = taosArrayGetSize(res); size_t size = numOfTables * sizeof(uint64_t) + sizeof(int32_t); char* pPayload = taosMemoryMalloc(size); @@ -1015,8 +1014,6 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, size, 1); -#endif - } else { qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t) taosArrayGetSize(res)); } From a36c24eb1ceac64c8b9cfdfb812345d726544c72 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 16 Nov 2022 15:47:24 +0800 Subject: [PATCH 22/66] fix(query): remove invalid free. --- source/dnode/vnode/src/meta/metaCache.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 17c99e34bf..22fc49efac 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -151,8 +151,6 @@ void metaCacheClose(SMeta* pMeta) { taosHashCleanup(pMeta->pCache->sTagFilterResCache.pTableEntry); taosLRUCacheCleanup(pMeta->pCache->sTagFilterResCache.pUidResCache); - - taosMemoryFree(pMeta->pCache->sTagFilterResCache.keyBuf); taosMemoryFree(pMeta->pCache); pMeta->pCache = NULL; } From ec7ad45b2b8d2ffb8b2f7aa931db8c5a47b85b18 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 17 Nov 2022 17:37:45 +0800 Subject: [PATCH 23/66] fix(query): fix a typo. --- source/libs/function/src/detail/tavgfunction.c | 6 ++---- source/libs/qworker/src/qwUtil.c | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index d7ef73b08e..744927d6c8 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -31,7 +31,7 @@ do { \ T* plist = (T*)pCol->pData; \ for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { \ - if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { \ + if (colDataIsNull_f(pCol->nullbitmap, i)) { \ continue; \ } \ \ @@ -661,8 +661,6 @@ int32_t avgInvertFunction(SqlFunctionCtx* pCtx) { // Only the pre-computing information loaded and actual data does not loaded SInputColumnInfoData* pInput = &pCtx->input; - int32_t type = pInput->pData[0]->info.type; - SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); // computing based on the true data block @@ -671,7 +669,7 @@ int32_t avgInvertFunction(SqlFunctionCtx* pCtx) { int32_t start = pInput->startRowIndex; int32_t numOfRows = pInput->numOfRows; - switch (type) { + switch (pCol->info.type) { case TSDB_DATA_TYPE_TINYINT: { LIST_AVG_N(pAvgRes->sum.isum, int8_t); break; diff --git a/source/libs/qworker/src/qwUtil.c b/source/libs/qworker/src/qwUtil.c index e9ded9b269..80a0a6e0ae 100644 --- a/source/libs/qworker/src/qwUtil.c +++ b/source/libs/qworker/src/qwUtil.c @@ -275,7 +275,7 @@ void qwFreeTaskHandle(qTaskInfo_t *taskHandle) { qTaskInfo_t otaskHandle = atomic_load_ptr(taskHandle); if (otaskHandle && atomic_val_compare_exchange_ptr(taskHandle, otaskHandle, NULL)) { qDestroyTask(otaskHandle); - qDebug("task handle destryed"); + qDebug("task handle destroyed"); } } @@ -306,7 +306,7 @@ void qwFreeTaskCtx(SQWTaskCtx *ctx) { if (ctx->sinkHandle) { dsDestroyDataSinker(ctx->sinkHandle); ctx->sinkHandle = NULL; - qDebug("sink handle destryed"); + qDebug("sink handle destroyed"); } } From f26a492c678a6ff79fc33bf27a31374184878592 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 18 Nov 2022 14:00:27 +0800 Subject: [PATCH 24/66] fix(query): check result size before store it. --- source/libs/executor/src/executil.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 68f4319bf4..6ee2dce59b 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1010,7 +1010,10 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, size_t size = numOfTables * sizeof(uint64_t) + sizeof(int32_t); char* pPayload = taosMemoryMalloc(size); *(int32_t*)pPayload = numOfTables; - memcpy(pPayload + sizeof(int32_t), taosArrayGet(res, 0), numOfTables * sizeof(uint64_t)); + + if (numOfTables > 0) { + memcpy(pPayload + sizeof(int32_t), taosArrayGet(res, 0), numOfTables * sizeof(uint64_t)); + } metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, size, 1); From 3ca38c41a704a4ad325caff1ef5837b809cbb95d Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Fri, 18 Nov 2022 14:38:44 +0800 Subject: [PATCH 25/66] meta: use meta cache to get uid's version instead of fetching from tdb --- source/dnode/vnode/src/meta/metaQuery.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 32dd427d09..89eb0525ea 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -152,7 +152,8 @@ bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid) { } int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) { - SMeta *pMeta = pReader->pMeta; + SMeta *pMeta = pReader->pMeta; + /* int64_t version1; // query uid.idx @@ -163,6 +164,14 @@ int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) { version1 = ((SUidIdxVal *)pReader->pBuf)[0].version; return metaGetTableEntryByVersion(pReader, version1, uid); + */ + 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); } int metaGetTableEntryByName(SMetaReader *pReader, const char *name) { @@ -1126,7 +1135,7 @@ int32_t metaFilterTableName(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) { valid = tdbTbcGet(pCursor->pCur, (const void **)pEntryKey, &nEntryKey, (const void **)&pEntryVal, &nEntryVal); if (valid < 0) break; - char *pTableKey = (char *)pEntryKey; + char *pTableKey = (char *)pEntryKey; cmp = (*param->filterFunc)(pTableKey, pName, pCursor->type); if (cmp == 0) { tb_uid_t tuid = *(tb_uid_t *)pEntryVal; From 71de2f056b92afb9b61c3c869d22561a525500a3 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 18 Nov 2022 14:53:39 +0800 Subject: [PATCH 26/66] fix(query): fix invalid write/read. --- source/dnode/vnode/src/meta/metaCache.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 22fc49efac..8647250191 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -427,7 +427,7 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK *acquireRes = 0; return TSDB_CODE_SUCCESS; } else { // do some book mark work after acquiring the filter result from cache - STagFilterResEntry* pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); + STagFilterResEntry** pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); ASSERT(pEntry != NULL); *acquireRes = 1; @@ -435,14 +435,14 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK int32_t size = *(int32_t*) p; taosArrayAddBatch(pList1, p + sizeof(int32_t), size); - pEntry->qTimes += 1; + (*pEntry)->qTimes += 1; // check if scanning all items are necessary or not - if (pEntry->qTimes >= 5000 && TD_DLIST_NELES(&pEntry->list) > 10) { + if ((*pEntry)->qTimes >= 5000 && TD_DLIST_NELES(&(*pEntry)->list) > 10) { SArray* pList = taosArrayInit(64, POINTER_BYTES); SListIter iter = {0}; - tdListInitIter(&pEntry->list, &iter, TD_LIST_FORWARD); + tdListInitIter(&(*pEntry)->list, &iter, TD_LIST_FORWARD); SListNode* pNode = NULL; while ((pNode = tdListNext(&iter)) != NULL) { @@ -461,10 +461,10 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK size_t s = taosArrayGetSize(pList); for(int32_t i = 0; i < s; ++i) { SListNode** p1 = taosArrayGet(pList, i); - tdListPopNode(&pEntry->list, *p1); + tdListPopNode(&(*pEntry)->list, *p1); } - pEntry->qTimes = 0; // reset the query times + (*pEntry)->qTimes = 0; // reset the query times } } From 35b9dc6b6cc0c0829ae092ac37311caad1a37ade Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Fri, 18 Nov 2022 14:38:44 +0800 Subject: [PATCH 27/66] meta: use meta cache to get uid's version instead of fetching from tdb --- source/dnode/vnode/src/inc/vnodeInt.h | 2 +- source/dnode/vnode/src/meta/metaQuery.c | 30 +++++++++++++++++++--- source/dnode/vnode/src/meta/metaTable.c | 2 +- source/dnode/vnode/src/tsdb/tsdbMemTable.c | 6 ++--- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index ac9fabf052..f229b3b127 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -142,7 +142,7 @@ typedef struct SMetaInfo { int64_t version; int32_t skmVer; } SMetaInfo; -int32_t metaGetInfo(SMeta* pMeta, int64_t uid, SMetaInfo* pInfo); +int32_t metaGetInfo(SMeta* pMeta, int64_t uid, SMetaInfo* pInfo, SMetaReader* pReader); typedef struct { int64_t uid; diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 32dd427d09..f58b97eeb8 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -152,7 +152,8 @@ bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid) { } int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) { - SMeta *pMeta = pReader->pMeta; + SMeta *pMeta = pReader->pMeta; + /* int64_t version1; // query uid.idx @@ -163,6 +164,15 @@ int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) { version1 = ((SUidIdxVal *)pReader->pBuf)[0].version; return metaGetTableEntryByVersion(pReader, version1, uid); + */ + + SMetaInfo info; + if (metaGetInfo(pMeta, uid, &info, pReader) == TSDB_CODE_NOT_FOUND) { + terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST; + return -1; + } + + return metaGetTableEntryByVersion(pReader, info.version, uid); } int metaGetTableEntryByName(SMetaReader *pReader, const char *name) { @@ -614,7 +624,7 @@ int32_t metaGetTbTSchemaEx(SMeta *pMeta, tb_uid_t suid, tb_uid_t uid, int32_t sv SSkmDbKey skmDbKey; if (sver <= 0) { SMetaInfo info; - if (metaGetInfo(pMeta, suid ? suid : uid, &info) == 0) { + if (metaGetInfo(pMeta, suid ? suid : uid, &info, NULL) == 0) { sver = info.skmVer; } else { TBC *pSkmDbC = NULL; @@ -1126,7 +1136,7 @@ int32_t metaFilterTableName(SMeta *pMeta, SMetaFltParam *param, SArray *pUids) { valid = tdbTbcGet(pCursor->pCur, (const void **)pEntryKey, &nEntryKey, (const void **)&pEntryVal, &nEntryVal); if (valid < 0) break; - char *pTableKey = (char *)pEntryKey; + char *pTableKey = (char *)pEntryKey; cmp = (*param->filterFunc)(pTableKey, pName, pCursor->type); if (cmp == 0) { tb_uid_t tuid = *(tb_uid_t *)pEntryVal; @@ -1379,10 +1389,11 @@ int32_t metaGetTableTags(SMeta *pMeta, uint64_t suid, SArray *uidList, SHashObj int32_t metaCacheGet(SMeta *pMeta, int64_t uid, SMetaInfo *pInfo); -int32_t metaGetInfo(SMeta *pMeta, int64_t uid, SMetaInfo *pInfo) { +int32_t metaGetInfo(SMeta *pMeta, int64_t uid, SMetaInfo *pInfo, SMetaReader *pReader) { int32_t code = 0; void *pData = NULL; int nData = 0; + int lock = 0; metaRLock(pMeta); @@ -1407,11 +1418,22 @@ int32_t metaGetInfo(SMeta *pMeta, int64_t uid, SMetaInfo *pInfo) { pInfo->version = ((SUidIdxVal *)pData)->version; pInfo->skmVer = ((SUidIdxVal *)pData)->skmVer; + if (pReader != NULL) { + lock = !(pReader->flags & META_READER_NOLOCK); + if (lock) { + metaULock(pReader->pMeta); + // metaReaderReleaseLock(pReader); + } + } // upsert the cache metaWLock(pMeta); metaCacheUpsert(pMeta, pInfo); metaULock(pMeta); + if (lock) { + metaRLock(pReader->pMeta); + } + _exit: tdbFree(pData); return code; diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index 6dadce80ca..bb0cfe183d 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -207,7 +207,7 @@ int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) { tb_uid_t uid = *(tb_uid_t *)pData; tdbFree(pData); SMetaInfo info; - metaGetInfo(pMeta, uid, &info); + metaGetInfo(pMeta, uid, &info, NULL); if (info.uid == info.suid) { return 0; } else { diff --git a/source/dnode/vnode/src/tsdb/tsdbMemTable.c b/source/dnode/vnode/src/tsdb/tsdbMemTable.c index c663e2b526..ca3c283d05 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMemTable.c +++ b/source/dnode/vnode/src/tsdb/tsdbMemTable.c @@ -104,7 +104,7 @@ int32_t tsdbInsertTableData(STsdb *pTsdb, int64_t version, SSubmitMsgIter *pMsgI tb_uid_t uid = pMsgIter->uid; SMetaInfo info; - code = metaGetInfo(pTsdb->pVnode->pMeta, uid, &info); + code = metaGetInfo(pTsdb->pVnode->pMeta, uid, &info, NULL); if (code) { code = TSDB_CODE_TDB_TABLE_NOT_EXIST; goto _err; @@ -114,7 +114,7 @@ int32_t tsdbInsertTableData(STsdb *pTsdb, int64_t version, SSubmitMsgIter *pMsgI goto _err; } if (info.suid) { - metaGetInfo(pTsdb->pVnode->pMeta, info.suid, &info); + metaGetInfo(pTsdb->pVnode->pMeta, info.suid, &info, NULL); } if (pMsgIter->sversion != info.skmVer) { tsdbError("vgId:%d, req sver:%d, skmVer:%d suid:%" PRId64 " uid:%" PRId64, TD_VID(pTsdb->pVnode), @@ -153,7 +153,7 @@ int32_t tsdbDeleteTableData(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid // check if table exists SMetaInfo info; - code = metaGetInfo(pTsdb->pVnode->pMeta, uid, &info); + code = metaGetInfo(pTsdb->pVnode->pMeta, uid, &info, NULL); if (code) { code = TSDB_CODE_TDB_TABLE_NOT_EXIST; goto _err; From d3452f6630538068be2541a4c38e8a932327e40a Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 18 Nov 2022 17:38:31 +0800 Subject: [PATCH 28/66] fix(query): fix error. --- source/dnode/vnode/src/meta/metaCache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 8647250191..05b6209c56 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -495,9 +495,9 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int STagFilterResEntry* p = taosMemoryMalloc(sizeof(STagFilterResEntry)); p->qTimes = 0; tdListInit(&p->list, keyLen); - taosHashPut(pTableEntry, &suid, sizeof(uint64_t), pEntry, POINTER_BYTES); pEntry = &p; + taosHashPut(pTableEntry, &suid, sizeof(uint64_t), pEntry, POINTER_BYTES); } tdListAppend(&(*(STagFilterResEntry**)pEntry)->list, pKey); From 1e25eac4c7257f00006fcaf2f866039b2faf5f7c Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sun, 20 Nov 2022 23:11:12 +0800 Subject: [PATCH 29/66] refactor: do some internal refactor. --- source/libs/function/src/detail/tminmax.c | 577 +++++++++++++++------- 1 file changed, 396 insertions(+), 181 deletions(-) diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index d239315e0e..ed297e2b66 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -20,68 +20,59 @@ #include "tglobal.h" static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool isMinFunc) { - int32_t v = 0; + int32_t v = 0; + const int32_t bitWidth = 256; + const int32_t* p = pData; + + int32_t width = (bitWidth>>3u) / sizeof(int32_t); + int32_t remain = numOfRows % width; + int32_t rounds = numOfRows / width; #if __AVX2__ - int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); - int32_t bitWidth = 8; - - int32_t remain = (numOfRows - startElem) % bitWidth; - int32_t rounds = (numOfRows - startElem) / bitWidth; - const int32_t* p = &pData[startElem]; - __m256i next; __m256i initialVal = _mm256_loadu_si256((__m256i*)p); - p += bitWidth; + p += width; if (!isMinFunc) { // max function for (int32_t i = 0; i < rounds; ++i) { next = _mm256_lddqu_si256((__m256i*)p); initialVal = _mm256_max_epi32(initialVal, next); - p += bitWidth; + p += width; } // let sum up the final results const int32_t* q = (const int32_t*)&initialVal; - v = TMAX(q[0], q[1]); - v = TMAX(v, q[2]); - v = TMAX(v, q[3]); - v = TMAX(v, q[4]); - v = TMAX(v, q[5]); - v = TMAX(v, q[6]); - v = TMAX(v, q[7]); + for (int32_t k = 1; k < width; ++k) { + v = TMAX(v, q[k]); + } // calculate the front and the reminder items in array list - startElem += rounds * bitWidth; + int32_t start = rounds * width; for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + startElem]) { - v = p[j + startElem]; + if (v < p[j + start]) { + v = p[j + start]; } } } else { // min function for (int32_t i = 0; i < rounds; ++i) { next = _mm256_lddqu_si256((__m256i*)p); initialVal = _mm256_min_epi32(initialVal, next); - p += bitWidth; + p += width; } // let sum up the final results const int32_t* q = (const int32_t*)&initialVal; - v = TMIN(q[0], q[1]); - v = TMIN(v, q[2]); - v = TMIN(v, q[3]); - v = TMIN(v, q[4]); - v = TMIN(v, q[5]); - v = TMIN(v, q[6]); - v = TMIN(v, q[7]); + for (int32_t k = 1; k < width; ++k) { + v = TMIN(v, q[k]); + } // calculate the front and the remainder items in array list - startElem += rounds * bitWidth; + int32_t start = rounds * width; for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + startElem]) { - v = p[j + startElem]; + if (v > p[j + start]) { + v = p[j + start]; } } } @@ -92,69 +83,59 @@ static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool is static float floatVectorCmpAVX(const float* pData, int32_t numOfRows, bool isMinFunc) { float v = 0; + const int32_t bitWidth = 256; + const float* p = pData; + + int32_t width = (bitWidth>>3u) / sizeof(float); + int32_t remain = numOfRows % width; + int32_t rounds = numOfRows / width; #if __AVX__ - int32_t startElem = 0;//((uint64_t)plist) & ((1<<8u)-1); - int32_t i = 0; - - int32_t bitWidth = 8; - - int32_t remain = (numOfRows - startElem) % bitWidth; - int32_t rounds = (numOfRows - startElem) / bitWidth; - const float* p = &pData[startElem]; __m256 next; __m256 initialVal = _mm256_loadu_ps(p); - p += bitWidth; + p += width; if (!isMinFunc) { // max function - for (; i < rounds; ++i) { + for (int32_t i = 1; i < rounds; ++i) { next = _mm256_loadu_ps(p); initialVal = _mm256_max_ps(initialVal, next); - p += bitWidth; + p += width; } // let sum up the final results const float* q = (const float*)&initialVal; - v = TMAX(q[0], q[1]); - v = TMAX(v, q[2]); - v = TMAX(v, q[3]); - v = TMAX(v, q[4]); - v = TMAX(v, q[5]); - v = TMAX(v, q[6]); - v = TMAX(v, q[7]); + for (int32_t k = 1; k < width; ++k) { + v = TMAX(v, q[k]); + } // calculate the front and the reminder items in array list - startElem += rounds * bitWidth; + int32_t start = rounds * width; for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + startElem]) { - v = p[j + startElem]; + if (v < p[j + width]) { + v = p[j + width]; } } } else { // min function - for (; i < rounds; ++i) { + for (int32_t i = 1; i < rounds; ++i) { next = _mm256_loadu_ps(p); initialVal = _mm256_min_ps(initialVal, next); - p += bitWidth; + p += width; } // let sum up the final results const float* q = (const float*)&initialVal; - v = TMIN(q[0], q[1]); - v = TMIN(v, q[2]); - v = TMIN(v, q[3]); - v = TMIN(v, q[4]); - v = TMIN(v, q[5]); - v = TMIN(v, q[6]); - v = TMIN(v, q[7]); + for (int32_t k = 1; k < width; ++k) { + v = TMIN(v, q[k]); + } // calculate the front and the reminder items in array list - startElem += rounds * bitWidth; + int32_t start = rounds * bitWidth; for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + startElem]) { - v = p[j + startElem]; + if (v > p[j + start]) { + v = p[j + start]; } } } @@ -163,6 +144,195 @@ static float floatVectorCmpAVX(const float* pData, int32_t numOfRows, bool isMin return v; } +static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMinFunc) { + int8_t v = 0; + const int32_t bitWidth = 256; + const int8_t* p = pData; + + int32_t width = (bitWidth>>3u) / sizeof(int8_t); + int32_t remain = numOfRows % width; + int32_t rounds = numOfRows / width; + +#if __AVX2__ + __m256i next; + __m256i initialVal = _mm256_loadu_si256((__m256i*)p); + p += width; + + if (!isMinFunc) { // max function + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initialVal = _mm256_max_epi8(initialVal, next); + p += width; + } + + // let sum up the final results + const int8_t* q = (const int8_t*)&initialVal; + v = TMAX(q[0], q[1]); + for (int32_t k = 1; k < width; ++k) { + v = TMAX(v, q[k]); + } + + // calculate the front and the reminder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + start]) { + v = p[j + start]; + } + } + } else { // min function + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initialVal = _mm256_min_epi8(initialVal, next); + p += width; + } + + // let sum up the final results + const int8_t* q = (const int8_t*)&initialVal; + + v = TMIN(q[0], q[1]); + for(int32_t k = 1; k < width; ++k) { + v = TMIN(v, q[k]); + } + + // calculate the front and the remainder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + start]) { + v = p[j + start]; + } + } + } +#endif + + return v; +} + +static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool isMinFunc) { + int16_t v = 0; + const int32_t bitWidth = 256; + const int16_t* p = pData; + + int32_t width = (bitWidth>>3u) / sizeof(int16_t); + int32_t remain = numOfRows % width; + int32_t rounds = numOfRows / width; + +#if __AVX2__ + __m256i next; + __m256i initialVal = _mm256_loadu_si256((__m256i*)p); + p += width; + + if (!isMinFunc) { // max function + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initialVal = _mm256_max_epi16(initialVal, next); + p += width; + } + + // let sum up the final results + const int16_t* q = (const int16_t*)&initialVal; + + v = TMAX(q[0], q[1]); + for(int32_t k = 1; k < width; ++k) { + v = TMAX(v, q[k]); + } + + // calculate the front and the reminder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + start]) { + v = p[j + start]; + } + } + } else { // min function + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initialVal = _mm256_min_epi16(initialVal, next); + p += width; + } + + // let sum up the final results + const int16_t* q = (const int16_t*)&initialVal; + + v = TMIN(q[0], q[1]); + for(int32_t k = 1; k < width; ++k) { + v = TMIN(v, q[k]); + } + + // calculate the front and the remainder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + start]) { + v = p[j + start]; + } + } + } +#endif + + return v; +} + +//static int64_t i64VectorCmpAVX2(const int64_t* pData, int32_t numOfRows, bool isMinFunc) { +// int64_t v = 0; +// const int32_t bitWidth = 256; +// const int64_t* p = pData; +// +// int32_t width = (bitWidth>>3u) / sizeof(int64_t); +// int32_t remain = numOfRows % width; +// int32_t rounds = numOfRows / width; +// +//#if __AVX2__ +// __m256i next; +// __m256i initialVal = _mm256_loadu_si256((__m256i*)p); +// p += width; +// +// if (!isMinFunc) { // max function +// for (int32_t i = 0; i < rounds; ++i) { +// next = _mm256_lddqu_si256((__m256i*)p); +// initialVal = _mm256_max_epi64(initialVal, next); +// p += width; +// } +// +// // let sum up the final results +// const int64_t* q = (const int64_t*)&initialVal; +// v = TMAX(q[0], q[1]); +// for(int32_t k = 1; k < width; ++k) { +// v = TMAX(v, q[k]); +// } +// +// // calculate the front and the reminder items in array list +// int32_t start = rounds * width; +// for (int32_t j = 0; j < remain; ++j) { +// if (v < p[j + start]) { +// v = p[j + start]; +// } +// } +// } else { // min function +// for (int32_t i = 0; i < rounds; ++i) { +// next = _mm256_lddqu_si256((__m256i*)p); +// initialVal = _mm256_min_epi64(initialVal, next); +// p += width; +// } +// +// // let sum up the final results +// const int64_t* q = (const int64_t*)&initialVal; +// v = TMIN(q[0], q[1]); +// for(int32_t k = 1; k < width; ++k) { +// v = TMIN(v, q[k]); +// } +// +// // calculate the front and the remainder items in array list +// int32_t start = rounds * width; +// for (int32_t j = 0; j < remain; ++j) { +// if (v > p[j + start]) { +// v = p[j + start]; +// } +// } +// } +//#endif +// +// return v; +//} + static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, bool isMinFunc) { int32_t* pData = (int32_t*)pCol->pData; @@ -170,56 +340,56 @@ static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numO int32_t numOfElems = 0; if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { - if (isMinFunc) { // min - for (int32_t i = start; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - - numOfElems += 1; - } - } else { // max function - for (int32_t i = start; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - - numOfElems += 1; + int32_t i = start; + while (i < (start + numOfRows)) { + if (!colDataIsNull_f(pCol->nullbitmap, i)) { + break; } + i += 1; } - } else { // not has null value + + if ((i < (start + numOfRows)) && (!pBuf->assign)) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + numOfElems += 1; + } + + if (isMinFunc) { // min + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } else { // max function + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } + } else { // not has null value // AVX2 version to speedup the loop if (tsAVX2Enable && tsSIMDEnable) { *val = i32VectorCmpAVX2(pData, numOfRows, isMinFunc); @@ -257,56 +427,55 @@ static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numO int32_t numOfElems = 0; if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { + int32_t i = start; + while (i < (start + numOfRows)) { + if (!colDataIsNull_f(pCol->nullbitmap, i)) { + break; + } + i += 1; + } + + if ((i < (start + numOfRows)) && (!pBuf->assign)) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + numOfElems += 1; + } + if (isMinFunc) { // min - for (int32_t i = start; i < start + numOfRows; ++i) { + for (; i < start + numOfRows; ++i) { if (colDataIsNull_f(pCol->nullbitmap, i)) { continue; } - if (!pBuf->assign) { + if (*val > pData[i]) { *val = pData[i]; if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); } } - numOfElems += 1; } } else { // max function - for (int32_t i = start; i < start + numOfRows; ++i) { + for (; i < start + numOfRows; ++i) { if (colDataIsNull_f(pCol->nullbitmap, i)) { continue; } - if (!pBuf->assign) { + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (*val < pData[i]) { *val = pData[i]; if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); } } - numOfElems += 1; } } - } else { // not has null value + } else { // not has null value // AVX version to speedup the loop if (tsAVXEnable && tsSIMDEnable) { *val = (double) floatVectorCmpAVX(pData, numOfRows, isMinFunc); @@ -337,6 +506,93 @@ static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numO return numOfElems; } +static int32_t handleInt8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, + SMinmaxResInfo* pBuf, bool isMinFunc) { + int8_t* pData = (int8_t*)pCol->pData; + int8_t* val = (int8_t*)&pBuf->v; + + int32_t numOfElems = 0; + if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { + int32_t i = start; + while (i < (start + numOfRows)) { + if (!colDataIsNull_f(pCol->nullbitmap, i)) { + break; + } + i += 1; + } + + if ((i < (start + numOfRows)) && (!pBuf->assign)) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + numOfElems += 1; + } + + if (isMinFunc) { // min + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } else { // max function + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } + } else { // not has null value + // AVX2 version to speedup the loop + if (tsAVX2Enable && tsSIMDEnable) { + *val = i8VectorCmpAVX2(pData, numOfRows, isMinFunc); + } else { + if (!pBuf->assign) { + *val = pData[0]; + pBuf->assign = true; + } + + if (isMinFunc) { // min + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val > pData[i]) { + *val = pData[i]; + } + } + } else { // max + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val < pData[i]) { + *val = pData[i]; + } + } + } + } + + numOfElems = numOfRows; + } + + return numOfElems; +} + static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, const char* tval) { // the data is loaded, not only the block SMA value for (int32_t i = start; i < num + start; ++i) { @@ -463,42 +719,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) { if (type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_BOOL) { - int8_t* pData = (int8_t*)pCol->pData; - int8_t* val = (int8_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } + numOfElems = handleInt8Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); } else if (type == TSDB_DATA_TYPE_SMALLINT) { int16_t* pData = (int16_t*)pCol->pData; int16_t* val = (int16_t*)&pBuf->v; @@ -537,9 +758,6 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { numOfElems += 1; } } else if (type == TSDB_DATA_TYPE_INT) { - int32_t* pData = (int32_t*)pCol->pData; - int32_t* val = (int32_t*)&pBuf->v; - numOfElems = handleInt32Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); #if 0 for (int32_t i = start; i < start + numOfRows; ++i) { @@ -803,9 +1021,6 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { numOfElems += 1; } } else if (type == TSDB_DATA_TYPE_FLOAT) { - float* pData = (float*)pCol->pData; - float* val = (float*)&pBuf->v; - numOfElems = handleFloatCol(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); #if 0 for (int32_t i = start; i < start + numOfRows; ++i) { From 8fee089aaf30f30b36de81409d057dbf48a4f4bf Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Mon, 21 Nov 2022 22:48:25 +0800 Subject: [PATCH 30/66] refactor: do some internal refactor. --- source/dnode/vnode/src/tsdb/tsdbRead.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 6ea270e5f4..e919593f90 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -693,6 +693,7 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN tMapDataReset(&pScanInfo->mapData); tsdbReadDataBlk(pReader->pFileReader, pBlockIdx, &pScanInfo->mapData); + taosArrayEnsureCap(pScanInfo->pBlockList, pScanInfo->mapData.nItem); sizeInDisk += pScanInfo->mapData.nData; for (int32_t j = 0; j < pScanInfo->mapData.nItem; ++j) { From 56edf57c121f97efc6bccacfe1dfc21c679ad4cd Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 22 Nov 2022 09:52:53 +0800 Subject: [PATCH 31/66] refactor: do some internal refactor. --- source/dnode/vnode/src/tsdb/tsdbRead.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index e919593f90..04f2a14bce 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -38,7 +38,7 @@ typedef struct { typedef struct SBlockIndex { int32_t ordinalIndex; int64_t inFileOffset; - STimeWindow window; + STimeWindow window; // todo replace it with overlap flag. } SBlockIndex; typedef struct STableBlockScanInfo { @@ -1440,6 +1440,7 @@ static int32_t setFileBlockActiveInBlockIter(SDataBlockIter* pBlockIter, int32_t return TSDB_CODE_SUCCESS; } +// todo: this attribute could be acquired during extractin the global ordered block list. static bool overlapWithNeighborBlock(SDataBlk* pBlock, SBlockIndex* pNeighborBlockIndex, int32_t order) { // it is the last block in current file, no chance to overlap with neighbor blocks. if (ASCENDING_TRAVERSE(order)) { From 390709e3c856817f595e101e7c7d3b31a9423554 Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Tue, 22 Nov 2022 10:10:23 +0800 Subject: [PATCH 32/66] add interface --- include/util/tarray.h | 9 +++++++++ source/dnode/vnode/src/inc/tsdb.h | 2 ++ source/dnode/vnode/src/tsdb/tsdbUtil.c | 24 ++++++++++++++++++++++++ source/util/src/tarray.c | 11 +++++++++++ 4 files changed, 46 insertions(+) diff --git a/include/util/tarray.h b/include/util/tarray.h index e95568197b..0632db3103 100644 --- a/include/util/tarray.h +++ b/include/util/tarray.h @@ -104,6 +104,15 @@ static FORCE_INLINE void* taosArrayPush(SArray* pArray, const void* pData) { return taosArrayAddBatch(pArray, pData, 1); } +/** + * @brief reserve the capacity of the array + * + * @param pArray + * @param num + * @return void* the start position of the reserved memory + */ +void* taosArrayReserve(SArray* pArray, int32_t num); + /** * * @param pArray diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h index a5257b32c0..6552a76590 100644 --- a/source/dnode/vnode/src/inc/tsdb.h +++ b/source/dnode/vnode/src/inc/tsdb.h @@ -186,6 +186,8 @@ int32_t tMapDataSearch(SMapData *pMapData, void *pSearchItem, int32_t (*tGetItem int32_t (*tItemCmprFn)(const void *, const void *), void *pItem); int32_t tPutMapData(uint8_t *p, SMapData *pMapData); int32_t tGetMapData(uint8_t *p, SMapData *pMapData); +int32_t tMapDataToArray(SMapData *pMapData, int32_t itemSize, int32_t (*tGetItemFn)(uint8_t *, void *), + SArray **ppArray); // other int32_t tsdbKeyFid(TSKEY key, int32_t minutes, int8_t precision); void tsdbFidKeyRange(int32_t fid, int32_t minutes, int8_t precision, TSKEY *minKey, TSKEY *maxKey); diff --git a/source/dnode/vnode/src/tsdb/tsdbUtil.c b/source/dnode/vnode/src/tsdb/tsdbUtil.c index 52b74aea3f..0902a9bd73 100644 --- a/source/dnode/vnode/src/tsdb/tsdbUtil.c +++ b/source/dnode/vnode/src/tsdb/tsdbUtil.c @@ -101,6 +101,30 @@ void tMapDataGetItemByIdx(SMapData *pMapData, int32_t idx, void *pItem, int32_t tGetItemFn(pMapData->pData + pMapData->aOffset[idx], pItem); } +int32_t tMapDataToArray(SMapData *pMapData, int32_t itemSize, int32_t (*tGetItemFn)(uint8_t *, void *), + SArray **ppArray) { + int32_t code = 0; + + SArray *pArray = taosArrayInit(pMapData->nItem, itemSize); + if (pArray == NULL) { + code = TSDB_CODE_TDB_OUT_OF_MEMORY; + goto _exit; + } + + for (int32_t i = 0; i < pMapData->nItem; i++) { + tMapDataGetItemByIdx(pMapData, i, taosArrayReserve(pArray, 1), tGetItemFn); + } + +_exit: + if (code) { + *ppArray = NULL; + if (pArray) taosArrayDestroy(pArray); + } else { + *ppArray = pArray; + } + return code; +} + int32_t tPutMapData(uint8_t *p, SMapData *pMapData) { int32_t n = 0; diff --git a/source/util/src/tarray.c b/source/util/src/tarray.c index 95065972a3..5703d8f8f4 100644 --- a/source/util/src/tarray.c +++ b/source/util/src/tarray.c @@ -181,6 +181,17 @@ void* taosArrayAddAll(SArray* pArray, const SArray* pInput) { } } +void* taosArrayReserve(SArray* pArray, int32_t num) { + if (taosArrayEnsureCap(pArray, pArray->size + num) != 0) { + return NULL; + } + + void* dst = TARRAY_GET_ELEM(pArray, pArray->size); + pArray->size += num; + + return dst; +} + void* taosArrayPop(SArray* pArray) { assert(pArray != NULL); From 0af77e6ae23c69a87f776d6a8efaa69bb4b2fa72 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 22 Nov 2022 12:43:00 +0800 Subject: [PATCH 33/66] refactor: do some internal refactor. --- source/dnode/vnode/src/tsdb/tsdbRead.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 04f2a14bce..64cdba5648 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -695,33 +695,38 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN tsdbReadDataBlk(pReader->pFileReader, pBlockIdx, &pScanInfo->mapData); taosArrayEnsureCap(pScanInfo->pBlockList, pScanInfo->mapData.nItem); + SArray* pList = NULL; + tMapDataToArray(&pScanInfo->mapData, sizeof(SDataBlk), tGetDataBlk, &pList); sizeInDisk += pScanInfo->mapData.nData; for (int32_t j = 0; j < pScanInfo->mapData.nItem; ++j) { - SDataBlk block = {0}; - tMapDataGetItemByIdx(&pScanInfo->mapData, j, &block, tGetDataBlk); +// SDataBlk block = {0}; +// tMapDataGetItemByIdx(&pScanInfo->mapData, j, &block, tGetDataBlk); + SDataBlk* pBlock = taosArrayGet(pList, j); // 1. time range check - if (block.minKey.ts > pReader->window.ekey || block.maxKey.ts < pReader->window.skey) { + if (pBlock->minKey.ts > pReader->window.ekey || pBlock->maxKey.ts < pReader->window.skey) { continue; } // 2. version range check - if (block.minVer > pReader->verRange.maxVer || block.maxVer < pReader->verRange.minVer) { + if (pBlock->minVer > pReader->verRange.maxVer || pBlock->maxVer < pReader->verRange.minVer) { continue; } - SBlockIndex bIndex = {.ordinalIndex = j, .inFileOffset = block.aSubBlock->offset}; - bIndex.window = (STimeWindow){.skey = block.minKey.ts, .ekey = block.maxKey.ts}; + SBlockIndex bIndex = {.ordinalIndex = j, .inFileOffset = pBlock->aSubBlock->offset}; + bIndex.window = (STimeWindow){.skey = pBlock->minKey.ts, .ekey = pBlock->maxKey.ts}; void* p = taosArrayPush(pScanInfo->pBlockList, &bIndex); if (p == NULL) { tMapDataClear(&pScanInfo->mapData); + taosArrayDestroy(pList); return TSDB_CODE_OUT_OF_MEMORY; } pBlockNum->numOfBlocks += 1; } + taosArrayDestroy(pList); if (pScanInfo->pBlockList != NULL && taosArrayGetSize(pScanInfo->pBlockList) > 0) { numOfQTable += 1; } From 93ad9e9d3d05383c7f353cc0a5b8abbf73219ce2 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 22 Nov 2022 14:29:30 +0800 Subject: [PATCH 34/66] refactor: do some internal refactor. --- source/dnode/vnode/src/tsdb/tsdbRead.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 64cdba5648..5b9ab2dac0 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -695,13 +695,14 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN tsdbReadDataBlk(pReader->pFileReader, pBlockIdx, &pScanInfo->mapData); taosArrayEnsureCap(pScanInfo->pBlockList, pScanInfo->mapData.nItem); - SArray* pList = NULL; - tMapDataToArray(&pScanInfo->mapData, sizeof(SDataBlk), tGetDataBlk, &pList); + SDataBlk* p = taosMemoryMalloc(sizeof(SDataBlk) * pScanInfo->mapData.nItem); + for (int32_t k = 0; k < pScanInfo->mapData.nItem; k++) { + tMapDataGetItemByIdx(&pScanInfo->mapData, i, &p[k], tGetDataBlk); + } + sizeInDisk += pScanInfo->mapData.nData; for (int32_t j = 0; j < pScanInfo->mapData.nItem; ++j) { -// SDataBlk block = {0}; -// tMapDataGetItemByIdx(&pScanInfo->mapData, j, &block, tGetDataBlk); - SDataBlk* pBlock = taosArrayGet(pList, j); + SDataBlk* pBlock = &p[j]; // 1. time range check if (pBlock->minKey.ts > pReader->window.ekey || pBlock->maxKey.ts < pReader->window.skey) { @@ -719,14 +720,14 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN void* p = taosArrayPush(pScanInfo->pBlockList, &bIndex); if (p == NULL) { tMapDataClear(&pScanInfo->mapData); - taosArrayDestroy(pList); + taosMemoryFree(p); return TSDB_CODE_OUT_OF_MEMORY; } pBlockNum->numOfBlocks += 1; } - taosArrayDestroy(pList); + taosMemoryFree(p); if (pScanInfo->pBlockList != NULL && taosArrayGetSize(pScanInfo->pBlockList) > 0) { numOfQTable += 1; } @@ -742,6 +743,7 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN numOfTables, pBlockNum->numOfBlocks, numOfQTable, pBlockNum->numOfLastFiles, sizeInDisk / 1000.0, el, pReader->idStr); + pReader->cost.numOfBlocks += total; pReader->cost.headFileLoadTime += el; From 4d206fd3b29cc2af9a755185df999e3090806034 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 22 Nov 2022 14:59:17 +0800 Subject: [PATCH 35/66] refactor: do some internal refactor. --- source/dnode/vnode/src/tsdb/tsdbRead.c | 29 ++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 5b9ab2dac0..d64c20ae9e 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -695,39 +695,42 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN tsdbReadDataBlk(pReader->pFileReader, pBlockIdx, &pScanInfo->mapData); taosArrayEnsureCap(pScanInfo->pBlockList, pScanInfo->mapData.nItem); - SDataBlk* p = taosMemoryMalloc(sizeof(SDataBlk) * pScanInfo->mapData.nItem); - for (int32_t k = 0; k < pScanInfo->mapData.nItem; k++) { - tMapDataGetItemByIdx(&pScanInfo->mapData, i, &p[k], tGetDataBlk); - } +// SDataBlk* p = taosMemoryMalloc(sizeof(SDataBlk) * pScanInfo->mapData.nItem); +// for (int32_t k = 0; k < pScanInfo->mapData.nItem; k++) { +// tMapDataGetItemByIdx(&pScanInfo->mapData, k, &p[k], tGetDataBlk); +// } sizeInDisk += pScanInfo->mapData.nData; + SDataBlk block = {0}; + for (int32_t j = 0; j < pScanInfo->mapData.nItem; ++j) { - SDataBlk* pBlock = &p[j]; + tGetDataBlk(pScanInfo->mapData.pData + pScanInfo->mapData.aOffset[j], &block); +// SDataBlk* pBlock = &p[j]; // 1. time range check - if (pBlock->minKey.ts > pReader->window.ekey || pBlock->maxKey.ts < pReader->window.skey) { + if (block.minKey.ts > pReader->window.ekey || block.maxKey.ts < pReader->window.skey) { continue; } // 2. version range check - if (pBlock->minVer > pReader->verRange.maxVer || pBlock->maxVer < pReader->verRange.minVer) { + if (block.minVer > pReader->verRange.maxVer || block.maxVer < pReader->verRange.minVer) { continue; } - SBlockIndex bIndex = {.ordinalIndex = j, .inFileOffset = pBlock->aSubBlock->offset}; - bIndex.window = (STimeWindow){.skey = pBlock->minKey.ts, .ekey = pBlock->maxKey.ts}; + SBlockIndex bIndex = {.ordinalIndex = j, .inFileOffset = block.aSubBlock->offset}; + bIndex.window = (STimeWindow){.skey = block.minKey.ts, .ekey = block.maxKey.ts}; - void* p = taosArrayPush(pScanInfo->pBlockList, &bIndex); - if (p == NULL) { + void* p1 = taosArrayPush(pScanInfo->pBlockList, &bIndex); + if (p1 == NULL) { tMapDataClear(&pScanInfo->mapData); - taosMemoryFree(p); +// taosMemoryFree(p); return TSDB_CODE_OUT_OF_MEMORY; } pBlockNum->numOfBlocks += 1; } - taosMemoryFree(p); +// taosMemoryFree(p); if (pScanInfo->pBlockList != NULL && taosArrayGetSize(pScanInfo->pBlockList) > 0) { numOfQTable += 1; } From b70a616a2d22e8d07fc906bd805658b2be508e87 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 22 Nov 2022 15:27:33 +0800 Subject: [PATCH 36/66] refactor: do some internal refactor. --- source/dnode/vnode/src/tsdb/tsdbRead.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index d64c20ae9e..c19e39e7e1 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -695,17 +695,11 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN tsdbReadDataBlk(pReader->pFileReader, pBlockIdx, &pScanInfo->mapData); taosArrayEnsureCap(pScanInfo->pBlockList, pScanInfo->mapData.nItem); -// SDataBlk* p = taosMemoryMalloc(sizeof(SDataBlk) * pScanInfo->mapData.nItem); -// for (int32_t k = 0; k < pScanInfo->mapData.nItem; k++) { -// tMapDataGetItemByIdx(&pScanInfo->mapData, k, &p[k], tGetDataBlk); -// } - sizeInDisk += pScanInfo->mapData.nData; - SDataBlk block = {0}; + SDataBlk block = {0}; for (int32_t j = 0; j < pScanInfo->mapData.nItem; ++j) { tGetDataBlk(pScanInfo->mapData.pData + pScanInfo->mapData.aOffset[j], &block); -// SDataBlk* pBlock = &p[j]; // 1. time range check if (block.minKey.ts > pReader->window.ekey || block.maxKey.ts < pReader->window.skey) { @@ -723,14 +717,12 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, SBlockN void* p1 = taosArrayPush(pScanInfo->pBlockList, &bIndex); if (p1 == NULL) { tMapDataClear(&pScanInfo->mapData); -// taosMemoryFree(p); return TSDB_CODE_OUT_OF_MEMORY; } pBlockNum->numOfBlocks += 1; } -// taosMemoryFree(p); if (pScanInfo->pBlockList != NULL && taosArrayGetSize(pScanInfo->pBlockList) > 0) { numOfQTable += 1; } From 611ab8b39407b5b7beababce8f4ef481bc433eeb Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 23 Nov 2022 21:52:51 +0800 Subject: [PATCH 37/66] refactor: make sure the memory is aligned to 32 bytes. --- include/os/osMemory.h | 1 + source/common/src/tdatablock.c | 13 ++++- source/libs/function/src/detail/tminmax.c | 61 ----------------------- source/os/src/osMemory.c | 8 +++ 4 files changed, 21 insertions(+), 62 deletions(-) diff --git a/include/os/osMemory.h b/include/os/osMemory.h index 14d53a7a06..4681ff6674 100644 --- a/include/os/osMemory.h +++ b/include/os/osMemory.h @@ -37,6 +37,7 @@ void taosMemoryFree(void *ptr); int64_t taosMemorySize(void *ptr); void taosPrintBackTrace(); void taosMemoryTrim(int32_t size); +void *taosMemoryMallocAlign(uint32_t alignment, int64_t size); #define taosMemoryFreeClear(ptr) \ do { \ diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index f5dba35440..c79910978a 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -19,6 +19,8 @@ #include "tlog.h" #include "tname.h" +#define MALLOC_ALIGN_BYTES 32 + int32_t colDataGetLength(const SColumnInfoData* pColumnInfoData, int32_t numOfRows) { ASSERT(pColumnInfoData != NULL); if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) { @@ -1163,6 +1165,7 @@ static int32_t doEnsureCapacity(SColumnInfoData* pColumn, const SDataBlockInfo* pColumn->varmeta.offset = (int32_t*)tmp; memset(&pColumn->varmeta.offset[existedRows], 0, sizeof(int32_t) * (numOfRows - existedRows)); } else { + // prepare for the null bitmap char* tmp = taosMemoryRealloc(pColumn->nullbitmap, BitmapLen(numOfRows)); if (tmp == NULL) { return TSDB_CODE_OUT_OF_MEMORY; @@ -1173,11 +1176,19 @@ static int32_t doEnsureCapacity(SColumnInfoData* pColumn, const SDataBlockInfo* memset(&pColumn->nullbitmap[oldLen], 0, BitmapLen(numOfRows) - oldLen); ASSERT(pColumn->info.bytes); - tmp = taosMemoryRealloc(pColumn->pData, numOfRows * pColumn->info.bytes); + + // make sure the allocated memory is MALLOC_ALIGN_BYTES aligned + tmp = taosMemoryMallocAlign(MALLOC_ALIGN_BYTES, numOfRows * pColumn->info.bytes); if (tmp == NULL) { return TSDB_CODE_OUT_OF_MEMORY; } + // copy back the existed data + if (pColumn->pData != NULL) { + memcpy(tmp, pColumn->pData, existedRows * pColumn->info.bytes); + taosMemoryFreeClear(pColumn->pData); + } + pColumn->pData = tmp; if (clearPayload) { memset(tmp + pColumn->info.bytes * existedRows, 0, pColumn->info.bytes * (numOfRows - existedRows)); diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index ed297e2b66..a98b172873 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -271,67 +271,6 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is return v; } -//static int64_t i64VectorCmpAVX2(const int64_t* pData, int32_t numOfRows, bool isMinFunc) { -// int64_t v = 0; -// const int32_t bitWidth = 256; -// const int64_t* p = pData; -// -// int32_t width = (bitWidth>>3u) / sizeof(int64_t); -// int32_t remain = numOfRows % width; -// int32_t rounds = numOfRows / width; -// -//#if __AVX2__ -// __m256i next; -// __m256i initialVal = _mm256_loadu_si256((__m256i*)p); -// p += width; -// -// if (!isMinFunc) { // max function -// for (int32_t i = 0; i < rounds; ++i) { -// next = _mm256_lddqu_si256((__m256i*)p); -// initialVal = _mm256_max_epi64(initialVal, next); -// p += width; -// } -// -// // let sum up the final results -// const int64_t* q = (const int64_t*)&initialVal; -// v = TMAX(q[0], q[1]); -// for(int32_t k = 1; k < width; ++k) { -// v = TMAX(v, q[k]); -// } -// -// // calculate the front and the reminder items in array list -// int32_t start = rounds * width; -// for (int32_t j = 0; j < remain; ++j) { -// if (v < p[j + start]) { -// v = p[j + start]; -// } -// } -// } else { // min function -// for (int32_t i = 0; i < rounds; ++i) { -// next = _mm256_lddqu_si256((__m256i*)p); -// initialVal = _mm256_min_epi64(initialVal, next); -// p += width; -// } -// -// // let sum up the final results -// const int64_t* q = (const int64_t*)&initialVal; -// v = TMIN(q[0], q[1]); -// for(int32_t k = 1; k < width; ++k) { -// v = TMIN(v, q[k]); -// } -// -// // calculate the front and the remainder items in array list -// int32_t start = rounds * width; -// for (int32_t j = 0; j < remain; ++j) { -// if (v > p[j + start]) { -// v = p[j + start]; -// } -// } -// } -//#endif -// -// return v; -//} static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, bool isMinFunc) { diff --git a/source/os/src/osMemory.c b/source/os/src/osMemory.c index 78fa362179..1facff1f3b 100644 --- a/source/os/src/osMemory.c +++ b/source/os/src/osMemory.c @@ -345,3 +345,11 @@ void taosMemoryTrim(int32_t size) { malloc_trim(size); #endif } + +void* taosMemoryMallocAlign(uint32_t alignment, int64_t size) { +#ifdef USE_TD_MEMORY + ASSERT(0); +#else + return memalign(alignment, size); +#endif +} From e0e55b2d6510e8d1420a8bc8852a9a9f0797c495 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 23 Nov 2022 22:08:35 +0800 Subject: [PATCH 38/66] refactor: do some internal refactor. --- include/common/tdatablock.h | 13 -------- include/common/tmisce.h | 42 +++++++++++++++++++++++++ source/client/inc/clientInt.h | 2 +- source/client/src/clientMain.c | 2 +- source/client/src/clientMsgHandler.c | 1 + source/common/src/tglobal.c | 2 +- source/common/src/tmisce.c | 2 +- source/dnode/mgmt/node_util/src/dmEps.c | 1 + source/dnode/mnode/impl/src/mndDnode.c | 1 + source/dnode/mnode/impl/src/mndMnode.c | 2 +- source/dnode/mnode/impl/src/mndVgroup.c | 1 + 11 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 include/common/tmisce.h diff --git a/include/common/tdatablock.h b/include/common/tdatablock.h index 502ba10d33..76ab2f7c3f 100644 --- a/include/common/tdatablock.h +++ b/include/common/tdatablock.h @@ -24,11 +24,6 @@ extern "C" { #endif -typedef struct SCorEpSet { - int32_t version; - SEpSet epSet; -} SCorEpSet; - typedef struct SBlockOrderInfo { bool nullFirst; int32_t order; @@ -36,14 +31,6 @@ typedef struct SBlockOrderInfo { SColumnInfoData* pColData; } SBlockOrderInfo; -int32_t taosGetFqdnPortFromEp(const char* ep, SEp* pEp); -void addEpIntoEpSet(SEpSet* pEpSet, const char* fqdn, uint16_t port); - -bool isEpsetEqual(const SEpSet* s1, const SEpSet* s2); - -void updateEpSet_s(SCorEpSet* pEpSet, SEpSet* pNewEpSet); -SEpSet getEpSet_s(SCorEpSet* pEpSet); - #define NBIT (3u) #define BitPos(_n) ((_n) & ((1 << NBIT) - 1)) #define BMCharPos(bm_, r_) ((bm_)[(r_) >> NBIT]) diff --git a/include/common/tmisce.h b/include/common/tmisce.h new file mode 100644 index 0000000000..b9f5cf5b91 --- /dev/null +++ b/include/common/tmisce.h @@ -0,0 +1,42 @@ +/* + * 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 . + */ + +#ifndef TDENGINE_TMISCE_H +#define TDENGINE_TMISCE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tmsg.h" + +typedef struct SCorEpSet { + int32_t version; + SEpSet epSet; +} SCorEpSet; + +int32_t taosGetFqdnPortFromEp(const char* ep, SEp* pEp); +void addEpIntoEpSet(SEpSet* pEpSet, const char* fqdn, uint16_t port); + +bool isEpsetEqual(const SEpSet* s1, const SEpSet* s2); + +void updateEpSet_s(SCorEpSet* pEpSet, SEpSet* pNewEpSet); +SEpSet getEpSet_s(SCorEpSet* pEpSet); + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_TMISCE_H diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index e569a97723..aae20c587d 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -26,7 +26,7 @@ extern "C" { #include "query.h" #include "taos.h" #include "tcommon.h" -#include "tdatablock.h" +#include "tmisce.h" #include "tdef.h" #include "thash.h" #include "tlist.h" diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index efa7d095c5..a84f9e6bb0 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -20,13 +20,13 @@ #include "functionMgt.h" #include "os.h" #include "query.h" -#include "qworker.h" #include "scheduler.h" #include "tglobal.h" #include "tmsg.h" #include "tref.h" #include "trpc.h" #include "version.h" +#include "tdatablock.h" #define TSC_VAR_NOT_RELEASE 1 #define TSC_VAR_RELEASED 0 diff --git a/source/client/src/clientMsgHandler.c b/source/client/src/clientMsgHandler.c index 591d469d7c..a49d072569 100644 --- a/source/client/src/clientMsgHandler.c +++ b/source/client/src/clientMsgHandler.c @@ -20,6 +20,7 @@ #include "query.h" #include "tdef.h" #include "tname.h" +#include "tdatablock.h" static void setErrno(SRequestObj* pRequest, int32_t code) { pRequest->code = code; diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 0db3e99863..d82ad5c15a 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -16,7 +16,7 @@ #define _DEFAULT_SOURCE #include "tglobal.h" #include "tconfig.h" -#include "tdatablock.h" +#include "tmisce.h" #include "tgrant.h" #include "tlog.h" diff --git a/source/common/src/tmisce.c b/source/common/src/tmisce.c index dfaebc99f6..dfb1917fcf 100644 --- a/source/common/src/tmisce.c +++ b/source/common/src/tmisce.c @@ -14,7 +14,7 @@ */ #define _DEFAULT_SOURCE -#include "tdatablock.h" +#include "tmisce.h" #include "tglobal.h" #include "tlog.h" #include "tname.h" diff --git a/source/dnode/mgmt/node_util/src/dmEps.c b/source/dnode/mgmt/node_util/src/dmEps.c index 7fe7d44827..4bc2e64fad 100644 --- a/source/dnode/mgmt/node_util/src/dmEps.c +++ b/source/dnode/mgmt/node_util/src/dmEps.c @@ -15,6 +15,7 @@ #define _DEFAULT_SOURCE #include "dmUtil.h" +#include "tmisce.h" static void dmPrintEps(SDnodeData *pData); static bool dmIsEpChanged(SDnodeData *pData, int32_t dnodeId, const char *ep); diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 521f924fad..2a3ecf1924 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -24,6 +24,7 @@ #include "mndTrans.h" #include "mndUser.h" #include "mndVgroup.h" +#include "tmisce.h" #define TSDB_DNODE_VER_NUMBER 1 #define TSDB_DNODE_RESERVE_SIZE 64 diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 563b3cd3cf..b02ca4c773 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -20,7 +20,7 @@ #include "mndShow.h" #include "mndSync.h" #include "mndTrans.h" -#include "mndUser.h" +#include "tmisce.h" #define MNODE_VER_NUMBER 1 #define MNODE_RESERVE_SIZE 64 diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index e00d0d955e..5555335765 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -22,6 +22,7 @@ #include "mndShow.h" #include "mndTrans.h" #include "mndUser.h" +#include "tmisce.h" #define VGROUP_VER_NUMBER 1 #define VGROUP_RESERVE_SIZE 64 From d71439260fc7353ef0aea8689a5e3dc995ce83aa Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 24 Nov 2022 15:01:25 +0800 Subject: [PATCH 39/66] refactor(query): add simd support for minmax query. --- .../libs/function/src/detail/tavgfunction.c | 33 -- source/libs/function/src/detail/tminmax.c | 282 +++++++++++++++++- 2 files changed, 268 insertions(+), 47 deletions(-) diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 744927d6c8..1553a446a7 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -272,39 +272,6 @@ static void i64VectorSumAVX2(const int64_t* plist, int32_t numOfRows, SAvgRes* p #endif } -static int32_t handleFloatCols(const SColumnInfoData* pCol, const SInputColumnInfoData* pInput, SAvgRes* pRes) { - int32_t numOfElems = 0; - float* plist = (float*)pCol->pData; - - const int32_t THRESHOLD_SIZE = 8; - - if (pCol->hasNull || pInput->numOfRows <= THRESHOLD_SIZE) { - for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - numOfElems += 1; - pRes->count += 1; - pRes->sum.dsum += plist[i]; - } - } else { // no null values exist - numOfElems = pInput->numOfRows; - pRes->count += pInput->numOfRows; - - // 3. If the CPU supports AVX, let's employ AVX instructions to speedup this loop - if (tsAVXEnable && tsSIMDEnable) { - floatVectorSumAVX(plist, pInput->numOfRows, pRes); - } else { - for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; ++i) { - pRes->sum.dsum += plist[i]; - } - } - } - - return numOfElems; -} - int32_t getAvgInfoSize() { return (int32_t)sizeof(SAvgRes); } bool getAvgFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index a98b172873..bda1fea90a 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -30,7 +30,7 @@ static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool is #if __AVX2__ __m256i next; - __m256i initialVal = _mm256_loadu_si256((__m256i*)p); + __m256i initialVal = _mm256_lddqu_si256((__m256i*)p); p += width; if (!isMinFunc) { // max function @@ -40,7 +40,7 @@ static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool is p += width; } - // let sum up the final results + // let compare the final results const int32_t* q = (const int32_t*)&initialVal; v = TMAX(q[0], q[1]); for (int32_t k = 1; k < width; ++k) { @@ -155,7 +155,7 @@ static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMin #if __AVX2__ __m256i next; - __m256i initialVal = _mm256_loadu_si256((__m256i*)p); + __m256i initialVal = _mm256_lddqu_si256((__m256i*)p); p += width; if (!isMinFunc) { // max function @@ -218,7 +218,7 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is #if __AVX2__ __m256i next; - __m256i initialVal = _mm256_loadu_si256((__m256i*)p); + __m256i initialVal = _mm256_lddqu_si256((__m256i*)p); p += width; if (!isMinFunc) { // max function @@ -271,6 +271,179 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is return v; } +static int32_t handleInt8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, + SMinmaxResInfo* pBuf, bool isMinFunc) { + int8_t* pData = (int8_t*)pCol->pData; + int8_t* val = (int8_t*)&pBuf->v; + + int32_t numOfElems = 0; + if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { + int32_t i = start; + while (i < (start + numOfRows)) { + if (!colDataIsNull_f(pCol->nullbitmap, i)) { + break; + } + i += 1; + } + + if ((i < (start + numOfRows)) && (!pBuf->assign)) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + numOfElems += 1; + } + + if (isMinFunc) { // min + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } else { // max function + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } + } else { // not has null value + // AVX2 version to speedup the loop + if (tsAVX2Enable && tsSIMDEnable) { + *val = i8VectorCmpAVX2(pData, numOfRows, isMinFunc); + } else { + if (!pBuf->assign) { + *val = pData[0]; + pBuf->assign = true; + } + + if (isMinFunc) { // min + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val > pData[i]) { + *val = pData[i]; + } + } + } else { // max + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val < pData[i]) { + *val = pData[i]; + } + } + } + } + + numOfElems = numOfRows; + } + + return numOfElems; +} + +static int32_t handleInt16Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, + SMinmaxResInfo* pBuf, bool isMinFunc) { + int16_t* pData = (int16_t*)pCol->pData; + int16_t* val = (int16_t*)&pBuf->v; + + int32_t numOfElems = 0; + if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { + int32_t i = start; + while (i < (start + numOfRows)) { + if (!colDataIsNull_f(pCol->nullbitmap, i)) { + break; + } + i += 1; + } + + if ((i < (start + numOfRows)) && (!pBuf->assign)) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + numOfElems += 1; + } + + if (isMinFunc) { // min + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } else { // max function + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } + } else { // not has null value + // AVX2 version to speedup the loop + if (tsAVX2Enable && tsSIMDEnable) { + *val = i16VectorCmpAVX2(pData, numOfRows, isMinFunc); + } else { + if (!pBuf->assign) { + *val = pData[0]; + pBuf->assign = true; + } + + if (isMinFunc) { // min + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val > pData[i]) { + *val = pData[i]; + } + } + } else { // max + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val < pData[i]) { + *val = pData[i]; + } + } + } + } + + numOfElems = numOfRows; + } + + return numOfElems; +} static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, bool isMinFunc) { @@ -359,6 +532,87 @@ static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numO return numOfElems; } +static int32_t handleInt64Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, + SMinmaxResInfo* pBuf, bool isMinFunc) { + int32_t* pData = (int32_t*)pCol->pData; + int32_t* val = (int32_t*)&pBuf->v; + + int32_t numOfElems = 0; + if (pCol->hasNull || pCtx->subsidiaries.num > 0) { + int32_t i = start; + while (i < (start + numOfRows)) { + if (!colDataIsNull_f(pCol->nullbitmap, i)) { + break; + } + i += 1; + } + + if ((i < (start + numOfRows)) && (!pBuf->assign)) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + numOfElems += 1; + } + + if (isMinFunc) { // min + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + + if (*val > pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + + } else { // max function + for (; i < start + numOfRows; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } + // ignore the equivalent data value + // NOTE: An faster version to avoid one additional comparison with FPU. + if (*val < pData[i]) { + *val = pData[i]; + if (pCtx->subsidiaries.num > 0) { + updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); + } + } + numOfElems += 1; + } + } + } else { // not has null value + // AVX2 version to speedup the loop + if (!pBuf->assign) { + *val = pData[0]; + pBuf->assign = true; + } + + if (isMinFunc) { // min + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val > pData[i]) { + *val = pData[i]; + } + } + } else { // max + for (int32_t i = start; i < start + numOfRows; ++i) { + if (*val < pData[i]) { + *val = pData[i]; + } + } + } + + numOfElems = numOfRows; + } + return numOfElems; +} + static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, bool isMinFunc) { float* pData = (float*)pCol->pData; @@ -445,13 +699,13 @@ static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numO return numOfElems; } -static int32_t handleInt8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, - SMinmaxResInfo* pBuf, bool isMinFunc) { - int8_t* pData = (int8_t*)pCol->pData; - int8_t* val = (int8_t*)&pBuf->v; +static int32_t handleDoubleCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, + SMinmaxResInfo* pBuf, bool isMinFunc) { + float* pData = (float*)pCol->pData; + double* val = (double*)&pBuf->v; int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { + if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { int32_t i = start; while (i < (start + numOfRows)) { if (!colDataIsNull_f(pCol->nullbitmap, i)) { @@ -483,12 +737,12 @@ static int32_t handleInt8Col(SColumnInfoData* pCol, int32_t start, int32_t numOf } numOfElems += 1; } - } else { // max function for (; i < start + numOfRows; ++i) { if (colDataIsNull_f(pCol->nullbitmap, i)) { continue; } + // ignore the equivalent data value // NOTE: An faster version to avoid one additional comparison with FPU. if (*val < pData[i]) { @@ -499,12 +753,11 @@ static int32_t handleInt8Col(SColumnInfoData* pCol, int32_t start, int32_t numOf } numOfElems += 1; } - } } else { // not has null value - // AVX2 version to speedup the loop - if (tsAVX2Enable && tsSIMDEnable) { - *val = i8VectorCmpAVX2(pData, numOfRows, isMinFunc); + // AVX version to speedup the loop + if (tsAVXEnable && tsSIMDEnable) { + *val = (double) floatVectorCmpAVX(pData, numOfRows, isMinFunc); } else { if (!pBuf->assign) { *val = pData[0]; @@ -660,6 +913,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { if (type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_BOOL) { numOfElems = handleInt8Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); } else if (type == TSDB_DATA_TYPE_SMALLINT) { + numOfElems = handleInt16Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); int16_t* pData = (int16_t*)pCol->pData; int16_t* val = (int16_t*)&pBuf->v; From 0ed2c923ad54efebbe2cc9a9286c300b745986a9 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 24 Nov 2022 17:01:00 +0800 Subject: [PATCH 40/66] enh(query): support simd in min/max query. --- source/libs/function/src/detail/tminmax.c | 551 +++++++++------------- source/libs/function/src/udfd.c | 1 + 2 files changed, 218 insertions(+), 334 deletions(-) diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index bda1fea90a..21f8631156 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -19,139 +19,20 @@ #include "tfunctionInt.h" #include "tglobal.h" -static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool isMinFunc) { - int32_t v = 0; - const int32_t bitWidth = 256; - const int32_t* p = pData; - - int32_t width = (bitWidth>>3u) / sizeof(int32_t); - int32_t remain = numOfRows % width; - int32_t rounds = numOfRows / width; - -#if __AVX2__ - __m256i next; - __m256i initialVal = _mm256_lddqu_si256((__m256i*)p); - p += width; - - if (!isMinFunc) { // max function - for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_lddqu_si256((__m256i*)p); - initialVal = _mm256_max_epi32(initialVal, next); - p += width; - } - - // let compare the final results - const int32_t* q = (const int32_t*)&initialVal; - v = TMAX(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMAX(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + start]) { - v = p[j + start]; - } - } - } else { // min function - for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_lddqu_si256((__m256i*)p); - initialVal = _mm256_min_epi32(initialVal, next); - p += width; - } - - // let sum up the final results - const int32_t* q = (const int32_t*)&initialVal; - v = TMIN(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMIN(v, q[k]); - } - - // calculate the front and the remainder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + start]) { - v = p[j + start]; - } - } - } -#endif - - return v; -} - -static float floatVectorCmpAVX(const float* pData, int32_t numOfRows, bool isMinFunc) { - float v = 0; +static void calculateRounds(int32_t numOfRows, int32_t bytes, int32_t* remainder, int32_t* rounds, int32_t* width) { const int32_t bitWidth = 256; - const float* p = pData; - int32_t width = (bitWidth>>3u) / sizeof(float); - int32_t remain = numOfRows % width; - int32_t rounds = numOfRows / width; - -#if __AVX__ - - __m256 next; - __m256 initialVal = _mm256_loadu_ps(p); - p += width; - - if (!isMinFunc) { // max function - for (int32_t i = 1; i < rounds; ++i) { - next = _mm256_loadu_ps(p); - initialVal = _mm256_max_ps(initialVal, next); - p += width; - } - - // let sum up the final results - const float* q = (const float*)&initialVal; - v = TMAX(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMAX(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + width]) { - v = p[j + width]; - } - } - } else { // min function - for (int32_t i = 1; i < rounds; ++i) { - next = _mm256_loadu_ps(p); - initialVal = _mm256_min_ps(initialVal, next); - p += width; - } - - // let sum up the final results - const float* q = (const float*)&initialVal; - v = TMIN(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMIN(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * bitWidth; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + start]) { - v = p[j + start]; - } - } - } -#endif - - return v; + *width = (bitWidth>>3u) / bytes; + *remainder = numOfRows % (*width); + *rounds = numOfRows / (*width); } static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMinFunc) { int8_t v = 0; - const int32_t bitWidth = 256; const int8_t* p = pData; - int32_t width = (bitWidth>>3u) / sizeof(int8_t); - int32_t remain = numOfRows % width; - int32_t rounds = numOfRows / width; + int32_t width, remain, rounds; + calculateRounds(numOfRows, sizeof(int8_t), &remain, &rounds, &width); #if __AVX2__ __m256i next; @@ -209,12 +90,10 @@ static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMin static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool isMinFunc) { int16_t v = 0; - const int32_t bitWidth = 256; const int16_t* p = pData; - int32_t width = (bitWidth>>3u) / sizeof(int16_t); - int32_t remain = numOfRows % width; - int32_t rounds = numOfRows / width; + int32_t width, remain, rounds; + calculateRounds(numOfRows, sizeof(int16_t), &remain, &rounds, &width); #if __AVX2__ __m256i next; @@ -236,6 +115,7 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is v = TMAX(v, q[k]); } + // calculate the front and the reminder items in array list int32_t start = rounds * width; for (int32_t j = 0; j < remain; ++j) { @@ -271,20 +151,208 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is return v; } +static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool isMinFunc) { + int32_t v = 0; + const int32_t* p = pData; + + int32_t width, remain, rounds; + calculateRounds(numOfRows, sizeof(int32_t), &remain, &rounds, &width); + +#if __AVX2__ + __m256i next; + __m256i initialVal = _mm256_lddqu_si256((__m256i*)p); + p += width; + + if (!isMinFunc) { // max function + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initialVal = _mm256_max_epi32(initialVal, next); + p += width; + } + + // let compare the final results + const int32_t* q = (const int32_t*)&initialVal; + v = TMAX(q[0], q[1]); + for (int32_t k = 1; k < width; ++k) { + v = TMAX(v, q[k]); + } + + // calculate the front and the reminder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + start]) { + v = p[j + start]; + } + } + } else { // min function + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initialVal = _mm256_min_epi32(initialVal, next); + p += width; + } + + // let sum up the final results + const int32_t* q = (const int32_t*)&initialVal; + v = TMIN(q[0], q[1]); + for (int32_t k = 1; k < width; ++k) { + v = TMIN(v, q[k]); + } + + // calculate the front and the remainder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + start]) { + v = p[j + start]; + } + } + } +#endif + + return v; +} + +static float floatVectorCmpAVX(const float* pData, int32_t numOfRows, bool isMinFunc) { + float v = 0; + const float* p = pData; + + int32_t width, remain, rounds; + calculateRounds(numOfRows, sizeof(float), &remain, &rounds, &width); + +#if __AVX__ + + __m256 next; + __m256 initialVal = _mm256_loadu_ps(p); + p += width; + + if (!isMinFunc) { // max function + for (int32_t i = 1; i < rounds; ++i) { + next = _mm256_loadu_ps(p); + initialVal = _mm256_max_ps(initialVal, next); + p += width; + } + + // let sum up the final results + const float* q = (const float*)&initialVal; + v = TMAX(q[0], q[1]); + for (int32_t k = 1; k < width; ++k) { + v = TMAX(v, q[k]); + } + + // calculate the front and the reminder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + start]) { + v = p[j + start]; + } + } + } else { // min function + for (int32_t i = 1; i < rounds; ++i) { + next = _mm256_loadu_ps(p); + initialVal = _mm256_min_ps(initialVal, next); + p += width; + } + + // let sum up the final results + const float* q = (const float*)&initialVal; + v = TMIN(q[0], q[1]); + for (int32_t k = 1; k < width; ++k) { + v = TMIN(v, q[k]); + } + + // calculate the front and the reminder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + start]) { + v = p[j + start]; + } + } + } +#endif + + return v; +} + +static double doubleVectorCmpAVX(const double* pData, int32_t numOfRows, bool isMinFunc) { + double v = 0; + const double* p = pData; + + int32_t width, remain, rounds; + calculateRounds(numOfRows, sizeof(double), &remain, &rounds, &width); + +#if __AVX__ + + __m256d next; + __m256d initialVal = _mm256_loadu_pd(p); + p += width; + + if (!isMinFunc) { // max function + for (int32_t i = 1; i < rounds; ++i) { + next = _mm256_loadu_pd(p); + initialVal = _mm256_max_pd(initialVal, next); + p += width; + } + + // let sum up the final results + const double* q = (const double*)&initialVal; + v = TMAX(q[0], q[1]); + for (int32_t k = 1; k < width; ++k) { + v = TMAX(v, q[k]); + } + + // calculate the front and the reminder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v < p[j + start]) { + v = p[j + start]; + } + } + } else { // min function + for (int32_t i = 1; i < rounds; ++i) { + next = _mm256_loadu_pd(p); + initialVal = _mm256_min_pd(initialVal, next); + p += width; + } + + // let sum up the final results + const double* q = (const double*)&initialVal; + v = TMIN(q[0], q[1]); + for (int32_t k = 1; k < width; ++k) { + v = TMIN(v, q[k]); + } + + // calculate the front and the reminder items in array list + int32_t start = rounds * width; + for (int32_t j = 0; j < remain; ++j) { + if (v > p[j + start]) { + v = p[j + start]; + } + } + } +#endif + + return v; +} + +static int32_t findFirstVal(const SColumnInfoData* pCol, int32_t start, int32_t numOfRows) { + int32_t i = start; + while (i < (start + numOfRows)) { + if (!colDataIsNull_f(pCol->nullbitmap, i)) { + break; + } + i += 1; + } + + return i; +} + static int32_t handleInt8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, bool isMinFunc) { int8_t* pData = (int8_t*)pCol->pData; int8_t* val = (int8_t*)&pBuf->v; int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { - int32_t i = start; - while (i < (start + numOfRows)) { - if (!colDataIsNull_f(pCol->nullbitmap, i)) { - break; - } - i += 1; - } + if (pCol->hasNull || numOfRows <= 32 || pCtx->subsidiaries.num > 0) { + int32_t i = findFirstVal(pCol, start, numOfRows); if ((i < (start + numOfRows)) && (!pBuf->assign)) { *val = pData[i]; @@ -365,13 +433,7 @@ static int32_t handleInt16Col(SColumnInfoData* pCol, int32_t start, int32_t numO int32_t numOfElems = 0; if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { - int32_t i = start; - while (i < (start + numOfRows)) { - if (!colDataIsNull_f(pCol->nullbitmap, i)) { - break; - } - i += 1; - } + int32_t i = findFirstVal(pCol, start, numOfRows); if ((i < (start + numOfRows)) && (!pBuf->assign)) { *val = pData[i]; @@ -452,13 +514,7 @@ static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numO int32_t numOfElems = 0; if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { - int32_t i = start; - while (i < (start + numOfRows)) { - if (!colDataIsNull_f(pCol->nullbitmap, i)) { - break; - } - i += 1; - } + int32_t i = findFirstVal(pCol, start, numOfRows); if ((i < (start + numOfRows)) && (!pBuf->assign)) { *val = pData[i]; @@ -539,13 +595,7 @@ static int32_t handleInt64Col(SColumnInfoData* pCol, int32_t start, int32_t numO int32_t numOfElems = 0; if (pCol->hasNull || pCtx->subsidiaries.num > 0) { - int32_t i = start; - while (i < (start + numOfRows)) { - if (!colDataIsNull_f(pCol->nullbitmap, i)) { - break; - } - i += 1; - } + int32_t i = findFirstVal(pCol, start, numOfRows); if ((i < (start + numOfRows)) && (!pBuf->assign)) { *val = pData[i]; @@ -616,18 +666,11 @@ static int32_t handleInt64Col(SColumnInfoData* pCol, int32_t start, int32_t numO static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, bool isMinFunc) { float* pData = (float*)pCol->pData; - double* val = (double*)&pBuf->v; + float* val = (float*)&pBuf->v; int32_t numOfElems = 0; if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { - int32_t i = start; - while (i < (start + numOfRows)) { - if (!colDataIsNull_f(pCol->nullbitmap, i)) { - break; - } - i += 1; - } - + int32_t i = findFirstVal(pCol, start, numOfRows); if ((i < (start + numOfRows)) && (!pBuf->assign)) { *val = pData[i]; if (pCtx->subsidiaries.num > 0) { @@ -701,18 +744,12 @@ static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numO static int32_t handleDoubleCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, bool isMinFunc) { - float* pData = (float*)pCol->pData; + double* pData = (double*)pCol->pData; double* val = (double*)&pBuf->v; int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { - int32_t i = start; - while (i < (start + numOfRows)) { - if (!colDataIsNull_f(pCol->nullbitmap, i)) { - break; - } - i += 1; - } + if (pCol->hasNull || numOfRows < 4 || pCtx->subsidiaries.num > 0) { + int32_t i = findFirstVal(pCol, start, numOfRows); if ((i < (start + numOfRows)) && (!pBuf->assign)) { *val = pData[i]; @@ -757,7 +794,7 @@ static int32_t handleDoubleCol(SColumnInfoData* pCol, int32_t start, int32_t num } else { // not has null value // AVX version to speedup the loop if (tsAVXEnable && tsSIMDEnable) { - *val = (double) floatVectorCmpAVX(pData, numOfRows, isMinFunc); + *val = (double) doubleVectorCmpAVX(pData, numOfRows, isMinFunc); } else { if (!pBuf->assign) { *val = pData[0]; @@ -813,7 +850,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { if (IS_NULL_TYPE(type)) { numOfElems = 0; - goto _min_max_over; + goto _over; } // data in current data block are qualified to the query @@ -914,117 +951,10 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { numOfElems = handleInt8Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); } else if (type == TSDB_DATA_TYPE_SMALLINT) { numOfElems = handleInt16Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); - int16_t* pData = (int16_t*)pCol->pData; - int16_t* val = (int16_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } } else if (type == TSDB_DATA_TYPE_INT) { numOfElems = handleInt32Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); -#if 0 - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } -#endif - } else if (type == TSDB_DATA_TYPE_BIGINT) { - int64_t* pData = (int64_t*)pCol->pData; - int64_t* val = (int64_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } + numOfElems = handleInt64Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); } } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { if (type == TSDB_DATA_TYPE_UTINYINT) { @@ -1215,56 +1145,9 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { } } else if (type == TSDB_DATA_TYPE_FLOAT) { numOfElems = handleFloatCol(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); -#if 0 - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { -#if 0 - if ((*val) == pData[i]) { - continue; - } - - if ((*val < pData[i]) ^ isMinFunc) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } -#endif - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; - } -#endif - } -_min_max_over: +_over: if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); pBuf->nullTupleSaved = true; diff --git a/source/libs/function/src/udfd.c b/source/libs/function/src/udfd.c index 088aa62248..2ad36469ff 100644 --- a/source/libs/function/src/udfd.c +++ b/source/libs/function/src/udfd.c @@ -27,6 +27,7 @@ #include "tglobal.h" #include "tmsg.h" #include "trpc.h" +#include "tmisce.h" // clang-foramt on typedef struct SUdfdContext { From 89341bc303375abdfb0adacc409cd300a9125971 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 24 Nov 2022 17:01:37 +0800 Subject: [PATCH 41/66] enh(query): support simd in min/max query. --- source/libs/function/src/detail/tminmax.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index 21f8631156..5fbc70a213 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -432,7 +432,7 @@ static int32_t handleInt16Col(SColumnInfoData* pCol, int32_t start, int32_t numO int16_t* val = (int16_t*)&pBuf->v; int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { + if (pCol->hasNull || numOfRows <= 16 || pCtx->subsidiaries.num > 0) { int32_t i = findFirstVal(pCol, start, numOfRows); if ((i < (start + numOfRows)) && (!pBuf->assign)) { From f745dec5ec8f45dbeb805da1404e4491a7731b95 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 24 Nov 2022 17:17:22 +0800 Subject: [PATCH 42/66] other: merge 3.0 --- source/libs/executor/inc/executorimpl.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 10a322a758..fad232a7c0 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -153,6 +153,11 @@ typedef struct { SSchemaWrapper* qsw; } SSchemaInfo; +typedef struct { + SRWLatch lock; + SArray* pStopInfo; +} STaskStopInfo; + typedef struct SExecTaskInfo { STaskIdInfo id; uint32_t status; From 8dd780b486c45a2209a33a02581d51b3b7faa448 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 24 Nov 2022 17:17:53 +0800 Subject: [PATCH 43/66] other: merge 3.0 --- source/libs/executor/inc/executorimpl.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index fad232a7c0..af3399bc2c 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -153,6 +153,11 @@ typedef struct { SSchemaWrapper* qsw; } SSchemaInfo; +typedef struct { + int32_t operatorType; + int64_t refId; +} SExchangeOpStopInfo; + typedef struct { SRWLatch lock; SArray* pStopInfo; From e5e817ae5539f8901180d460db77f7d06ea38832 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 24 Nov 2022 17:24:24 +0800 Subject: [PATCH 44/66] other: merge 3.0 --- source/libs/executor/inc/executorimpl.h | 8 ++++---- source/libs/executor/src/exchangeoperator.c | 10 +++++----- source/libs/function/inc/builtinsimpl.h | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index af3399bc2c..b9d622a4c3 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -153,17 +153,17 @@ typedef struct { SSchemaWrapper* qsw; } SSchemaInfo; -typedef struct { +typedef struct SExchangeOpStopInfo { int32_t operatorType; int64_t refId; } SExchangeOpStopInfo; -typedef struct { +typedef struct STaskStopInfo { SRWLatch lock; SArray* pStopInfo; } STaskStopInfo; -typedef struct SExecTaskInfo { +struct SExecTaskInfo { STaskIdInfo id; uint32_t status; STimeWindow window; @@ -260,7 +260,7 @@ typedef struct SExchangeInfo { // SArray, result block list, used to keep the multi-block that // passed by downstream operator - SArray* pReadyBlocks; + SArray* pResultBlockList; SArray* pRecycledBlocks;// build a pool for small data block to avoid to repeatly create and then destroy. SSDataBlock* pDummyBlock; // dummy block, not keep data bool seqLoadData; // sequential load data or not, false by default diff --git a/source/libs/executor/src/exchangeoperator.c b/source/libs/executor/src/exchangeoperator.c index cf1f5aa290..52aa3db0fd 100644 --- a/source/libs/executor/src/exchangeoperator.c +++ b/source/libs/executor/src/exchangeoperator.c @@ -182,7 +182,7 @@ static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) { } // we have buffered retrieved datablock, return it directly - SSDataBlock** p = taosArrayPop(pExchangeInfo->pReadyBlocks); + SSDataBlock** p = taosArrayPop(pExchangeInfo->pResultBlockList); if (p != NULL) { taosArrayPush(pExchangeInfo->pRecycledBlocks, p); return *p; @@ -193,10 +193,10 @@ static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) { concurrentlyLoadRemoteDataImpl(pOperator, pExchangeInfo, pTaskInfo); } - if (taosArrayGetSize(pExchangeInfo->pReadyBlocks) == 0) { + if (taosArrayGetSize(pExchangeInfo->pResultBlockList) == 0) { return NULL; } else { - p = taosArrayPop(pExchangeInfo->pReadyBlocks); + p = taosArrayPop(pExchangeInfo->pResultBlockList); taosArrayPush(pExchangeInfo->pRecycledBlocks, p); return *p; } @@ -298,7 +298,7 @@ SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, SExchangePhysiNode tsem_init(&pInfo->ready, 0, 0); pInfo->pDummyBlock = createResDataBlock(pExNode->node.pOutputDataBlockDesc); - pInfo->pReadyBlocks = taosArrayInit(64, POINTER_BYTES); + pInfo->pResultBlockList = taosArrayInit(64, POINTER_BYTES); pInfo->pRecycledBlocks = taosArrayInit(64, POINTER_BYTES); SExchangeOpStopInfo stopInfo = {QUERY_NODE_PHYSICAL_PLAN_EXCHANGE, pInfo->self}; @@ -346,7 +346,7 @@ void doDestroyExchangeOperatorInfo(void* param) { taosArrayDestroy(pExInfo->pSources); taosArrayDestroyEx(pExInfo->pSourceDataInfo, freeSourceDataInfo); - taosArrayDestroyEx(pExInfo->pReadyBlocks, freeBlock); + taosArrayDestroyEx(pExInfo->pResultBlockList, freeBlock); taosArrayDestroyEx(pExInfo->pRecycledBlocks, freeBlock); blockDataDestroy(pExInfo->pDummyBlock); diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h index 2ec882d1de..307a82e256 100644 --- a/source/libs/function/inc/builtinsimpl.h +++ b/source/libs/function/inc/builtinsimpl.h @@ -30,6 +30,8 @@ typedef struct SSumRes { double dsum; }; int16_t type; + int64_t prevTs; + bool isPrevTsSet; } SSumRes; typedef struct SMinmaxResInfo { From f4f2774100eb39cba09f392e12dd05c3d7a19199 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 24 Nov 2022 23:23:05 +0800 Subject: [PATCH 45/66] refactor: do some internal refactor. --- .../libs/function/src/detail/tavgfunction.c | 1 + source/libs/function/src/detail/tminmax.c | 1300 +++++++---------- 2 files changed, 529 insertions(+), 772 deletions(-) diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 1553a446a7..9507380d38 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -551,6 +551,7 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { } break; } + case TSDB_DATA_TYPE_FLOAT: { const float* plist = (const float*) pCol->pData; diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index 5fbc70a213..03438350ed 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -19,6 +19,48 @@ #include "tfunctionInt.h" #include "tglobal.h" +#define __COMPARE_ACQUIRED_MAX(i, end, bm, _data, ctx, val, pos) \ + for (; i < (end); ++i) { \ + if (colDataIsNull_f(bm, i)) { \ + continue; \ + } \ + \ + if ((val) < (_data)[i]) { \ + (val) = (_data)[i]; \ + if ((ctx)->subsidiaries.num > 0) { \ + updateTupleData((ctx), i, (ctx)->pSrcBlock, pos); \ + } \ + } \ + } + +#define __COMPARE_ACQUIRED_MIN(i, end, bm, _data, ctx, val, pos) \ + for (; i < (end); ++i) { \ + if (colDataIsNull_f(bm, i)) { \ + continue; \ + } \ + \ + if ((val) > (_data)[i]) { \ + (val) = (_data)[i]; \ + if ((ctx)->subsidiaries.num > 0) { \ + updateTupleData((ctx), i, (ctx)->pSrcBlock, pos); \ + } \ + } \ + } + +#define __COMPARE_EXTRACT_MIN(start, end, val, _data) \ + for (int32_t i = (start); i < (end); ++i) { \ + if ((val) > (_data)[i]) { \ + (val) = (_data)[i]; \ + } \ + } + +#define __COMPARE_EXTRACT_MAX(start, end, val, _data) \ + for (int32_t i = (start); i < (end); ++i) { \ + if ((val) < (_data)[i]) { \ + (val) = (_data)[i]; \ + } \ + } + static void calculateRounds(int32_t numOfRows, int32_t bytes, int32_t* remainder, int32_t* rounds, int32_t* width) { const int32_t bitWidth = 256; @@ -27,7 +69,32 @@ static void calculateRounds(int32_t numOfRows, int32_t bytes, int32_t* remainder *rounds = numOfRows / (*width); } -static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMinFunc) { +#define EXTRACT_MAX_VAL(_first, _sec, _width, _remain, _v) \ + (_v) = TMAX((_first)[0], (_first)[1]); \ + for (int32_t k = 1; k < (_width); ++k) { \ + (_v) = TMAX((_v), (_first)[k]); \ + } \ + \ + for (int32_t j = 0; j < (_remain); ++j) { \ + if ((_v) < (_sec)[j]) { \ + (_v) = (_sec)[j]; \ + } \ + } + +#define EXTRACT_MIN_VAL(_first, _sec, _width, _remain, _v) \ + (_v) = TMIN((_first)[0], (_first)[1]); \ + for (int32_t k = 1; k < (_width); ++k) { \ + (_v) = TMIN((_v), (_first)[k]); \ + } \ + \ + for (int32_t j = 0; j < (_remain); ++j) { \ + if ((_v) > (_sec)[j]) { \ + (_v) = (_sec)[j]; \ + } \ + } + + +static int8_t i8VectorCmpAVX2(const void* pData, int32_t numOfRows, bool isMinFunc, bool signVal) { int8_t v = 0; const int8_t* p = pData; @@ -36,51 +103,51 @@ static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMin #if __AVX2__ __m256i next; - __m256i initialVal = _mm256_lddqu_si256((__m256i*)p); + __m256i initVal = _mm256_lddqu_si256((__m256i*)p); p += width; if (!isMinFunc) { // max function - for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_lddqu_si256((__m256i*)p); - initialVal = _mm256_max_epi8(initialVal, next); - p += width; - } - - // let sum up the final results - const int8_t* q = (const int8_t*)&initialVal; - v = TMAX(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMAX(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + start]) { - v = p[j + start]; + if (signVal) { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_max_epi8(initVal, next); + p += width; } + + const int8_t* q = (const int8_t*)&initVal; + EXTRACT_MAX_VAL(q, p, width, remain, v) + } else { // unsigned value + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_max_epu8(initVal, next); + p += width; + } + + const uint8_t* q = (const uint8_t*)&initVal; + EXTRACT_MAX_VAL(q, p, width, remain, v) } + } else { // min function - for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_lddqu_si256((__m256i*)p); - initialVal = _mm256_min_epi8(initialVal, next); - p += width; - } - - // let sum up the final results - const int8_t* q = (const int8_t*)&initialVal; - - v = TMIN(q[0], q[1]); - for(int32_t k = 1; k < width; ++k) { - v = TMIN(v, q[k]); - } - - // calculate the front and the remainder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + start]) { - v = p[j + start]; + if (signVal) { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_min_epi8(initVal, next); + p += width; } + + // let sum up the final results + const int8_t* q = (const int8_t*)&initVal; + EXTRACT_MIN_VAL(q, p, width, remain, v) + } else { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_min_epu8(initVal, next); + p += width; + } + + // let sum up the final results + const uint8_t* q = (const uint8_t*)&initVal; + EXTRACT_MIN_VAL(q, p, width, remain, v) } } #endif @@ -88,7 +155,7 @@ static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMin return v; } -static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool isMinFunc) { +static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool isMinFunc, bool signVal) { int16_t v = 0; const int16_t* p = pData; @@ -97,53 +164,53 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is #if __AVX2__ __m256i next; - __m256i initialVal = _mm256_lddqu_si256((__m256i*)p); + __m256i initVal = _mm256_lddqu_si256((__m256i*)p); p += width; if (!isMinFunc) { // max function - for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_lddqu_si256((__m256i*)p); - initialVal = _mm256_max_epi16(initialVal, next); - p += width; - } - - // let sum up the final results - const int16_t* q = (const int16_t*)&initialVal; - - v = TMAX(q[0], q[1]); - for(int32_t k = 1; k < width; ++k) { - v = TMAX(v, q[k]); - } - - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + start]) { - v = p[j + start]; + if (signVal) { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_max_epi16(initVal, next); + p += width; } + + // let sum up the final results + const int16_t* q = (const int16_t*)&initVal; + EXTRACT_MAX_VAL(q, p, width, remain, v) + } else { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_max_epu16(initVal, next); + p += width; + } + + // let sum up the final results + const uint16_t* q = (const uint16_t*)&initVal; + EXTRACT_MAX_VAL(q, p, width, remain, v) } + } else { // min function - for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_lddqu_si256((__m256i*)p); - initialVal = _mm256_min_epi16(initialVal, next); - p += width; - } - - // let sum up the final results - const int16_t* q = (const int16_t*)&initialVal; - - v = TMIN(q[0], q[1]); - for(int32_t k = 1; k < width; ++k) { - v = TMIN(v, q[k]); - } - - // calculate the front and the remainder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + start]) { - v = p[j + start]; + if (signVal) { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_min_epi16(initVal, next); + p += width; } + + // let sum up the final results + const int16_t* q = (const int16_t*)&initVal; + EXTRACT_MIN_VAL(q, p, width, remain, v) + } else { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_min_epi16(initVal, next); + p += width; + } + + // let sum up the final results + const uint16_t* q = (const uint16_t*)&initVal; + EXTRACT_MIN_VAL(q, p, width, remain, v) } } #endif @@ -151,7 +218,7 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is return v; } -static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool isMinFunc) { +static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool isMinFunc, bool signVal) { int32_t v = 0; const int32_t* p = pData; @@ -160,50 +227,52 @@ static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool is #if __AVX2__ __m256i next; - __m256i initialVal = _mm256_lddqu_si256((__m256i*)p); + __m256i initVal = _mm256_lddqu_si256((__m256i*)p); p += width; if (!isMinFunc) { // max function - for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_lddqu_si256((__m256i*)p); - initialVal = _mm256_max_epi32(initialVal, next); - p += width; - } - - // let compare the final results - const int32_t* q = (const int32_t*)&initialVal; - v = TMAX(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMAX(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + start]) { - v = p[j + start]; + if (signVal) { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_max_epi32(initVal, next); + p += width; } + + // let compare the final results + const int32_t* q = (const int32_t*)&initVal; + EXTRACT_MAX_VAL(q, p, width, remain, v) + } else { // unsigned value + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_max_epi32(initVal, next); + p += width; + } + + // let compare the final results + const uint32_t* q = (const uint32_t*)&initVal; + EXTRACT_MAX_VAL(q, p, width, remain, v) } } else { // min function - for (int32_t i = 0; i < rounds; ++i) { - next = _mm256_lddqu_si256((__m256i*)p); - initialVal = _mm256_min_epi32(initialVal, next); - p += width; - } - - // let sum up the final results - const int32_t* q = (const int32_t*)&initialVal; - v = TMIN(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMIN(v, q[k]); - } - - // calculate the front and the remainder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + start]) { - v = p[j + start]; + if (signVal) { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_min_epi32(initVal, next); + p += width; } + + // let sum up the final results + const int32_t* q = (const int32_t*)&initVal; + EXTRACT_MIN_VAL(q, p, width, remain, v) + } else { + for (int32_t i = 0; i < rounds; ++i) { + next = _mm256_lddqu_si256((__m256i*)p); + initVal = _mm256_min_epu32(initVal, next); + p += width; + } + + // let sum up the final results + const uint32_t* q = (const uint32_t*)&initVal; + EXTRACT_MIN_VAL(q, p, width, remain, v) } } #endif @@ -221,51 +290,27 @@ static float floatVectorCmpAVX(const float* pData, int32_t numOfRows, bool isMin #if __AVX__ __m256 next; - __m256 initialVal = _mm256_loadu_ps(p); + __m256 initVal = _mm256_loadu_ps(p); p += width; if (!isMinFunc) { // max function for (int32_t i = 1; i < rounds; ++i) { next = _mm256_loadu_ps(p); - initialVal = _mm256_max_ps(initialVal, next); + initVal = _mm256_max_ps(initVal, next); p += width; } - // let sum up the final results - const float* q = (const float*)&initialVal; - v = TMAX(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMAX(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + start]) { - v = p[j + start]; - } - } + const float* q = (const float*)&initVal; + EXTRACT_MAX_VAL(q, p, width, remain, v) } else { // min function for (int32_t i = 1; i < rounds; ++i) { next = _mm256_loadu_ps(p); - initialVal = _mm256_min_ps(initialVal, next); + initVal = _mm256_min_ps(initVal, next); p += width; } - // let sum up the final results - const float* q = (const float*)&initialVal; - v = TMIN(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMIN(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + start]) { - v = p[j + start]; - } - } + const float* q = (const float*)&initVal; + EXTRACT_MIN_VAL(q, p, width, remain, v) } #endif @@ -282,366 +327,207 @@ static double doubleVectorCmpAVX(const double* pData, int32_t numOfRows, bool is #if __AVX__ __m256d next; - __m256d initialVal = _mm256_loadu_pd(p); + __m256d initVal = _mm256_loadu_pd(p); p += width; if (!isMinFunc) { // max function for (int32_t i = 1; i < rounds; ++i) { next = _mm256_loadu_pd(p); - initialVal = _mm256_max_pd(initialVal, next); + initVal = _mm256_max_pd(initVal, next); p += width; } // let sum up the final results - const double* q = (const double*)&initialVal; - v = TMAX(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMAX(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v < p[j + start]) { - v = p[j + start]; - } - } + const double* q = (const double*)&initVal; + EXTRACT_MAX_VAL(q, p, width, remain, v) } else { // min function for (int32_t i = 1; i < rounds; ++i) { next = _mm256_loadu_pd(p); - initialVal = _mm256_min_pd(initialVal, next); + initVal = _mm256_min_pd(initVal, next); p += width; } // let sum up the final results - const double* q = (const double*)&initialVal; - v = TMIN(q[0], q[1]); - for (int32_t k = 1; k < width; ++k) { - v = TMIN(v, q[k]); - } - - // calculate the front and the reminder items in array list - int32_t start = rounds * width; - for (int32_t j = 0; j < remain; ++j) { - if (v > p[j + start]) { - v = p[j + start]; - } - } + const double* q = (const double*)&initVal; + EXTRACT_MIN_VAL(q, p, width, remain, v) } #endif return v; } -static int32_t findFirstVal(const SColumnInfoData* pCol, int32_t start, int32_t numOfRows) { +static int32_t findFirstValPosition(const SColumnInfoData* pCol, int32_t start, int32_t numOfRows) { int32_t i = start; - while (i < (start + numOfRows)) { - if (!colDataIsNull_f(pCol->nullbitmap, i)) { - break; - } + + while (i < (start + numOfRows) && (colDataIsNull_f(pCol->nullbitmap, i) == true)) { i += 1; } return i; } -static int32_t handleInt8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, - SMinmaxResInfo* pBuf, bool isMinFunc) { - int8_t* pData = (int8_t*)pCol->pData; - int8_t* val = (int8_t*)&pBuf->v; - - int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows <= 32 || pCtx->subsidiaries.num > 0) { - int32_t i = findFirstVal(pCol, start, numOfRows); - - if ((i < (start + numOfRows)) && (!pBuf->assign)) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - numOfElems += 1; +static void handleInt8Col(const void* data, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc, + bool signVal) { + // AVX2 version to speedup the loop + if (tsAVX2Enable && tsSIMDEnable) { + pBuf->v = i8VectorCmpAVX2(data, numOfRows, isMinFunc, signVal); + } else { + if (!pBuf->assign) { + pBuf->v = ((int8_t*)data)[0]; } - if (isMinFunc) { // min - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } + if (signVal) { + const int8_t* p = (const int8_t*)data; + int8_t* v = (int8_t*)&pBuf->v; - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; + if (isMinFunc) { + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p); } - - } else { // max function - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; - } - - } - } else { // not has null value - // AVX2 version to speedup the loop - if (tsAVX2Enable && tsSIMDEnable) { - *val = i8VectorCmpAVX2(pData, numOfRows, isMinFunc); } else { - if (!pBuf->assign) { - *val = pData[0]; - pBuf->assign = true; - } + const uint8_t* p = (const uint8_t*)data; + uint8_t* v = (uint8_t*)&pBuf->v; - if (isMinFunc) { // min - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val > pData[i]) { - *val = pData[i]; - } - } - } else { // max - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val < pData[i]) { - *val = pData[i]; - } - } + if (isMinFunc) { + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p); } } - - numOfElems = numOfRows; } - return numOfElems; + pBuf->assign = true; } -static int32_t handleInt16Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, - SMinmaxResInfo* pBuf, bool isMinFunc) { - int16_t* pData = (int16_t*)pCol->pData; - int16_t* val = (int16_t*)&pBuf->v; - - int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows <= 16 || pCtx->subsidiaries.num > 0) { - int32_t i = findFirstVal(pCol, start, numOfRows); - - if ((i < (start + numOfRows)) && (!pBuf->assign)) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - numOfElems += 1; +static void handleInt16Col(const void* data, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc, + bool signVal) { + // AVX2 version to speedup the loop + if (tsAVX2Enable && tsSIMDEnable) { + pBuf->v = i16VectorCmpAVX2(data, numOfRows, isMinFunc, signVal); + } else { + if (!pBuf->assign) { + pBuf->v = ((int16_t*)data)[0]; } - if (isMinFunc) { // min - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } + if (signVal) { + const int16_t* p = (const int16_t*)data; + int16_t* v = (int16_t*)&pBuf->v; - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; + if (isMinFunc) { + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p); } - - } else { // max function - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; - } - - } - } else { // not has null value - // AVX2 version to speedup the loop - if (tsAVX2Enable && tsSIMDEnable) { - *val = i16VectorCmpAVX2(pData, numOfRows, isMinFunc); } else { - if (!pBuf->assign) { - *val = pData[0]; - pBuf->assign = true; - } + const uint16_t* p = (const uint16_t*)data; + uint16_t* v = (uint16_t*)&pBuf->v; - if (isMinFunc) { // min - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val > pData[i]) { - *val = pData[i]; - } - } - } else { // max - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val < pData[i]) { - *val = pData[i]; - } - } + if (isMinFunc) { + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p); } } - - numOfElems = numOfRows; } - return numOfElems; + pBuf->assign = true; } -static int32_t handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, - SMinmaxResInfo* pBuf, bool isMinFunc) { - int32_t* pData = (int32_t*)pCol->pData; - int32_t* val = (int32_t*)&pBuf->v; - - int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { - int32_t i = findFirstVal(pCol, start, numOfRows); - - if ((i < (start + numOfRows)) && (!pBuf->assign)) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - numOfElems += 1; +static void handleInt32Col(const void* data, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc, + bool signVal) { + // AVX2 version to speedup the loop + if (tsAVX2Enable && tsSIMDEnable) { + pBuf->v = i32VectorCmpAVX2(data, numOfRows, isMinFunc, signVal); + } else { + if (!pBuf->assign) { + pBuf->v = ((int32_t*)data)[0]; } - if (isMinFunc) { // min - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } + if (signVal) { + const int32_t* p = (const int32_t*)data; + int32_t* v = (int32_t*)&pBuf->v; - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; + if (isMinFunc) { + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p); } - - } else { // max function - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; - } - - } - } else { // not has null value - // AVX2 version to speedup the loop - if (tsAVX2Enable && tsSIMDEnable) { - *val = i32VectorCmpAVX2(pData, numOfRows, isMinFunc); } else { - if (!pBuf->assign) { - *val = pData[0]; - pBuf->assign = true; - } + const uint32_t* p = (const uint32_t*)data; + uint32_t* v = (uint32_t*)&pBuf->v; - if (isMinFunc) { // min - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val > pData[i]) { - *val = pData[i]; - } - } - } else { // max - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val < pData[i]) { - *val = pData[i]; - } - } + if (isMinFunc) { + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p); } } - - numOfElems = numOfRows; } - return numOfElems; + pBuf->assign = true; } -static int32_t handleInt64Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, - SMinmaxResInfo* pBuf, bool isMinFunc) { - int32_t* pData = (int32_t*)pCol->pData; - int32_t* val = (int32_t*)&pBuf->v; +static void handleInt64Col(const void* data, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc, + bool signVal) { + if (!pBuf->assign) { + pBuf->v = ((int64_t*)data)[0]; + } - int32_t numOfElems = 0; - if (pCol->hasNull || pCtx->subsidiaries.num > 0) { - int32_t i = findFirstVal(pCol, start, numOfRows); + if (signVal) { + const int64_t* p = (const int64_t*)data; + int64_t* v = &pBuf->v; - if ((i < (start + numOfRows)) && (!pBuf->assign)) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - numOfElems += 1; + if (isMinFunc) { + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p); } + } else { + const uint64_t* p = (const uint64_t*)data; + uint64_t* v = (uint64_t*)&pBuf->v; - if (isMinFunc) { // min - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; - } - - } else { // max function - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; - } + if (isMinFunc) { + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p); } - } else { // not has null value - // AVX2 version to speedup the loop + } +} + +static void handleUint8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, + bool isMinFunc) { + const uint8_t* pData = (uint8_t*)pCol->pData; + uint8_t* val = (uint8_t*)&pBuf->v; + + // AVX2 version to speedup the loop + if (tsAVX2Enable && tsSIMDEnable) { + *val = i8VectorCmpAVX2(pData, numOfRows, isMinFunc, false); + } else { + if (!pBuf->assign) { + *val = pData[0]; + } + + if (isMinFunc) { // min + __COMPARE_EXTRACT_MIN(start, start + numOfRows, *val, pData); + } else { + __COMPARE_EXTRACT_MAX(start, start + numOfRows, *val, pData); + } + } + + pBuf->assign = true; +} + +static void handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc) { + float* pData = (float*)pCol->pData; + float* val = (float*)&pBuf->v; + + // AVX version to speedup the loop + if (tsAVXEnable && tsSIMDEnable) { + *val = floatVectorCmpAVX(pData, numOfRows, isMinFunc); + } else { if (!pBuf->assign) { *val = pData[0]; - pBuf->assign = true; } if (isMinFunc) { // min @@ -657,169 +543,39 @@ static int32_t handleInt64Col(SColumnInfoData* pCol, int32_t start, int32_t numO } } } - - numOfElems = numOfRows; - } - return numOfElems; -} - -static int32_t handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, - SMinmaxResInfo* pBuf, bool isMinFunc) { - float* pData = (float*)pCol->pData; - float* val = (float*)&pBuf->v; - - int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { - int32_t i = findFirstVal(pCol, start, numOfRows); - if ((i < (start + numOfRows)) && (!pBuf->assign)) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - numOfElems += 1; - } - - if (isMinFunc) { // min - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; - } - } else { // max function - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; - } - } - } else { // not has null value - // AVX version to speedup the loop - if (tsAVXEnable && tsSIMDEnable) { - *val = (double) floatVectorCmpAVX(pData, numOfRows, isMinFunc); - } else { - if (!pBuf->assign) { - *val = pData[0]; - pBuf->assign = true; - } - - if (isMinFunc) { // min - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val > pData[i]) { - *val = pData[i]; - } - } - } else { // max - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val < pData[i]) { - *val = pData[i]; - } - } - } - } - - numOfElems = numOfRows; } - return numOfElems; + pBuf->assign = true; } -static int32_t handleDoubleCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, - SMinmaxResInfo* pBuf, bool isMinFunc) { +static void handleDoubleCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc) { double* pData = (double*)pCol->pData; double* val = (double*)&pBuf->v; - int32_t numOfElems = 0; - if (pCol->hasNull || numOfRows < 4 || pCtx->subsidiaries.num > 0) { - int32_t i = findFirstVal(pCol, start, numOfRows); - - if ((i < (start + numOfRows)) && (!pBuf->assign)) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - numOfElems += 1; + // AVX version to speedup the loop + if (tsAVXEnable && tsSIMDEnable) { + *val = (double)doubleVectorCmpAVX(pData, numOfRows, isMinFunc); + } else { + if (!pBuf->assign) { + *val = pData[0]; } if (isMinFunc) { // min - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - + for (int32_t i = start; i < start + numOfRows; ++i) { if (*val > pData[i]) { *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } } - numOfElems += 1; } - } else { // max function - for (; i < start + numOfRows; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. + } else { // max + for (int32_t i = start; i < start + numOfRows; ++i) { if (*val < pData[i]) { *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - numOfElems += 1; - } - } - } else { // not has null value - // AVX version to speedup the loop - if (tsAVXEnable && tsSIMDEnable) { - *val = (double) doubleVectorCmpAVX(pData, numOfRows, isMinFunc); - } else { - if (!pBuf->assign) { - *val = pData[0]; - pBuf->assign = true; - } - - if (isMinFunc) { // min - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val > pData[i]) { - *val = pData[i]; - } - } - } else { // max - for (int32_t i = start; i < start + numOfRows; ++i) { - if (*val < pData[i]) { - *val = pData[i]; - } } } } - - numOfElems = numOfRows; } - return numOfElems; + pBuf->assign = true; } static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, const char* tval) { @@ -835,6 +591,137 @@ static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, c return -1; } +static void doExtractVal(SColumnInfoData* pCol, int32_t i, int32_t end, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf, + bool isMinFunc) { + if (isMinFunc) { + switch (pCol->info.type) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: { + const int8_t* pData = (const int8_t*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(int8_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_SMALLINT: { + const int16_t* pData = (const int16_t*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(int16_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_INT: { + const int32_t* pData = (const int32_t*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(int32_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_BIGINT: { + const int64_t* pData = (const int64_t*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, (pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_UTINYINT: { + const uint8_t* pData = (const uint8_t*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(uint8_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_USMALLINT: { + const uint16_t* pData = (const uint16_t*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(uint16_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_UINT: { + const uint32_t* pData = (const uint32_t*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(uint32_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_UBIGINT: { + const uint64_t* pData = (const uint64_t*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(uint64_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_FLOAT: { + const float* pData = (const float*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(float*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_DOUBLE: { + const double* pData = (const double*)pCol->pData; + __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(double*)&(pBuf->v), &pBuf->tuplePos) + break; + } + } + } else { + switch (pCol->info.type) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: { + const int8_t* pData = (const int8_t*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(int8_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_SMALLINT: { + const int16_t* pData = (const int16_t*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(int16_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_INT: { + const int16_t* pData = (const int16_t*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(int32_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_BIGINT: { + const int64_t* pData = (const int64_t*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, (pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_UTINYINT: { + const uint8_t* pData = (const uint8_t*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(uint8_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_USMALLINT: { + const uint16_t* pData = (const uint16_t*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(uint16_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_UINT: { + const uint32_t* pData = (const uint32_t*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(uint32_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_UBIGINT: { + const uint64_t* pData = (const uint64_t*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(uint64_t*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_FLOAT: { + const float* pData = (const float*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(float*)&(pBuf->v), &pBuf->tuplePos) + break; + } + + case TSDB_DATA_TYPE_DOUBLE: { + const double* pData = (const double*)pCol->pData; + __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(double*)&(pBuf->v), &pBuf->tuplePos) + break; + } + } + } +} + int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { int32_t numOfElems = 0; @@ -857,6 +744,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { if (pInput->colDataSMAIsSet) { numOfElems = pInput->numOfRows - pAgg->numOfNull; ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0); + if (numOfElems == 0) { return numOfElems; } @@ -945,212 +833,80 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { int32_t start = pInput->startRowIndex; int32_t numOfRows = pInput->numOfRows; + int32_t end = start + numOfRows; - if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) { - if (type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_BOOL) { - numOfElems = handleInt8Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); - } else if (type == TSDB_DATA_TYPE_SMALLINT) { - numOfElems = handleInt16Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); - } else if (type == TSDB_DATA_TYPE_INT) { - numOfElems = handleInt32Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); - } else if (type == TSDB_DATA_TYPE_BIGINT) { - numOfElems = handleInt64Col(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); + if (pCol->hasNull || numOfRows < 32 || pCtx->subsidiaries.num > 0) { + int32_t i = findFirstValPosition(pCol, start, numOfRows); + + if ((i < end) && (!pBuf->assign)) { + memcpy(&pBuf->v, pCol->pData + (pCol->info.bytes * i), pCol->info.bytes); + + if (pCtx->subsidiaries.num > 0) { + pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); + } + pBuf->assign = true; + numOfElems = 1; } - } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - if (type == TSDB_DATA_TYPE_UTINYINT) { - uint8_t* pData = (uint8_t*)pCol->pData; - uint8_t* val = (uint8_t*)&pBuf->v; - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } + if (i >= end) { + ASSERT(numOfElems == 0); + return numOfElems; + } - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } + doExtractVal(pCol, i, end, pCtx, pBuf, isMinFunc); + } else { + numOfElems = numOfRows; - numOfElems += 1; + switch(pCol->info.type) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: { + handleInt8Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, true); + break; } - } else if (type == TSDB_DATA_TYPE_USMALLINT) { - uint16_t* pData = (uint16_t*)pCol->pData; - uint16_t* val = (uint16_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; + case TSDB_DATA_TYPE_SMALLINT: { + handleInt16Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, true); + break; } - } else if (type == TSDB_DATA_TYPE_UINT) { - uint32_t* pData = (uint32_t*)pCol->pData; - uint32_t* val = (uint32_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; + case TSDB_DATA_TYPE_INT: { + handleInt32Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, true); + break; } - } else if (type == TSDB_DATA_TYPE_UBIGINT) { - uint64_t* pData = (uint64_t*)pCol->pData; - uint64_t* val = (uint64_t*)&pBuf->v; - - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; + case TSDB_DATA_TYPE_BIGINT: { + handleInt64Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, true); + break; + } + case TSDB_DATA_TYPE_UTINYINT: { + handleInt8Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false); + break; + } + case TSDB_DATA_TYPE_USMALLINT: { + handleInt16Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false); + break; + } + case TSDB_DATA_TYPE_UINT: { + handleInt16Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false); + break; + } + case TSDB_DATA_TYPE_UBIGINT: { + handleInt16Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false); + break; + } + case TSDB_DATA_TYPE_FLOAT: { + handleFloatCol(pCol, start, numOfRows, pBuf, isMinFunc); + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + handleDoubleCol(pCol, start, numOfRows, pBuf, isMinFunc); + break; } } - } else if (type == TSDB_DATA_TYPE_DOUBLE) { - double* pData = (double*)pCol->pData; - double* val = (double*)&pBuf->v; - for (int32_t i = start; i < start + numOfRows; ++i) { - if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { - continue; - } - - if (!pBuf->assign) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); - } - pBuf->assign = true; - } else { - // ignore the equivalent data value - // NOTE: An faster version to avoid one additional comparison with FPU. - if (isMinFunc) { // min - if (*val > pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } else { // max - if (*val < pData[i]) { - *val = pData[i]; - if (pCtx->subsidiaries.num > 0) { - updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); - } - } - } - } - - numOfElems += 1; + _over: + if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { + pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); + pBuf->nullTupleSaved = true; } - } else if (type == TSDB_DATA_TYPE_FLOAT) { - numOfElems = handleFloatCol(pCol, start, numOfRows, pCtx, pBuf, isMinFunc); } -_over: - if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { - pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); - pBuf->nullTupleSaved = true; - } return numOfElems; } \ No newline at end of file From 969331c49e337a3f346c82a2f1c47c6cd56b5267 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 25 Nov 2022 11:14:17 +0800 Subject: [PATCH 46/66] refactor: do some internal refactor. --- source/libs/function/src/detail/tminmax.c | 41 +++++------------------ 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index 03438350ed..e07cd38b65 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -495,29 +495,6 @@ static void handleInt64Col(const void* data, int32_t start, int32_t numOfRows, S } } -static void handleUint8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, - bool isMinFunc) { - const uint8_t* pData = (uint8_t*)pCol->pData; - uint8_t* val = (uint8_t*)&pBuf->v; - - // AVX2 version to speedup the loop - if (tsAVX2Enable && tsSIMDEnable) { - *val = i8VectorCmpAVX2(pData, numOfRows, isMinFunc, false); - } else { - if (!pBuf->assign) { - *val = pData[0]; - } - - if (isMinFunc) { // min - __COMPARE_EXTRACT_MIN(start, start + numOfRows, *val, pData); - } else { - __COMPARE_EXTRACT_MAX(start, start + numOfRows, *val, pData); - } - } - - pBuf->assign = true; -} - static void handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc) { float* pData = (float*)pCol->pData; float* val = (float*)&pBuf->v; @@ -746,7 +723,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0); if (numOfElems == 0) { - return numOfElems; + goto _over; } void* tval = NULL; @@ -857,7 +834,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { } else { numOfElems = numOfRows; - switch(pCol->info.type) { + switch (pCol->info.type) { case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT: { handleInt8Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, true); @@ -884,11 +861,11 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { break; } case TSDB_DATA_TYPE_UINT: { - handleInt16Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false); + handleInt32Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false); break; } case TSDB_DATA_TYPE_UBIGINT: { - handleInt16Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false); + handleInt64Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false); break; } case TSDB_DATA_TYPE_FLOAT: { @@ -900,12 +877,12 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { break; } } + } - _over: - if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { - pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); - pBuf->nullTupleSaved = true; - } +_over: + if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { + pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); + pBuf->nullTupleSaved = true; } return numOfElems; From f8bc4df4afe96690789e279009f57845aca0462e Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 25 Nov 2022 11:58:46 +0800 Subject: [PATCH 47/66] refactor: do some internal refactor. --- source/dnode/vnode/inc/vnode.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 149c3fbaa9..e25c899036 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -108,9 +108,11 @@ int metaGetTableNameByUid(void *meta, uint64_t uid, char *tbName); int metaGetTableUidByName(void *meta, char *tbName, uint64_t *uid); int metaGetTableTypeByName(void *meta, char *tbName, ETableType *tbType); bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid); -int32_t metaGetCachedTableUidList(SMeta *pMeta, tb_uid_t suid, const uint8_t *key, int32_t keyLen, SArray *pList, bool* acquired); +int32_t metaGetCachedTableUidList(SMeta *pMeta, tb_uid_t suid, const uint8_t *key, int32_t keyLen, SArray *pList, + bool *acquired); int32_t metaUidFilterCachePut(SMeta *pMeta, uint64_t suid, const void *pKey, int32_t keyLen, void *pPayload, int32_t payloadLen, double selectivityRatio); +int32_t metaUidCacheClear(SMeta *pMeta, uint64_t suid); typedef struct SMetaFltParam { tb_uid_t suid; From 59a15719451eea1e32b23ee1e7852c20569a5d7b Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Fri, 25 Nov 2022 18:56:00 +0800 Subject: [PATCH 48/66] fix(meta/cache): invalidate suid cache when create/drop ctb & update tag --- source/dnode/vnode/src/meta/metaTable.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index 4d0a0a50a4..dff8adf29b 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -458,6 +458,7 @@ int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMe metaWLock(pMeta); metaUpdateStbStats(pMeta, me.ctbEntry.suid, 1); + metaUidCacheClear(pMeta, me.ctbEntry.suid); metaULock(pMeta); } else { me.ntbEntry.ctime = pReq->ctime; @@ -681,6 +682,7 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) { --pMeta->pVnode->config.vndStats.numOfCTables; metaUpdateStbStats(pMeta, e.ctbEntry.suid, -1); + metaUidCacheClear(pMeta, e.ctbEntry.suid); } else if (e.type == TSDB_NORMAL_TABLE) { // drop schema.db (todo) @@ -691,6 +693,7 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) { // drop schema.db (todo) metaStatsCacheDrop(pMeta, uid); + metaUidCacheClear(pMeta, uid); --pMeta->pVnode->config.vndStats.numOfSTables; } @@ -1069,6 +1072,8 @@ static int metaUpdateTableTagVal(SMeta *pMeta, int64_t version, SVAlterTbReq *pA tdbTbUpsert(pMeta->pCtbIdx, &ctbIdxKey, sizeof(ctbIdxKey), ctbEntry.ctbEntry.pTags, ((STag *)(ctbEntry.ctbEntry.pTags))->len, &pMeta->txn); + metaUidCacheClear(pMeta, ctbEntry.ctbEntry.suid); + metaULock(pMeta); tDecoderClear(&dc1); From d77f5fa70c001a5c756edb3cec91441fec57fb53 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 25 Nov 2022 22:54:54 +0800 Subject: [PATCH 49/66] fix(query): fix error in windows and darwin system. --- include/os/os.h | 2 +- include/util/tpagedbuf.h | 7 ++----- source/os/src/osMemory.c | 4 ++++ source/util/src/tpagedbuf.c | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/os/os.h b/include/os/os.h index 0334cd4d95..ab4d0a406e 100644 --- a/include/os/os.h +++ b/include/os/os.h @@ -43,6 +43,7 @@ extern "C" { #include #include #include +#include #if defined(DARWIN) #else @@ -81,7 +82,6 @@ extern "C" { #include #include #include -#include #if __AVX__ #include diff --git a/include/util/tpagedbuf.h b/include/util/tpagedbuf.h index 5f81ccfcfd..73af65997d 100644 --- a/include/util/tpagedbuf.h +++ b/include/util/tpagedbuf.h @@ -24,12 +24,9 @@ extern "C" { #endif -typedef struct SArray* SIDList; typedef struct SPageInfo SPageInfo; typedef struct SDiskbasedBuf SDiskbasedBuf; -#define DEFAULT_INTERN_BUF_PAGE_SIZE (1024LL) // in bytes - typedef struct SFilePage { int32_t num; char data[]; @@ -69,7 +66,7 @@ void* getNewBufPage(SDiskbasedBuf* pBuf, int32_t* pageId); * @param pBuf * @return */ -SIDList getDataBufPagesIdList(SDiskbasedBuf* pBuf); +SArray* getDataBufPagesIdList(SDiskbasedBuf* pBuf); /** * get the specified buffer page by id @@ -111,7 +108,7 @@ void destroyDiskbasedBuf(SDiskbasedBuf* pBuf); * @param pList * @return */ -SPageInfo* getLastPageInfo(SIDList pList); +SPageInfo* getLastPageInfo(SArray* pList); /** * diff --git a/source/os/src/osMemory.c b/source/os/src/osMemory.c index 1facff1f3b..2f30e8977a 100644 --- a/source/os/src/osMemory.c +++ b/source/os/src/osMemory.c @@ -350,6 +350,10 @@ void* taosMemoryMallocAlign(uint32_t alignment, int64_t size) { #ifdef USE_TD_MEMORY ASSERT(0); #else +#if defined(LINUX) return memalign(alignment, size); +#else + return taosMemoryMalloc(size); +#endif #endif } diff --git a/source/util/src/tpagedbuf.c b/source/util/src/tpagedbuf.c index 79ea10552c..e1a43ace47 100644 --- a/source/util/src/tpagedbuf.c +++ b/source/util/src/tpagedbuf.c @@ -495,7 +495,7 @@ void releaseBufPageInfo(SDiskbasedBuf* pBuf, SPageInfo* pi) { size_t getTotalBufSize(const SDiskbasedBuf* pBuf) { return (size_t)pBuf->totalBufSize; } -SIDList getDataBufPagesIdList(SDiskbasedBuf* pBuf) { +SArray* getDataBufPagesIdList(SDiskbasedBuf* pBuf) { ASSERT(pBuf != NULL); return pBuf->pIdList; } @@ -561,7 +561,7 @@ void destroyDiskbasedBuf(SDiskbasedBuf* pBuf) { taosMemoryFreeClear(pBuf); } -SPageInfo* getLastPageInfo(SIDList pList) { +SPageInfo* getLastPageInfo(SArray* pList) { size_t size = taosArrayGetSize(pList); SPageInfo* pPgInfo = taosArrayGetP(pList, size - 1); return pPgInfo; From 86fda9f3da231bbecc4e97ddcb9d1927a29666a4 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 25 Nov 2022 23:06:32 +0800 Subject: [PATCH 50/66] fix(query): fix error in windows and darwin system. --- source/libs/executor/src/executorimpl.c | 2 +- source/libs/function/src/tpercentile.c | 2 +- source/util/test/pageBufferTest.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 49471dc959..9ad0aae3e4 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -244,7 +244,7 @@ static int32_t addNewWindowResultBuf(SResultRow* pWindowRes, SDiskbasedBuf* pRes // in the first scan, new space needed for results int32_t pageId = -1; - SIDList list = getDataBufPagesIdList(pResultBuf); + SArray* list = getDataBufPagesIdList(pResultBuf); if (taosArrayGetSize(list) == 0) { pData = getNewBufPage(pResultBuf, &pageId); diff --git a/source/libs/function/src/tpercentile.c b/source/libs/function/src/tpercentile.c index 0924106476..e5727f1472 100644 --- a/source/libs/function/src/tpercentile.c +++ b/source/libs/function/src/tpercentile.c @@ -494,7 +494,7 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction) resetSlotInfo(pMemBucket); int32_t groupId = getGroupId(pMemBucket->numOfSlots, i, pMemBucket->times - 1); - SIDList list = taosHashGet(pMemBucket->groupPagesMap, &groupId, sizeof(groupId)); + SArray* list = taosHashGet(pMemBucket->groupPagesMap, &groupId, sizeof(groupId)); ASSERT(list != NULL && list->size > 0); for (int32_t f = 0; f < list->size; ++f) { diff --git a/source/util/test/pageBufferTest.cpp b/source/util/test/pageBufferTest.cpp index 869bb2a76d..00ed804930 100644 --- a/source/util/test/pageBufferTest.cpp +++ b/source/util/test/pageBufferTest.cpp @@ -23,7 +23,7 @@ void simpleTest() { ASSERT_EQ(getTotalBufSize(pBuf), 1024); - SIDList list = getDataBufPagesIdList(pBuf); + SArray* list = getDataBufPagesIdList(pBuf); ASSERT_EQ(taosArrayGetSize(list), 1); // ASSERT_EQ(getNumOfBufGroupId(pBuf), 1); From 99ea0abffa13020f7b1035c36cf1df7f2f5892c5 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 25 Nov 2022 23:09:31 +0800 Subject: [PATCH 51/66] fix(query): add return value. --- source/os/src/osSysinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/os/src/osSysinfo.c b/source/os/src/osSysinfo.c index 93eebd2437..f336b84e1e 100644 --- a/source/os/src/osSysinfo.c +++ b/source/os/src/osSysinfo.c @@ -504,9 +504,9 @@ int32_t taosGetCpuInstructions(char* sse42, char* avx, char* avx2, char* fma) { // Ref to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77756 __cpuid_fix(7u, eax, ebx, ecx, edx); *avx2 = (char) ((ebx & bit_AVX2) == bit_AVX2); - return 0; - #endif + + return 0; } int32_t taosGetTotalMemory(int64_t *totalKB) { From f9d1726c890471b0f0339e560ac76189134f3434 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Fri, 25 Nov 2022 23:27:36 +0800 Subject: [PATCH 52/66] fix(query): fix error in ut. --- include/util/thash.h | 2 +- source/dnode/mgmt/test/sut/src/client.cpp | 1 + source/libs/parser/test/mockCatalogService.cpp | 2 +- source/libs/scheduler/test/schedulerTests.cpp | 1 + source/libs/transport/test/transUT.cpp | 2 ++ source/util/src/thash.c | 2 +- 6 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/util/thash.h b/include/util/thash.h index a04f78a3d1..08caad495d 100644 --- a/include/util/thash.h +++ b/include/util/thash.h @@ -213,7 +213,7 @@ void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp); */ void taosHashSetFreeFp(SHashObj *pHashObj, _hash_free_fn_t fp); -//int64_t taosHashGetCompTimes(SHashObj *pHashObj); +int64_t taosHashGetCompTimes(SHashObj *pHashObj); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/test/sut/src/client.cpp b/source/dnode/mgmt/test/sut/src/client.cpp index 6b4c23c0de..a27a511651 100644 --- a/source/dnode/mgmt/test/sut/src/client.cpp +++ b/source/dnode/mgmt/test/sut/src/client.cpp @@ -15,6 +15,7 @@ #include "sut.h" #include "tdatablock.h" +#include "tmisce.h" static void processClientRsp(void* parent, SRpcMsg* pRsp, SEpSet* pEpSet) { TestClient* client = (TestClient*)parent; diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index 95f7af435d..be2e4b90b9 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -20,9 +20,9 @@ #include #include -#include "tdatablock.h" #include "tname.h" #include "ttypes.h" +#include "tmisce.h" std::unique_ptr g_mockCatalogService; diff --git a/source/libs/scheduler/test/schedulerTests.cpp b/source/libs/scheduler/test/schedulerTests.cpp index 97e14b617c..5605a4b842 100644 --- a/source/libs/scheduler/test/schedulerTests.cpp +++ b/source/libs/scheduler/test/schedulerTests.cpp @@ -38,6 +38,7 @@ #include "tglobal.h" #include "trpc.h" #include "tvariant.h" +#include "tmisce.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wwrite-strings" diff --git a/source/libs/transport/test/transUT.cpp b/source/libs/transport/test/transUT.cpp index 92f0bf11cf..88a1e2564f 100644 --- a/source/libs/transport/test/transUT.cpp +++ b/source/libs/transport/test/transUT.cpp @@ -20,6 +20,8 @@ #include "tlog.h" #include "transLog.h" #include "trpc.h" +#include "tmisce.h" + using namespace std; const char *label = "APP"; diff --git a/source/util/src/thash.c b/source/util/src/thash.c index fe6c0a8af5..a0411483ca 100644 --- a/source/util/src/thash.c +++ b/source/util/src/thash.c @@ -889,4 +889,4 @@ void *taosHashAcquire(SHashObj *pHashObj, const void *key, size_t keyLen) { void taosHashRelease(SHashObj *pHashObj, void *p) { taosHashCancelIterate(pHashObj, p); } -//int64_t taosHashGetCompTimes(SHashObj *pHashObj) { return atomic_load_64(&pHashObj->compTimes); } +int64_t taosHashGetCompTimes(SHashObj *pHashObj) { return 0 /*atomic_load_64(&pHashObj->compTimes)*/; } From c6795b68d2a98eec103a4e3d3f9d4e97648571be Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 00:12:27 +0800 Subject: [PATCH 53/66] fix(query): check list size before iterate it. --- source/dnode/vnode/src/meta/metaCache.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 05b6209c56..4aa6ed3744 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -519,20 +519,20 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int // remove the lru cache that are expired due to the tags value update, or creating, or dropping, of child tables int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) { STagFilterResEntry* pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); - if (pEntry == NULL) { + if (pEntry == NULL || listNEles(&pEntry->list) == 0) { return TSDB_CODE_SUCCESS; } - int32_t keyLen = sizeof(uint64_t) + 128; - char* p = taosMemoryMalloc(keyLen); - *(uint64_t*)p = pEntry->suid; + int32_t keyLen = sizeof(uint64_t) * 3; + uint64_t p[3] = {0}; + p[0] = suid; SListIter iter = {0}; tdListInitIter(&pEntry->list, &iter, TD_LIST_FORWARD); SListNode* pNode = NULL; while ((pNode = tdListNext(&iter)) != NULL) { - memcpy(p + sizeof(suid), pNode->data, 128); + memcpy(&p[1], pNode->data, 16); taosLRUCacheErase(pMeta->pCache->sTagFilterResCache.pUidResCache, p, keyLen); } From 802ca0f607ff7d8241ebf0765f04987f710f6bf9 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 00:58:29 +0800 Subject: [PATCH 54/66] fix(query): fix memory leak. --- source/dnode/vnode/src/meta/metaCache.c | 7 +++++++ source/libs/executor/src/executil.c | 1 + 2 files changed, 8 insertions(+) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 4aa6ed3744..45f70e1c92 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -90,6 +90,12 @@ static void statsCacheClose(SMeta* pMeta) { } } +static void freeCacheEntryFp(void* param) { + STagFilterResEntry** p = param; + tdListEmpty(&(*p)->list); + taosMemoryFreeClear(*p); +} + int32_t metaCacheOpen(SMeta* pMeta) { int32_t code = 0; SMetaCache* pCache = NULL; @@ -132,6 +138,7 @@ int32_t metaCacheOpen(SMeta* pMeta) { goto _err2; } + taosHashSetFreeFp(pCache->sTagFilterResCache.pTableEntry, freeCacheEntryFp); pMeta->pCache = pCache; return code; diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 6ee2dce59b..21fba22af4 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1017,6 +1017,7 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, size, 1); + taosMemoryFree(pPayload); } else { qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t) taosArrayGetSize(res)); } From 98771bb461ce1b8aaa3ee5f4973c7d96b76fb728 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 01:50:17 +0800 Subject: [PATCH 55/66] fix(query): deprecate the error reported by asan. --- source/dnode/vnode/src/meta/metaCache.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 45f70e1c92..c590f0d014 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -497,17 +497,17 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int SLRUCache* pCache = pMeta->pCache->sTagFilterResCache.pUidResCache; SHashObj* pTableEntry = pMeta->pCache->sTagFilterResCache.pTableEntry; - void* pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); + STagFilterResEntry** pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); if (pEntry == NULL) { STagFilterResEntry* p = taosMemoryMalloc(sizeof(STagFilterResEntry)); p->qTimes = 0; tdListInit(&p->list, keyLen); - - pEntry = &p; - taosHashPut(pTableEntry, &suid, sizeof(uint64_t), pEntry, POINTER_BYTES); + taosHashPut(pTableEntry, &suid, sizeof(uint64_t), &p, POINTER_BYTES); + tdListAppend(&p->list, pKey); + } else { + tdListAppend(&(*pEntry)->list, pKey); } - tdListAppend(&(*(STagFilterResEntry**)pEntry)->list, pKey); uint64_t* pBuf = pMeta->pCache->sTagFilterResCache.keyBuf; pBuf[0] = suid; From 0015e65f5b2e89d8ff6b37d180c9a1f9fe615fb7 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 02:13:46 +0800 Subject: [PATCH 56/66] fix(query): remove invalid free --- source/dnode/vnode/src/meta/metaCache.c | 1 - source/libs/executor/src/executil.c | 1 - 2 files changed, 2 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index c590f0d014..fa803627ea 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -508,7 +508,6 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int tdListAppend(&(*pEntry)->list, pKey); } - uint64_t* pBuf = pMeta->pCache->sTagFilterResCache.keyBuf; pBuf[0] = suid; diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 21fba22af4..6ee2dce59b 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -1017,7 +1017,6 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, size, 1); - taosMemoryFree(pPayload); } else { qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t) taosArrayGetSize(res)); } From 861b9b82642f40967722e6fa91bc986a2fbbe516 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 11:46:36 +0800 Subject: [PATCH 57/66] fix(query): fix memory leak. --- source/dnode/vnode/src/meta/metaCache.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index fa803627ea..5277e25d4a 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -443,6 +443,7 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK taosArrayAddBatch(pList1, p + sizeof(int32_t), size); (*pEntry)->qTimes += 1; + taosLRUCacheRelease(pCache, pHandle, false); // check if scanning all items are necessary or not if ((*pEntry)->qTimes >= 5000 && TD_DLIST_NELES(&(*pEntry)->list) > 10) { @@ -478,12 +479,20 @@ int32_t metaGetCachedTableUidList(SMeta* pMeta, tb_uid_t suid, const uint8_t* pK return TSDB_CODE_SUCCESS; } +static void freePayload(const void* key, size_t keyLen, void* value) { + if (value == NULL) { + return; + } + taosMemoryFree(value); +} + // check both the payload size and selectivity ratio int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int32_t keyLen, void* pPayload, int32_t payloadLen, double selectivityRatio) { if (selectivityRatio > tsSelectivityRatio) { metaDebug("vgId:%d, suid:%" PRIu64 " failed to add to uid list cache, due to selectivity ratio %.2f less than threshold %.2f", TD_VID(pMeta->pVnode), suid, selectivityRatio, tsSelectivityRatio); + taosMemoryFree(pPayload); return TSDB_CODE_SUCCESS; } @@ -491,13 +500,14 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int metaDebug("vgId:%d, suid:%" PRIu64 " failed to add to uid list cache, due to payload length %d greater than threshold %d", TD_VID(pMeta->pVnode), suid, payloadLen, tsTagFilterResCacheSize); + taosMemoryFree(pPayload); return TSDB_CODE_SUCCESS; } SLRUCache* pCache = pMeta->pCache->sTagFilterResCache.pUidResCache; - SHashObj* pTableEntry = pMeta->pCache->sTagFilterResCache.pTableEntry; + SHashObj* pTableEntry = pMeta->pCache->sTagFilterResCache.pTableEntry; - STagFilterResEntry** pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); + STagFilterResEntry** pEntry = taosHashGet(pTableEntry, &suid, sizeof(uint64_t)); if (pEntry == NULL) { STagFilterResEntry* p = taosMemoryMalloc(sizeof(STagFilterResEntry)); p->qTimes = 0; @@ -515,7 +525,7 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int ASSERT(sizeof(uint64_t) + keyLen == 24); // add to cache. - taosLRUCacheInsert(pCache, pBuf, sizeof(uint64_t) + keyLen, pPayload, payloadLen, NULL, NULL, TAOS_LRU_PRIORITY_LOW); + taosLRUCacheInsert(pCache, pBuf, sizeof(uint64_t) + keyLen, pPayload, payloadLen, freePayload, NULL, TAOS_LRU_PRIORITY_LOW); metaDebug("vgId:%d, suid:%"PRIu64" list cache added into cache, total:%d, tables:%d", TD_VID(pMeta->pVnode), suid, (int32_t) taosLRUCacheGetUsage(pCache), taosHashGetSize(pTableEntry)); From 60d6b8e2eec0b0b852c3b276a37aeff8545d69b0 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 11:51:15 +0800 Subject: [PATCH 58/66] fix(query): change the ptr --- source/dnode/vnode/src/meta/metaCache.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaCache.c b/source/dnode/vnode/src/meta/metaCache.c index 5277e25d4a..6a704d0425 100644 --- a/source/dnode/vnode/src/meta/metaCache.c +++ b/source/dnode/vnode/src/meta/metaCache.c @@ -534,8 +534,8 @@ int32_t metaUidFilterCachePut(SMeta* pMeta, uint64_t suid, const void* pKey, int // remove the lru cache that are expired due to the tags value update, or creating, or dropping, of child tables int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) { - STagFilterResEntry* pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); - if (pEntry == NULL || listNEles(&pEntry->list) == 0) { + STagFilterResEntry** pEntry = taosHashGet(pMeta->pCache->sTagFilterResCache.pTableEntry, &suid, sizeof(uint64_t)); + if (pEntry == NULL || listNEles(&(*pEntry)->list) == 0) { return TSDB_CODE_SUCCESS; } @@ -544,7 +544,7 @@ int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) { p[0] = suid; SListIter iter = {0}; - tdListInitIter(&pEntry->list, &iter, TD_LIST_FORWARD); + tdListInitIter(&(*pEntry)->list, &iter, TD_LIST_FORWARD); SListNode* pNode = NULL; while ((pNode = tdListNext(&iter)) != NULL) { @@ -552,8 +552,8 @@ int32_t metaUidCacheClear(SMeta* pMeta, uint64_t suid) { taosLRUCacheErase(pMeta->pCache->sTagFilterResCache.pUidResCache, p, keyLen); } - pEntry->qTimes = 0; - tdListEmpty(&pEntry->list); + (*pEntry)->qTimes = 0; + tdListEmpty(&(*pEntry)->list); return TSDB_CODE_SUCCESS; } From 257137e55e814dc2988389020cd8657e418e49b4 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 12:15:49 +0800 Subject: [PATCH 59/66] fix(query): fix memory leak. --- source/libs/executor/src/executil.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 6ee2dce59b..c072a5f1aa 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -985,6 +985,8 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, tMD5Init(&context); tMD5Update(&context, (uint8_t*)payload, (uint32_t)len); tMD5Final(&context); + + taosMemoryFree(payload); } bool acquired = false; From 965ee9a6c8067dd63b4bd32c8752beb1f6e3d530 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 15:32:36 +0800 Subject: [PATCH 60/66] fix(query): keep block order in exchange operator. --- source/libs/executor/src/exchangeoperator.c | 16 +++++++++++----- source/libs/executor/src/tsort.c | 2 +- source/libs/function/src/detail/tminmax.c | 2 +- source/util/src/tarray.c | 2 ++ tests/script/tsim/parser/select_with_tags.sim | 3 +++ 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/source/libs/executor/src/exchangeoperator.c b/source/libs/executor/src/exchangeoperator.c index 52aa3db0fd..0efdeca5b6 100644 --- a/source/libs/executor/src/exchangeoperator.c +++ b/source/libs/executor/src/exchangeoperator.c @@ -182,10 +182,15 @@ static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) { } // we have buffered retrieved datablock, return it directly - SSDataBlock** p = taosArrayPop(pExchangeInfo->pResultBlockList); + SSDataBlock* p = NULL; + if (taosArrayGetSize(pExchangeInfo->pResultBlockList) > 0) { + p = taosArrayGetP(pExchangeInfo->pResultBlockList, 0); + taosArrayRemove(pExchangeInfo->pResultBlockList, 0); + } + if (p != NULL) { - taosArrayPush(pExchangeInfo->pRecycledBlocks, p); - return *p; + taosArrayPush(pExchangeInfo->pRecycledBlocks, &p); + return p; } else { if (pExchangeInfo->seqLoadData) { seqLoadRemoteData(pOperator); @@ -196,9 +201,10 @@ static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) { if (taosArrayGetSize(pExchangeInfo->pResultBlockList) == 0) { return NULL; } else { - p = taosArrayPop(pExchangeInfo->pResultBlockList); + p = taosArrayGetP(pExchangeInfo->pResultBlockList, 0); + taosArrayRemove(pExchangeInfo->pResultBlockList, 0); taosArrayPush(pExchangeInfo->pRecycledBlocks, p); - return *p; + return p; } } } diff --git a/source/libs/executor/src/tsort.c b/source/libs/executor/src/tsort.c index 02f2b15a8f..e0a0b9442e 100644 --- a/source/libs/executor/src/tsort.c +++ b/source/libs/executor/src/tsort.c @@ -801,7 +801,7 @@ STupleHandle* tsortNextTuple(SSortHandle* pHandle) { index = tMergeTreeGetChosenIndex(pHandle->pMergeTree); pSource = pHandle->cmpParam.pSources[index]; - assert(pSource->src.pBlock != NULL); + ASSERT(pSource->src.pBlock != NULL); pHandle->tupleHandle.rowIndex = pSource->src.rowIndex; pHandle->tupleHandle.pBlock = pSource->src.pBlock; diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index e07cd38b65..46e68f46ec 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -649,7 +649,7 @@ static void doExtractVal(SColumnInfoData* pCol, int32_t i, int32_t end, SqlFunct } case TSDB_DATA_TYPE_INT: { - const int16_t* pData = (const int16_t*)pCol->pData; + const int32_t* pData = (const int32_t*)pCol->pData; __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(int32_t*)&(pBuf->v), &pBuf->tuplePos) break; } diff --git a/source/util/src/tarray.c b/source/util/src/tarray.c index 5703d8f8f4..bcf9a77950 100644 --- a/source/util/src/tarray.c +++ b/source/util/src/tarray.c @@ -17,6 +17,8 @@ #include "tarray.h" #include "tcoding.h" +// todo refactor API + SArray* taosArrayInit(size_t size, size_t elemSize) { assert(elemSize > 0); diff --git a/tests/script/tsim/parser/select_with_tags.sim b/tests/script/tsim/parser/select_with_tags.sim index 62f1771f03..0e777de7e8 100644 --- a/tests/script/tsim/parser/select_with_tags.sim +++ b/tests/script/tsim/parser/select_with_tags.sim @@ -396,7 +396,10 @@ if $row != 12800 then return -1 endi +print $data00 , $data01 + if $data00 != @select_tags_tb0@ then + print expect select_tags_tb0 , actual: $data00 return -1 endi From 9997ff9adaf5f8fe76de4ea3b62ac8fca6b56dd5 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 15:33:53 +0800 Subject: [PATCH 61/66] fix(query): fix one typo --- source/libs/executor/src/exchangeoperator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/executor/src/exchangeoperator.c b/source/libs/executor/src/exchangeoperator.c index 0efdeca5b6..de918e0034 100644 --- a/source/libs/executor/src/exchangeoperator.c +++ b/source/libs/executor/src/exchangeoperator.c @@ -203,7 +203,7 @@ static SSDataBlock* doLoadRemoteDataImpl(SOperatorInfo* pOperator) { } else { p = taosArrayGetP(pExchangeInfo->pResultBlockList, 0); taosArrayRemove(pExchangeInfo->pResultBlockList, 0); - taosArrayPush(pExchangeInfo->pRecycledBlocks, p); + taosArrayPush(pExchangeInfo->pRecycledBlocks, &p); return p; } } From 0948216ca90755b958e4d6181b19320488d66c30 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sat, 26 Nov 2022 21:13:34 +0800 Subject: [PATCH 62/66] fix(query): fix dead lock. --- source/dnode/vnode/inc/vnode.h | 1 + source/dnode/vnode/src/meta/metaQuery.c | 6 ++++-- source/dnode/vnode/src/meta/metaSma.c | 2 +- source/dnode/vnode/src/sma/smaRollup.c | 4 ++-- source/dnode/vnode/src/tq/tqExec.c | 2 +- source/dnode/vnode/src/tq/tqRead.c | 2 +- source/dnode/vnode/src/tsdb/tsdbCache.c | 2 +- source/dnode/vnode/src/tsdb/tsdbRead.c | 4 ++-- source/libs/executor/src/executil.c | 4 ++-- source/libs/executor/src/executor.c | 2 +- source/libs/executor/src/executorimpl.c | 4 ++-- source/libs/executor/src/scanoperator.c | 4 ++-- source/libs/executor/src/sysscanoperator.c | 7 +++++++ 13 files changed, 27 insertions(+), 17 deletions(-) diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index e25c899036..7ef3207b4d 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -99,6 +99,7 @@ void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags); void metaReaderReleaseLock(SMetaReader *pReader); void metaReaderClear(SMetaReader *pReader); int32_t metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid); +int32_t metaGetTableEntryByUidCache(SMetaReader *pReader, tb_uid_t uid); int metaGetTableEntryByName(SMetaReader *pReader, const char *name); int32_t metaGetTableTags(SMeta *pMeta, uint64_t suid, SArray *uidList, SHashObj *tags); int32_t metaGetTableTagsByUids(SMeta *pMeta, int64_t suid, SArray *uidList, SHashObj *tags); diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 0f409eecd9..0257aede3d 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -153,7 +153,6 @@ bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid) { int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) { SMeta *pMeta = pReader->pMeta; - /* int64_t version1; // query uid.idx @@ -164,7 +163,10 @@ int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) { version1 = ((SUidIdxVal *)pReader->pBuf)[0].version; return metaGetTableEntryByVersion(pReader, version1, uid); - */ +} + +int metaGetTableEntryByUidCache(SMetaReader *pReader, tb_uid_t uid) { + SMeta *pMeta = pReader->pMeta; SMetaInfo info; if (metaGetInfo(pMeta, uid, &info, pReader) == TSDB_CODE_NOT_FOUND) { diff --git a/source/dnode/vnode/src/meta/metaSma.c b/source/dnode/vnode/src/meta/metaSma.c index 3ada7d1814..52452bf710 100644 --- a/source/dnode/vnode/src/meta/metaSma.c +++ b/source/dnode/vnode/src/meta/metaSma.c @@ -36,7 +36,7 @@ int32_t metaCreateTSma(SMeta *pMeta, int64_t version, SSmaCfg *pCfg) { // validate req // save smaIndex metaReaderInit(&mr, pMeta, 0); - if (metaGetTableEntryByUid(&mr, pCfg->indexUid) == 0) { + if (metaGetTableEntryByUidCache(&mr, pCfg->indexUid) == 0) { #if 1 terrno = TSDB_CODE_TSMA_ALREADY_EXIST; metaReaderClear(&mr); diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c index 75fb566438..c5f040c987 100644 --- a/source/dnode/vnode/src/sma/smaRollup.c +++ b/source/dnode/vnode/src/sma/smaRollup.c @@ -921,7 +921,7 @@ static int32_t tdRSmaInfoClone(SSma *pSma, SRSmaInfo *pInfo) { SMetaReader mr = {0}; metaReaderInit(&mr, SMA_META(pSma), 0); smaDebug("vgId:%d, rsma clone qTaskInfo for suid:%" PRIi64, SMA_VID(pSma), pInfo->suid); - if (metaGetTableEntryByUid(&mr, pInfo->suid) < 0) { + if (metaGetTableEntryByUidCache(&mr, pInfo->suid) < 0) { smaError("vgId:%d, rsma clone, failed to get table meta for %" PRIi64 " since %s", SMA_VID(pSma), pInfo->suid, terrstr()); goto _err; @@ -1125,7 +1125,7 @@ static int32_t tdRSmaRestoreQTaskInfoInit(SSma *pSma, int64_t *nTables) { for (int64_t i = 0; i < arrSize; ++i) { tb_uid_t suid = *(tb_uid_t *)taosArrayGet(suidList, i); smaDebug("vgId:%d, rsma restore, suid is %" PRIi64, TD_VID(pVnode), suid); - if (metaGetTableEntryByUid(&mr, suid) < 0) { + if (metaGetTableEntryByUidCache(&mr, suid) < 0) { smaError("vgId:%d, rsma restore, failed to get table meta for %" PRIi64 " since %s", TD_VID(pVnode), suid, terrstr()); goto _err; diff --git a/source/dnode/vnode/src/tq/tqExec.c b/source/dnode/vnode/src/tq/tqExec.c index 3887f72740..8bcfe53712 100644 --- a/source/dnode/vnode/src/tq/tqExec.c +++ b/source/dnode/vnode/src/tq/tqExec.c @@ -48,7 +48,7 @@ static int32_t tqAddTbNameToRsp(const STQ* pTq, int64_t uid, SMqDataRsp* pRsp, i SMetaReader mr = {0}; metaReaderInit(&mr, pTq->pVnode->pMeta, 0); // TODO add reference to gurantee success - if (metaGetTableEntryByUid(&mr, uid) < 0) { + if (metaGetTableEntryByUidCache(&mr, uid) < 0) { metaReaderClear(&mr); return -1; } diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index afb7ac39de..e41b1d8aa8 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -766,7 +766,7 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) { for (int32_t i = 0; i < taosArrayGetSize(tbUidList); ++i) { uint64_t* id = (uint64_t*)taosArrayGet(tbUidList, i); - int32_t code = metaGetTableEntryByUid(&mr, *id); + int32_t code = metaGetTableEntryByUidCache(&mr, *id); if (code != TSDB_CODE_SUCCESS) { qError("failed to get table meta, uid:%" PRIu64 " code:%s", *id, tstrerror(terrno)); continue; diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c index 291a5ab1eb..d71eb33951 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCache.c +++ b/source/dnode/vnode/src/tsdb/tsdbCache.c @@ -392,7 +392,7 @@ static tb_uid_t getTableSuidByUid(tb_uid_t uid, STsdb *pTsdb) { SMetaReader mr = {0}; metaReaderInit(&mr, pTsdb->pVnode->pMeta, 0); - if (metaGetTableEntryByUid(&mr, uid) < 0) { + if (metaGetTableEntryByUidCache(&mr, uid) < 0) { metaReaderClear(&mr); // table not esist return 0; } diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index ca3df04550..96cfa1752d 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -4350,7 +4350,7 @@ int32_t tsdbGetTableSchema(SVnode* pVnode, int64_t uid, STSchema** pSchema, int6 SMetaReader mr = {0}; metaReaderInit(&mr, pVnode->pMeta, 0); - int32_t code = metaGetTableEntryByUid(&mr, uid); + int32_t code = metaGetTableEntryByUidCache(&mr, uid); if (code != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TDB_INVALID_TABLE_ID; metaReaderClear(&mr); @@ -4362,7 +4362,7 @@ int32_t tsdbGetTableSchema(SVnode* pVnode, int64_t uid, STSchema** pSchema, int6 if (mr.me.type == TSDB_CHILD_TABLE) { tDecoderClear(&mr.coder); *suid = mr.me.ctbEntry.suid; - code = metaGetTableEntryByUid(&mr, *suid); + code = metaGetTableEntryByUidCache(&mr, *suid); if (code != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TDB_INVALID_TABLE_ID; metaReaderClear(&mr); diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index c072a5f1aa..3219ffa8f7 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -290,7 +290,7 @@ int32_t isQualifiedTable(STableKeyInfo* info, SNode* pTagCond, void* metaHandle, SMetaReader mr = {0}; metaReaderInit(&mr, metaHandle, 0); - code = metaGetTableEntryByUid(&mr, info->uid); + code = metaGetTableEntryByUidCache(&mr, info->uid); if (TSDB_CODE_SUCCESS != code) { metaReaderClear(&mr); *pQualified = false; @@ -1092,7 +1092,7 @@ size_t getTableTagsBufLen(const SNodeList* pGroups) { int32_t getGroupIdFromTagsVal(void* pMeta, uint64_t uid, SNodeList* pGroupNode, char* keyBuf, uint64_t* pGroupId) { SMetaReader mr = {0}; metaReaderInit(&mr, pMeta, 0); - if (metaGetTableEntryByUid(&mr, uid) != 0) { // table not exist + if (metaGetTableEntryByUidCache(&mr, uid) != 0) { // table not exist metaReaderClear(&mr); return TSDB_CODE_PAR_TABLE_NOT_EXIST; } diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 1b703c0137..3ee8ea9452 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -287,7 +287,7 @@ static SArray* filterUnqualifiedTables(const SStreamScanInfo* pScanInfo, const S for (int32_t i = 0; i < taosArrayGetSize(tableIdList); ++i) { uint64_t* id = (uint64_t*)taosArrayGet(tableIdList, i); - int32_t code = metaGetTableEntryByUid(&mr, *id); + int32_t code = metaGetTableEntryByUidCache(&mr, *id); if (code != TSDB_CODE_SUCCESS) { qError("failed to get table meta, uid:%" PRIu64 " code:%s, %s", *id, tstrerror(terrno), idstr); continue; diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 9ad0aae3e4..db6836b74e 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -2317,7 +2317,7 @@ SSchemaWrapper* extractQueriedColumnSchema(SScanPhysiNode* pScanNode); int32_t extractTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNode, SExecTaskInfo* pTaskInfo) { SMetaReader mr = {0}; metaReaderInit(&mr, pHandle->meta, 0); - int32_t code = metaGetTableEntryByUid(&mr, pScanNode->uid); + int32_t code = metaGetTableEntryByUidCache(&mr, pScanNode->uid); if (code != TSDB_CODE_SUCCESS) { qError("failed to get the table meta, uid:0x%" PRIx64 ", suid:0x%" PRIx64 ", %s", pScanNode->uid, pScanNode->suid, GET_TASKID(pTaskInfo)); @@ -2336,7 +2336,7 @@ int32_t extractTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNode, tDecoderClear(&mr.coder); tb_uid_t suid = mr.me.ctbEntry.suid; - metaGetTableEntryByUid(&mr, suid); + metaGetTableEntryByUidCache(&mr, suid); pSchemaInfo->sw = tCloneSSchemaWrapper(&mr.me.stbEntry.schemaRow); pSchemaInfo->tversion = mr.me.stbEntry.schemaTag.version; } else { diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 43d09dcac6..84c5bb425b 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -484,7 +484,7 @@ int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int // 1. check if it is existed in meta cache if (pCache == NULL) { metaReaderInit(&mr, pHandle->meta, 0); - code = metaGetTableEntryByUid(&mr, pBlock->info.uid); + code = metaGetTableEntryByUidCache(&mr, pBlock->info.uid); if (code != TSDB_CODE_SUCCESS) { if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) { qWarn("failed to get table meta, table may have been dropped, uid:0x%" PRIx64 ", code:%s, %s", pBlock->info.uid, @@ -508,7 +508,7 @@ int32_t addTagPseudoColumnData(SReadHandle* pHandle, const SExprInfo* pExpr, int h = taosLRUCacheLookup(pCache->pTableMetaEntryCache, &pBlock->info.uid, sizeof(pBlock->info.uid)); if (h == NULL) { metaReaderInit(&mr, pHandle->meta, 0); - code = metaGetTableEntryByUid(&mr, pBlock->info.uid); + code = metaGetTableEntryByUidCache(&mr, pBlock->info.uid); if (code != TSDB_CODE_SUCCESS) { if (terrno == TSDB_CODE_PAR_TABLE_NOT_EXIST) { qWarn("failed to get table meta, table may have been dropped, uid:0x%" PRIx64 ", code:%s, %s", diff --git a/source/libs/executor/src/sysscanoperator.c b/source/libs/executor/src/sysscanoperator.c index c5e1f2c214..eea2549a42 100644 --- a/source/libs/executor/src/sysscanoperator.c +++ b/source/libs/executor/src/sysscanoperator.c @@ -441,6 +441,9 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) { int32_t code = metaGetTableEntryByName(&smrChildTable, condTableName); if (code != TSDB_CODE_SUCCESS) { // terrno has been set by metaGetTableEntryByName, therefore, return directly + metaReaderClear(&smrChildTable); + blockDataDestroy(dataBlock); + pInfo->loadInfo.totalRows = 0; return NULL; } @@ -456,12 +459,16 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) { code = metaGetTableEntryByUid(&smrSuperTable, smrChildTable.me.ctbEntry.suid); if (code != TSDB_CODE_SUCCESS) { // terrno has been set by metaGetTableEntryByUid + metaReaderClear(&smrSuperTable); + metaReaderClear(&smrChildTable); + blockDataDestroy(dataBlock); return NULL; } sysTableUserTagsFillOneTableTags(pInfo, &smrSuperTable, &smrChildTable, dbname, tableName, &numOfRows, dataBlock); metaReaderClear(&smrSuperTable); metaReaderClear(&smrChildTable); + if (numOfRows > 0) { relocateAndFilterSysTagsScanResult(pInfo, numOfRows, dataBlock, pOperator->exprSupp.pFilterInfo); numOfRows = 0; From 31c2aa89efd5443f60db0061995bd2abbbaa9db3 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sun, 27 Nov 2022 01:59:49 +0800 Subject: [PATCH 63/66] fix(query): do some internal refactor. --- source/libs/executor/src/executil.c | 168 +++++++++++------- .../libs/function/src/detail/tavgfunction.c | 26 ++- tests/script/tsim/testsuit.sim | 48 ++--- 3 files changed, 136 insertions(+), 106 deletions(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 3219ffa8f7..65937ae1bc 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -405,7 +405,7 @@ static SColumnInfoData* getColInfoResult(void* metaHandle, int64_t suid, SArray* terrno = TSDB_CODE_OUT_OF_MEMORY; goto end; } - ctx.index = 0; + ctx.cInfoList = taosArrayInit(4, sizeof(SColumnInfo)); if (ctx.cInfoList == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -964,34 +964,98 @@ static int32_t optimizeTbnameInCondImpl(void* metaHandle, int64_t suid, SArray* return -1; } +static void genTagFilterDigest(const SNode* pTagCond, T_MD5_CTX* pContext) { + if (pTagCond == NULL) { + return; + } + + char* payload = NULL; + int32_t len = 0; + nodesNodeToMsg(pTagCond, &payload, &len); + + tMD5Init(pContext); + tMD5Update(pContext, (uint8_t*)payload, (uint32_t)len); + tMD5Final(pContext); + + taosMemoryFree(payload); +} + +static int32_t doFilterByTagCond(STableListInfo* pListInfo, SArray* res, SNode* pTagCond, void* metaHandle) { + if (pTagCond == NULL) { + return TSDB_CODE_SUCCESS; + } + + terrno = TDB_CODE_SUCCESS; + SColumnInfoData* pColInfoData = getColInfoResult(metaHandle, pListInfo->suid, res, pTagCond); + if (terrno != TDB_CODE_SUCCESS) { + colDataDestroy(pColInfoData); + taosMemoryFreeClear(pColInfoData); + taosArrayDestroy(res); + qError("failed to getColInfoResult, code: %s", tstrerror(terrno)); + return terrno; + } + + int32_t i = 0; + int32_t len = taosArrayGetSize(res); + + if (pColInfoData != NULL) { + bool* pResult = (bool*)pColInfoData->pData; + SArray* p = taosArrayInit(taosArrayGetSize(res), sizeof(uint64_t)); + + while (i < len && pColInfoData) { + int64_t* uid = taosArrayGet(res, i); + qDebug("tagfilter get uid:%" PRId64 ", res:%d", *uid, pResult[i]); + + if (pResult[i]) { + taosArrayPush(p, uid); + } + i += 1; + } + + taosArraySwap(res, p); + taosArrayDestroy(p); + } + + colDataDestroy(pColInfoData); + taosMemoryFreeClear(pColInfoData); + + return TSDB_CODE_SUCCESS; +} + int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, SNode* pTagCond, SNode* pTagIndexCond, STableListInfo* pListInfo) { int32_t code = TSDB_CODE_SUCCESS; + size_t numOfTables = 0; uint64_t tableUid = pScanNode->uid; pListInfo->suid = pScanNode->suid; SArray* res = taosArrayInit(8, sizeof(uint64_t)); - if (pScanNode->tableType == TSDB_SUPER_TABLE) { - // try to retrieve the result from meta cache - // generate the cache key - T_MD5_CTX context = {0}; - - if (pTagIndexCond) { - char* payload = NULL; - int32_t len = 0; - nodesNodeToMsg(pTagCond, &payload, &len); - - tMD5Init(&context); - tMD5Update(&context, (uint8_t*)payload, (uint32_t)len); - tMD5Final(&context); - - taosMemoryFree(payload); + if (pScanNode->tableType != TSDB_SUPER_TABLE) { + if (metaIsTableExist(metaHandle, tableUid)) { + taosArrayPush(res, &tableUid); } + code = doFilterByTagCond(pListInfo, res, pTagCond, metaHandle); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } else { + // try to retrieve the result from meta cache + T_MD5_CTX context = {0}; + genTagFilterDigest(pTagCond, &context); + bool acquired = false; metaGetCachedTableUidList(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), res, &acquired); - if (!acquired) { + if (acquired) { + qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t)taosArrayGetSize(res)); + goto _end; + } + + if (!pTagCond) { // no tag condition exists, let's fetch all tables of this super table + ASSERT(pTagIndexCond == NULL); + vnodeGetCtbIdList(pVnode, pScanNode->suid, res); + } else { // failed to find the result in the cache, let try to calculate the results if (pTagIndexCond) { SIndexMetaArg metaArg = { @@ -1003,63 +1067,29 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, qError("failed to get tableIds from index, reason:%s, suid:%" PRIu64, tstrerror(code), tableUid); code = TDB_CODE_SUCCESS; } - } else if (!pTagCond) { - vnodeGetCtbIdList(pVnode, pScanNode->suid, res); } - - // let's add the filter results into meta-cache - size_t numOfTables = taosArrayGetSize(res); - size_t size = numOfTables * sizeof(uint64_t) + sizeof(int32_t); - char* pPayload = taosMemoryMalloc(size); - *(int32_t*)pPayload = numOfTables; - - if (numOfTables > 0) { - memcpy(pPayload + sizeof(int32_t), taosArrayGet(res, 0), numOfTables * sizeof(uint64_t)); - } - - metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, - size, 1); - } else { - qDebug("retrieve table uid list from cache, numOfTables:%d", (int32_t) taosArrayGetSize(res)); } - } else { // Create one table group. - if (metaIsTableExist(metaHandle, tableUid)) { - taosArrayPush(res, &tableUid); + + code = doFilterByTagCond(pListInfo, res, pTagCond, metaHandle); + if (code != TSDB_CODE_SUCCESS) { + return code; } + + // let's add the filter results into meta-cache + numOfTables = taosArrayGetSize(res); + size_t size = numOfTables * sizeof(uint64_t) + sizeof(int32_t); + char* pPayload = taosMemoryMalloc(size); + *(int32_t*)pPayload = numOfTables; + + if (numOfTables > 0) { + memcpy(pPayload + sizeof(int32_t), taosArrayGet(res, 0), numOfTables * sizeof(uint64_t)); + } + + metaUidFilterCachePut(metaHandle, pScanNode->suid, context.digest, tListLen(context.digest), pPayload, size, 1); } - if (pTagCond) { - terrno = TDB_CODE_SUCCESS; - SColumnInfoData* pColInfoData = getColInfoResult(metaHandle, pListInfo->suid, res, pTagCond); - if (terrno != TDB_CODE_SUCCESS) { - colDataDestroy(pColInfoData); - taosMemoryFreeClear(pColInfoData); - taosArrayDestroy(res); - qError("failed to getColInfoResult, code: %s", tstrerror(terrno)); - return terrno; - } - - int32_t i = 0; - int32_t j = 0; - int32_t len = taosArrayGetSize(res); - while (i < taosArrayGetSize(res) && j < len && pColInfoData) { - void* var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes); - - int64_t* uid = taosArrayGet(res, i); - qDebug("tagfilter get uid:%" PRId64 ", res:%d", *uid, *(bool*)var); - if (*(bool*)var == false) { - taosArrayRemove(res, i); - j++; - continue; - } - i++; - j++; - } - colDataDestroy(pColInfoData); - taosMemoryFreeClear(pColInfoData); - } - - size_t numOfTables = taosArrayGetSize(res); +_end: + numOfTables = taosArrayGetSize(res); for (int i = 0; i < numOfTables; i++) { STableKeyInfo info = {.uid = *(uint64_t*)taosArrayGet(res, i), .groupId = 0}; diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 9507380d38..17190d8436 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -708,24 +708,22 @@ int32_t avgCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) { } int32_t avgFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { - SInputColumnInfoData* pInput = &pCtx->input; + SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx); - SAvgRes* pAvgRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - int32_t type = pAvgRes->type; + SAvgRes* pRes = GET_ROWCELL_INTERBUF(pEntryInfo); + int32_t type = pRes->type; - if (IS_SIGNED_NUMERIC_TYPE(type)) { - pAvgRes->result = pAvgRes->sum.isum / ((double)pAvgRes->count); - } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { - pAvgRes->result = pAvgRes->sum.usum / ((double)pAvgRes->count); - } else { - pAvgRes->result = pAvgRes->sum.dsum / ((double)pAvgRes->count); - } - - // check for overflow - if (isinf(pAvgRes->result) || isnan(pAvgRes->result)) { - GET_RES_INFO(pCtx)->numOfRes = 0; + if (pRes->count > 0) { + if (IS_SIGNED_NUMERIC_TYPE(type)) { + pRes->result = pRes->sum.isum / ((double)pRes->count); + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + pRes->result = pRes->sum.usum / ((double)pRes->count); + } else { + pRes->result = pRes->sum.dsum / ((double)pRes->count); + } } + pEntryInfo->numOfRes = (pRes->count > 0)? 1:0; return functionFinalize(pCtx, pBlock); } diff --git a/tests/script/tsim/testsuit.sim b/tests/script/tsim/testsuit.sim index ad8d70b089..c5fbf41b66 100644 --- a/tests/script/tsim/testsuit.sim +++ b/tests/script/tsim/testsuit.sim @@ -5,30 +5,32 @@ #run tsim/table/basic1.sim #run tsim/trans/lossdata1.sim #run tsim/trans/create_db.sim -run tsim/stable/alter_metrics.sim -run tsim/stable/tag_modify.sim -run tsim/stable/alter_comment.sim -run tsim/stable/column_drop.sim -run tsim/stable/column_modify.sim -run tsim/stable/tag_rename.sim -run tsim/stable/vnode3.sim -run tsim/stable/metrics.sim -run tsim/stable/alter_insert2.sim -run tsim/stable/show.sim -run tsim/stable/alter_import.sim -run tsim/stable/tag_add.sim -run tsim/stable/tag_drop.sim -run tsim/stable/column_add.sim -run tsim/stable/alter_count.sim -run tsim/stable/values.sim -run tsim/stable/dnode3.sim -run tsim/stable/alter_insert1.sim -run tsim/stable/refcount.sim -run tsim/stable/tag_filter.sim -run tsim/stable/disk.sim -run tsim/db/basic1.sim + +#run tsim/stable/alter_metrics.sim +#run tsim/stable/tag_modify.sim +#run tsim/stable/alter_comment.sim +#run tsim/stable/column_drop.sim +#run tsim/stable/column_modify.sim +#run tsim/stable/tag_rename.sim +#run tsim/stable/vnode3.sim +#run tsim/stable/metrics.sim +#run tsim/stable/alter_insert2.sim +#run tsim/stable/alter_import.sim +#run tsim/stable/tag_add.sim +#run tsim/stable/tag_drop.sim +#run tsim/stable/column_add.sim +#run tsim/stable/alter_count.sim +#run tsim/stable/values.sim +#run tsim/stable/dnode3.sim +#run tsim/stable/alter_insert1.sim +#run tsim/stable/refcount.sim +#run tsim/stable/tag_filter.sim +#run tsim/stable/disk.sim +#run tsim/db/basic1.sim +run tsim/db/basic2.sim run tsim/db/basic3.sim -run tsim/db/basic7.sim +run tsim/db/basic4.sim +run tsim/db/basic5.sim run tsim/db/basic6.sim run tsim/db/alter_replica_13.sim run tsim/db/create_all_options.sim From 203ea1f9c8c665d5732ba985b344cda6833c70e5 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sun, 27 Nov 2022 14:57:44 +0800 Subject: [PATCH 64/66] fix(query): fix error --- include/libs/executor/executor.h | 3 +++ source/common/src/tdatablock.c | 4 ---- source/dnode/vnode/src/sma/smaRollup.c | 6 ++++-- source/libs/executor/src/exchangeoperator.c | 1 + source/libs/executor/src/executor.c | 12 ++++++++++++ source/libs/executor/src/groupoperator.c | 5 ++--- source/libs/function/src/detail/tavgfunction.c | 2 +- source/libs/function/src/detail/tminmax.c | 2 +- tests/system-test/1-insert/block_wise.py | 2 +- tests/system-test/2-query/avg.py | 6 ++++-- tests/system-test/2-query/max_partition.py | 2 +- 11 files changed, 30 insertions(+), 15 deletions(-) diff --git a/include/libs/executor/executor.h b/include/libs/executor/executor.h index 1fe30a2d66..0bca254e14 100644 --- a/include/libs/executor/executor.h +++ b/include/libs/executor/executor.h @@ -142,8 +142,11 @@ int32_t qGetQueryTableSchemaVersion(qTaskInfo_t tinfo, char* dbName, char* table */ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal); + int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pBlock, uint64_t* useconds); +void qCleanExecTaskBlockBuf(qTaskInfo_t tinfo); + /** * kill the ongoing query asynchronously * @param tinfo qhandle diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 6a71d441b0..cfa2964e16 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -1322,10 +1322,6 @@ int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src) { for (int32_t i = 0; i < numOfCols; ++i) { SColumnInfoData* pDst = taosArrayGet(dst->pDataBlock, i); SColumnInfoData* pSrc = taosArrayGet(src->pDataBlock, i); - if (pSrc->pData == NULL) { - continue; - } - colDataAssign(pDst, pSrc, src->info.rows, &src->info); } diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c index c5f040c987..51842a8ae4 100644 --- a/source/dnode/vnode/src/sma/smaRollup.c +++ b/source/dnode/vnode/src/sma/smaRollup.c @@ -739,11 +739,13 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma } } - tdBlockDataDestroy(pResList); + taosArrayDestroy(pResList); + qCleanExecTaskBlockBuf(taskInfo); return TSDB_CODE_SUCCESS; _err: - tdBlockDataDestroy(pResList); + taosArrayDestroy(pResList); + qCleanExecTaskBlockBuf(taskInfo); return TSDB_CODE_FAILED; } diff --git a/source/libs/executor/src/exchangeoperator.c b/source/libs/executor/src/exchangeoperator.c index de918e0034..d8c85c5ffb 100644 --- a/source/libs/executor/src/exchangeoperator.c +++ b/source/libs/executor/src/exchangeoperator.c @@ -646,6 +646,7 @@ int32_t seqLoadRemoteData(SOperatorInfo* pOperator) { SRetrieveTableRsp* pRsp = pDataInfo->pRsp; SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo; + if (pRsp->numOfRows == 0) { qDebug("%s vgId:%d, taskID:0x%" PRIx64 " execId:%d %d of total completed, rowsOfSource:%" PRIu64 ", totalRows:%" PRIu64 " try next", diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 3ee8ea9452..01baba5a52 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -572,6 +572,18 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo return pTaskInfo->code; } +void qCleanExecTaskBlockBuf(qTaskInfo_t tinfo) { + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; + SArray* pList = pTaskInfo->pResultBlockList; + size_t num = taosArrayGetSize(pList); + for(int32_t i = 0; i < num; ++i) { + SSDataBlock** p = taosArrayGet(pTaskInfo->pResultBlockList, i); + blockDataDestroy(*p); + } + + taosArrayClear(pTaskInfo->pResultBlockList); +} + int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t* useconds) { SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; int64_t threadId = taosGetSelfPthreadId(); diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c index cde8346487..066912fbdf 100644 --- a/source/libs/executor/src/groupoperator.c +++ b/source/libs/executor/src/groupoperator.c @@ -274,10 +274,9 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) { // return; // } - int32_t len = 0; - STimeWindow w = TSWINDOW_INITIALIZER; - + int32_t len = 0; terrno = TSDB_CODE_SUCCESS; + int32_t num = 0; for (int32_t j = 0; j < pBlock->info.rows; ++j) { // Compare with the previous row of this column, and do not set the output buffer again if they are identical. diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 17190d8436..267cb36769 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -494,7 +494,7 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { switch(type) { case TSDB_DATA_TYPE_UTINYINT: case TSDB_DATA_TYPE_TINYINT: { - const int8_t* plist = (const int8_t*) &pCol->pData[start]; + const int8_t* plist = (const int8_t*) pCol->pData; // 1. If the CPU supports AVX, let's employ AVX instructions to speedup this loop if (simdAvailable) { diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index 46e68f46ec..e47edb8a1e 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -827,7 +827,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { if (i >= end) { ASSERT(numOfElems == 0); - return numOfElems; + goto _over; } doExtractVal(pCol, i, end, pCtx, pBuf, isMinFunc); diff --git a/tests/system-test/1-insert/block_wise.py b/tests/system-test/1-insert/block_wise.py index 0e17a01d05..8222000cd6 100644 --- a/tests/system-test/1-insert/block_wise.py +++ b/tests/system-test/1-insert/block_wise.py @@ -145,7 +145,7 @@ class TDTestCase: def init(self, conn, logSql, replicaVar=1): self.replicaVar = int(replicaVar) tdLog.debug(f"start to excute {__file__}") - tdSql.init(conn.cursor(), False) + tdSql.init(conn.cursor(), True) self.precision = "ms" self.sma_count = 0 self.sma_created_index = [] diff --git a/tests/system-test/2-query/avg.py b/tests/system-test/2-query/avg.py index 910dd524cb..139e7d4bf4 100644 --- a/tests/system-test/2-query/avg.py +++ b/tests/system-test/2-query/avg.py @@ -1,5 +1,7 @@ import taos import sys + +import math import numpy as np from util.log import * from util.sql import * @@ -411,7 +413,7 @@ class TDTestCase: tdSql.checkData(0,2,14042.142857143) tdSql.checkData(0,3,53.571428571) tdSql.checkData(0,4,5.828571332045761e+37) - tdSql.checkData(0,5,None) + tdSql.checkData(0,5,math.inf) # check + - * / in functions @@ -421,7 +423,7 @@ class TDTestCase: tdSql.checkData(0,2,14042.142857143) tdSql.checkData(0,3,26.785714286) tdSql.checkData(0,4,2.9142856660228804e+37) - tdSql.checkData(0,5,None) + tdSql.checkData(0,5,math.inf) diff --git a/tests/system-test/2-query/max_partition.py b/tests/system-test/2-query/max_partition.py index b14bc649dd..dec24010fc 100644 --- a/tests/system-test/2-query/max_partition.py +++ b/tests/system-test/2-query/max_partition.py @@ -7,7 +7,7 @@ class TDTestCase: def init(self, conn, logSql, replicaVar=1): self.replicaVar = int(replicaVar) tdLog.debug("start to execute %s" % __file__) - tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), True) self.row_nums = 10 self.tb_nums = 10 From e29e477b0c94ca4efe05be3d5d8a4d2b7f5b7114 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sun, 27 Nov 2022 15:46:31 +0800 Subject: [PATCH 65/66] fix(query): update api to avoid deadlock. --- source/libs/executor/src/executor.c | 2 +- source/libs/function/src/detail/tminmax.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 01baba5a52..9b3bd1d808 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -287,7 +287,7 @@ static SArray* filterUnqualifiedTables(const SStreamScanInfo* pScanInfo, const S for (int32_t i = 0; i < taosArrayGetSize(tableIdList); ++i) { uint64_t* id = (uint64_t*)taosArrayGet(tableIdList, i); - int32_t code = metaGetTableEntryByUidCache(&mr, *id); + int32_t code = metaGetTableEntryByUid(&mr, *id); if (code != TSDB_CODE_SUCCESS) { qError("failed to get table meta, uid:%" PRIu64 " code:%s, %s", *id, tstrerror(terrno), idstr); continue; diff --git a/source/libs/function/src/detail/tminmax.c b/source/libs/function/src/detail/tminmax.c index e47edb8a1e..b2cb36cba0 100644 --- a/source/libs/function/src/detail/tminmax.c +++ b/source/libs/function/src/detail/tminmax.c @@ -877,6 +877,8 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { break; } } + + pBuf->assign = true; } _over: From 1e8dcacea6347367315d5d2bacd96828bb793815 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Sun, 27 Nov 2022 18:25:20 +0800 Subject: [PATCH 66/66] fix(query): set null for inf and nan value. --- source/libs/function/src/detail/tavgfunction.c | 7 ++++++- tests/system-test/2-query/avg.py | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source/libs/function/src/detail/tavgfunction.c b/source/libs/function/src/detail/tavgfunction.c index 267cb36769..7d018a8dc7 100644 --- a/source/libs/function/src/detail/tavgfunction.c +++ b/source/libs/function/src/detail/tavgfunction.c @@ -723,7 +723,12 @@ int32_t avgFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { } } - pEntryInfo->numOfRes = (pRes->count > 0)? 1:0; + if (pRes->count == 0 || isinf(pRes->result) || isnan(pRes->result)) { + pEntryInfo->numOfRes = 0; + } else { + pEntryInfo->numOfRes = 1; + } + return functionFinalize(pCtx, pBlock); } diff --git a/tests/system-test/2-query/avg.py b/tests/system-test/2-query/avg.py index 139e7d4bf4..1d4d9a2494 100644 --- a/tests/system-test/2-query/avg.py +++ b/tests/system-test/2-query/avg.py @@ -15,7 +15,7 @@ class TDTestCase: def init(self, conn, logSql, replicaVar=1): self.replicaVar = int(replicaVar) tdLog.debug(f"start to excute {__file__}") - tdSql.init(conn.cursor(), False) + tdSql.init(conn.cursor(), True) self.setsql = TDSetSql() self.column_dict = { 'ts':'timestamp', @@ -413,7 +413,7 @@ class TDTestCase: tdSql.checkData(0,2,14042.142857143) tdSql.checkData(0,3,53.571428571) tdSql.checkData(0,4,5.828571332045761e+37) - tdSql.checkData(0,5,math.inf) + tdSql.checkData(0,5,None) # check + - * / in functions @@ -423,7 +423,7 @@ class TDTestCase: tdSql.checkData(0,2,14042.142857143) tdSql.checkData(0,3,26.785714286) tdSql.checkData(0,4,2.9142856660228804e+37) - tdSql.checkData(0,5,math.inf) + tdSql.checkData(0,5,None)