提交 ea83ae23 编写于 作者: H Haojun Liao

refactor: do some internal refactor.

上级 9f5cf450
...@@ -125,7 +125,7 @@ ELSE () ...@@ -125,7 +125,7 @@ ELSE ()
MESSAGE("System processor ID: ${CMAKE_SYSTEM_PROCESSOR}") MESSAGE("System processor ID: ${CMAKE_SYSTEM_PROCESSOR}")
IF (TD_INTEL_64 OR TD_INTEL_32) IF (TD_INTEL_64 OR TD_INTEL_32)
ADD_DEFINITIONS("-msse4.2 -mavx") ADD_DEFINITIONS("-msse4.2 -mavx -mavx2")
IF("${FMA_SUPPORT}" MATCHES "true") IF("${FMA_SUPPORT}" MATCHES "true")
MESSAGE(STATUS "turn fma function support on") MESSAGE(STATUS "turn fma function support on")
ADD_DEFINITIONS("-mfma") ADD_DEFINITIONS("-mfma")
......
...@@ -32,6 +32,21 @@ typedef struct SSumRes { ...@@ -32,6 +32,21 @@ typedef struct SSumRes {
int16_t type; int16_t type;
} SSumRes; } 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); bool functionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo);
int32_t functionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); int32_t functionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
int32_t functionFinalizeWithResultBuf(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, char* finalResult); int32_t functionFinalizeWithResultBuf(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, char* finalResult);
......
...@@ -48,15 +48,15 @@ ...@@ -48,15 +48,15 @@
// int16_t type; // store the original input type, used in merge function // int16_t type; // store the original input type, used in merge function
//} SAvgRes; //} SAvgRes;
typedef struct SMinmaxResInfo { //typedef struct SMinmaxResInfo {
bool assign; // assign the first value or not // bool assign; // assign the first value or not
int64_t v; // int64_t v;
STuplePos tuplePos; // STuplePos tuplePos;
//
STuplePos nullTuplePos; // STuplePos nullTuplePos;
bool nullTupleSaved; // bool nullTupleSaved;
int16_t type; // int16_t type;
} SMinmaxResInfo; //} SMinmaxResInfo;
typedef struct STopBotResItem { typedef struct STopBotResItem {
SVariant v; SVariant v;
...@@ -1124,529 +1124,529 @@ bool getMinmaxFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { ...@@ -1124,529 +1124,529 @@ bool getMinmaxFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
return true; return true;
} }
static STuplePos saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, //static STuplePos saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock,
const STupleKey* pKey); // const STupleKey* pKey);
static int32_t updateTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos); //static int32_t updateTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos);
static const char* loadTupleData(SqlFunctionCtx* pCtx, const 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;
}
}
// 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) { //static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, const char* tval) {
*val = pData[i]; // // the data is loaded, not only the block SMA value
if (pCtx->subsidiaries.num > 0) { // for (int32_t i = start; i < num + start; ++i) {
pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); // char* p = colDataGetData(pCol, i);
} // if (memcmp((void*)tval, p, pCol->info.bytes) == 0) {
pBuf->assign = true; // return i;
} else { // }
// ignore the equivalent data value // }
// NOTE: An faster version to avoid one additional comparison with FPU. //
if (isMinFunc) { // min // // if reach here means real data of block SMA is not set in pCtx->input.
if (*val > pData[i]) { // return -1;
*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: //int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
if (numOfElems == 0 && pCtx->subsidiaries.num > 0 && !pBuf->nullTupleSaved) { // int32_t numOfElems = 0;
pBuf->nullTuplePos = saveTupleData(pCtx, pInput->startRowIndex, pCtx->pSrcBlock, NULL); //
pBuf->nullTupleSaved = true; // SInputColumnInfoData* pInput = &pCtx->input;
} // SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0];
return numOfElems; //
} // 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 minFunction(SqlFunctionCtx* pCtx) {
int32_t numOfElems = doMinMaxHelper(pCtx, 1); int32_t numOfElems = doMinMaxHelper(pCtx, 1);
...@@ -3844,7 +3844,7 @@ static int32_t doUpdateTupleData(SSerializeDataHandle* pHandle, const void* pBuf ...@@ -3844,7 +3844,7 @@ static int32_t doUpdateTupleData(SSerializeDataHandle* pHandle, const void* pBuf
return TSDB_CODE_SUCCESS; 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); char* buf = serializeTupleData(pSrcBlock, rowIndex, &pCtx->subsidiaries, pCtx->subsidiaries.buf);
doUpdateTupleData(&pCtx->saveHandle, buf, pCtx->subsidiaries.rowLen, pPos); doUpdateTupleData(&pCtx->saveHandle, buf, pCtx->subsidiaries.rowLen, pPos);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -3864,7 +3864,7 @@ static char* doLoadTupleData(SSerializeDataHandle* pHandle, const STuplePos* pPo ...@@ -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); return doLoadTupleData(&pCtx->saveHandle, pPos);
} }
......
...@@ -282,19 +282,20 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { ...@@ -282,19 +282,20 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) {
} }
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT: {
#if 1
numOfElem = handleFloatCols(pCol, pInput, pAvgRes); numOfElem = handleFloatCols(pCol, pInput, pAvgRes);
// float* plist = (float*)pCol->pData; #else
// // float val = 0; float* plist = (float*)pCol->pData;
// for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) { for (int32_t i = start; i < numOfRows + pInput->startRowIndex; ++i) {
// if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) { if (pCol->hasNull && colDataIsNull_f(pCol->nullbitmap, i)) {
// continue; continue;
// } }
//
// numOfElem += 1; numOfElem += 1;
// pAvgRes->count += 1; pAvgRes->count += 1;
// pAvgRes->sum.dsum += plist[i]; pAvgRes->sum.dsum += plist[i];
// } }
// pAvgRes->sum.dsum = val; #endif
break; break;
} }
......
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <immintrin.h>
#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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册