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

refactor: do some internal refactor.

上级 e5e817ae
...@@ -551,6 +551,7 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) { ...@@ -551,6 +551,7 @@ int32_t avgFunction(SqlFunctionCtx* pCtx) {
} }
break; break;
} }
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT: {
const float* plist = (const float*) pCol->pData; const float* plist = (const float*) pCol->pData;
......
...@@ -19,6 +19,48 @@ ...@@ -19,6 +19,48 @@
#include "tfunctionInt.h" #include "tfunctionInt.h"
#include "tglobal.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) { static void calculateRounds(int32_t numOfRows, int32_t bytes, int32_t* remainder, int32_t* rounds, int32_t* width) {
const int32_t bitWidth = 256; const int32_t bitWidth = 256;
...@@ -27,7 +69,32 @@ static void calculateRounds(int32_t numOfRows, int32_t bytes, int32_t* remainder ...@@ -27,7 +69,32 @@ static void calculateRounds(int32_t numOfRows, int32_t bytes, int32_t* remainder
*rounds = numOfRows / (*width); *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; int8_t v = 0;
const int8_t* p = pData; const int8_t* p = pData;
...@@ -36,51 +103,51 @@ static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMin ...@@ -36,51 +103,51 @@ static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMin
#if __AVX2__ #if __AVX2__
__m256i next; __m256i next;
__m256i initialVal = _mm256_lddqu_si256((__m256i*)p); __m256i initVal = _mm256_lddqu_si256((__m256i*)p);
p += width; p += width;
if (!isMinFunc) { // max function if (!isMinFunc) { // max function
for (int32_t i = 0; i < rounds; ++i) { if (signVal) {
next = _mm256_lddqu_si256((__m256i*)p); for (int32_t i = 0; i < rounds; ++i) {
initialVal = _mm256_max_epi8(initialVal, next); next = _mm256_lddqu_si256((__m256i*)p);
p += width; initVal = _mm256_max_epi8(initVal, 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*)&initVal;
const int8_t* q = (const int8_t*)&initialVal; 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;
}
v = TMIN(q[0], q[1]); const uint8_t* q = (const uint8_t*)&initVal;
for(int32_t k = 1; k < width; ++k) { EXTRACT_MAX_VAL(q, p, width, remain, v)
v = TMIN(v, q[k]);
} }
} else { // min function
if (signVal) {
for (int32_t i = 0; i < rounds; ++i) {
next = _mm256_lddqu_si256((__m256i*)p);
initVal = _mm256_min_epi8(initVal, next);
p += width;
}
// calculate the front and the remainder items in array list // let sum up the final results
int32_t start = rounds * width; const int8_t* q = (const int8_t*)&initVal;
for (int32_t j = 0; j < remain; ++j) { EXTRACT_MIN_VAL(q, p, width, remain, v)
if (v > p[j + start]) { } else {
v = p[j + start]; 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 #endif
...@@ -88,7 +155,7 @@ static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMin ...@@ -88,7 +155,7 @@ static int8_t i8VectorCmpAVX2(const int8_t* pData, int32_t numOfRows, bool isMin
return v; 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; int16_t v = 0;
const int16_t* p = pData; const int16_t* p = pData;
...@@ -97,53 +164,53 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is ...@@ -97,53 +164,53 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is
#if __AVX2__ #if __AVX2__
__m256i next; __m256i next;
__m256i initialVal = _mm256_lddqu_si256((__m256i*)p); __m256i initVal = _mm256_lddqu_si256((__m256i*)p);
p += width; p += width;
if (!isMinFunc) { // max function if (!isMinFunc) { // max function
for (int32_t i = 0; i < rounds; ++i) { if (signVal) {
next = _mm256_lddqu_si256((__m256i*)p); for (int32_t i = 0; i < rounds; ++i) {
initialVal = _mm256_max_epi16(initialVal, next); next = _mm256_lddqu_si256((__m256i*)p);
p += width; initVal = _mm256_max_epi16(initVal, next);
} p += width;
}
// let sum up the final results // let sum up the final results
const int16_t* q = (const int16_t*)&initialVal; 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;
}
v = TMAX(q[0], q[1]); // let sum up the final results
for(int32_t k = 1; k < width; ++k) { const uint16_t* q = (const uint16_t*)&initVal;
v = TMAX(v, q[k]); EXTRACT_MAX_VAL(q, p, width, remain, v)
} }
// 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 } else { // min function
for (int32_t i = 0; i < rounds; ++i) { if (signVal) {
next = _mm256_lddqu_si256((__m256i*)p); for (int32_t i = 0; i < rounds; ++i) {
initialVal = _mm256_min_epi16(initialVal, next); next = _mm256_lddqu_si256((__m256i*)p);
p += width; initVal = _mm256_min_epi16(initVal, 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 // let sum up the final results
int32_t start = rounds * width; const int16_t* q = (const int16_t*)&initVal;
for (int32_t j = 0; j < remain; ++j) { EXTRACT_MIN_VAL(q, p, width, remain, v)
if (v > p[j + start]) { } else {
v = p[j + start]; 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 #endif
...@@ -151,7 +218,7 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is ...@@ -151,7 +218,7 @@ static int16_t i16VectorCmpAVX2(const int16_t* pData, int32_t numOfRows, bool is
return v; 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; int32_t v = 0;
const int32_t* p = pData; const int32_t* p = pData;
...@@ -160,50 +227,52 @@ static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool is ...@@ -160,50 +227,52 @@ static int32_t i32VectorCmpAVX2(const int32_t* pData, int32_t numOfRows, bool is
#if __AVX2__ #if __AVX2__
__m256i next; __m256i next;
__m256i initialVal = _mm256_lddqu_si256((__m256i*)p); __m256i initVal = _mm256_lddqu_si256((__m256i*)p);
p += width; p += width;
if (!isMinFunc) { // max function if (!isMinFunc) { // max function
for (int32_t i = 0; i < rounds; ++i) { if (signVal) {
next = _mm256_lddqu_si256((__m256i*)p); for (int32_t i = 0; i < rounds; ++i) {
initialVal = _mm256_max_epi32(initialVal, next); next = _mm256_lddqu_si256((__m256i*)p);
p += width; initVal = _mm256_max_epi32(initVal, 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 // let compare the final results
int32_t start = rounds * width; const int32_t* q = (const int32_t*)&initVal;
for (int32_t j = 0; j < remain; ++j) { EXTRACT_MAX_VAL(q, p, width, remain, v)
if (v < p[j + start]) { } else { // unsigned value
v = p[j + start]; for (int32_t i = 0; i < rounds; ++i) {
next = _mm256_lddqu_si256((__m256i*)p);
initVal = _mm256_max_epi32(initVal, next);
p += width;
} }
}
} 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 // let compare the final results
const int32_t* q = (const int32_t*)&initialVal; const uint32_t* q = (const uint32_t*)&initVal;
v = TMIN(q[0], q[1]); EXTRACT_MAX_VAL(q, p, width, remain, v)
for (int32_t k = 1; k < width; ++k) {
v = TMIN(v, q[k]);
} }
} else { // min function
if (signVal) {
for (int32_t i = 0; i < rounds; ++i) {
next = _mm256_lddqu_si256((__m256i*)p);
initVal = _mm256_min_epi32(initVal, next);
p += width;
}
// calculate the front and the remainder items in array list // let sum up the final results
int32_t start = rounds * width; const int32_t* q = (const int32_t*)&initVal;
for (int32_t j = 0; j < remain; ++j) { EXTRACT_MIN_VAL(q, p, width, remain, v)
if (v > p[j + start]) { } else {
v = p[j + start]; 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 #endif
...@@ -221,51 +290,27 @@ static float floatVectorCmpAVX(const float* pData, int32_t numOfRows, bool isMin ...@@ -221,51 +290,27 @@ static float floatVectorCmpAVX(const float* pData, int32_t numOfRows, bool isMin
#if __AVX__ #if __AVX__
__m256 next; __m256 next;
__m256 initialVal = _mm256_loadu_ps(p); __m256 initVal = _mm256_loadu_ps(p);
p += width; p += width;
if (!isMinFunc) { // max function if (!isMinFunc) { // max function
for (int32_t i = 1; i < rounds; ++i) { for (int32_t i = 1; i < rounds; ++i) {
next = _mm256_loadu_ps(p); next = _mm256_loadu_ps(p);
initialVal = _mm256_max_ps(initialVal, next); initVal = _mm256_max_ps(initVal, next);
p += width; p += width;
} }
// let sum up the final results const float* q = (const float*)&initVal;
const float* q = (const float*)&initialVal; EXTRACT_MAX_VAL(q, p, width, remain, v)
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 } else { // min function
for (int32_t i = 1; i < rounds; ++i) { for (int32_t i = 1; i < rounds; ++i) {
next = _mm256_loadu_ps(p); next = _mm256_loadu_ps(p);
initialVal = _mm256_min_ps(initialVal, next); initVal = _mm256_min_ps(initVal, next);
p += width; p += width;
} }
// let sum up the final results const float* q = (const float*)&initVal;
const float* q = (const float*)&initialVal; EXTRACT_MIN_VAL(q, p, width, remain, v)
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 #endif
...@@ -282,366 +327,237 @@ static double doubleVectorCmpAVX(const double* pData, int32_t numOfRows, bool is ...@@ -282,366 +327,237 @@ static double doubleVectorCmpAVX(const double* pData, int32_t numOfRows, bool is
#if __AVX__ #if __AVX__
__m256d next; __m256d next;
__m256d initialVal = _mm256_loadu_pd(p); __m256d initVal = _mm256_loadu_pd(p);
p += width; p += width;
if (!isMinFunc) { // max function if (!isMinFunc) { // max function
for (int32_t i = 1; i < rounds; ++i) { for (int32_t i = 1; i < rounds; ++i) {
next = _mm256_loadu_pd(p); next = _mm256_loadu_pd(p);
initialVal = _mm256_max_pd(initialVal, next); initVal = _mm256_max_pd(initVal, next);
p += width; p += width;
} }
// let sum up the final results // let sum up the final results
const double* q = (const double*)&initialVal; const double* q = (const double*)&initVal;
v = TMAX(q[0], q[1]); EXTRACT_MAX_VAL(q, p, width, remain, v)
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 } else { // min function
for (int32_t i = 1; i < rounds; ++i) { for (int32_t i = 1; i < rounds; ++i) {
next = _mm256_loadu_pd(p); next = _mm256_loadu_pd(p);
initialVal = _mm256_min_pd(initialVal, next); initVal = _mm256_min_pd(initVal, next);
p += width; p += width;
} }
// let sum up the final results // let sum up the final results
const double* q = (const double*)&initialVal; const double* q = (const double*)&initVal;
v = TMIN(q[0], q[1]); EXTRACT_MIN_VAL(q, p, width, remain, v)
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 #endif
return v; 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; int32_t i = start;
while (i < (start + numOfRows)) {
if (!colDataIsNull_f(pCol->nullbitmap, i)) { while (i < (start + numOfRows) && (colDataIsNull_f(pCol->nullbitmap, i) == true)) {
break;
}
i += 1; i += 1;
} }
return i; return i;
} }
static int32_t handleInt8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, static void handleInt8Col(const void* data, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc,
SMinmaxResInfo* pBuf, bool isMinFunc) { bool signVal) {
int8_t* pData = (int8_t*)pCol->pData; // AVX2 version to speedup the loop
int8_t* val = (int8_t*)&pBuf->v; if (tsAVX2Enable && tsSIMDEnable) {
pBuf->v = i8VectorCmpAVX2(data, numOfRows, isMinFunc, signVal);
int32_t numOfElems = 0; } else {
if (pCol->hasNull || numOfRows <= 32 || pCtx->subsidiaries.num > 0) { if (!pBuf->assign) {
int32_t i = findFirstVal(pCol, start, numOfRows); pBuf->v = ((int8_t*)data)[0];
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 if (signVal) {
for (; i < start + numOfRows; ++i) { const int8_t* p = (const int8_t*)data;
if (colDataIsNull_f(pCol->nullbitmap, i)) { int8_t* v = (int8_t*)&pBuf->v;
continue;
}
if (*val > pData[i]) { if (isMinFunc) {
*val = pData[i]; __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p);
if (pCtx->subsidiaries.num > 0) { } else {
updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p);
}
}
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 { } else {
if (!pBuf->assign) { const uint8_t* p = (const uint8_t*)data;
*val = pData[0]; uint8_t* v = (uint8_t*)&pBuf->v;
pBuf->assign = true;
}
if (isMinFunc) { // min if (isMinFunc) {
for (int32_t i = start; i < start + numOfRows; ++i) { __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p);
if (*val > pData[i]) { } else {
*val = pData[i]; __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p);
}
}
} 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 handleInt16Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, static void handleInt16Col(const void* data, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc,
SMinmaxResInfo* pBuf, bool isMinFunc) { bool signVal) {
int16_t* pData = (int16_t*)pCol->pData; // AVX2 version to speedup the loop
int16_t* val = (int16_t*)&pBuf->v; if (tsAVX2Enable && tsSIMDEnable) {
pBuf->v = i16VectorCmpAVX2(data, numOfRows, isMinFunc, signVal);
int32_t numOfElems = 0; } else {
if (pCol->hasNull || numOfRows <= 16 || pCtx->subsidiaries.num > 0) { if (!pBuf->assign) {
int32_t i = findFirstVal(pCol, start, numOfRows); pBuf->v = ((int16_t*)data)[0];
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 if (signVal) {
for (; i < start + numOfRows; ++i) { const int16_t* p = (const int16_t*)data;
if (colDataIsNull_f(pCol->nullbitmap, i)) { int16_t* v = (int16_t*)&pBuf->v;
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 if (isMinFunc) {
for (; i < start + numOfRows; ++i) { __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p);
if (colDataIsNull_f(pCol->nullbitmap, i)) { } else {
continue; __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p);
}
// 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 { } else {
if (!pBuf->assign) { const uint16_t* p = (const uint16_t*)data;
*val = pData[0]; uint16_t* v = (uint16_t*)&pBuf->v;
pBuf->assign = true;
}
if (isMinFunc) { // min if (isMinFunc) {
for (int32_t i = start; i < start + numOfRows; ++i) { __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p);
if (*val > pData[i]) { } else {
*val = pData[i]; __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p);
}
}
} 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 handleInt32Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, static void handleInt32Col(const void* data, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc,
SMinmaxResInfo* pBuf, bool isMinFunc) { bool signVal) {
int32_t* pData = (int32_t*)pCol->pData; // AVX2 version to speedup the loop
int32_t* val = (int32_t*)&pBuf->v; if (tsAVX2Enable && tsSIMDEnable) {
pBuf->v = i32VectorCmpAVX2(data, numOfRows, isMinFunc, signVal);
} else {
if (!pBuf->assign) {
pBuf->v = ((int32_t*)data)[0];
}
int32_t numOfElems = 0; if (signVal) {
if (pCol->hasNull || numOfRows <= 8 || pCtx->subsidiaries.num > 0) { const int32_t* p = (const int32_t*)data;
int32_t i = findFirstVal(pCol, start, numOfRows); int32_t* v = (int32_t*)&pBuf->v;
if ((i < (start + numOfRows)) && (!pBuf->assign)) { if (isMinFunc) {
*val = pData[i]; __COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p);
if (pCtx->subsidiaries.num > 0) { } else {
pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p);
}
} else {
const uint32_t* p = (const uint32_t*)data;
uint32_t* v = (uint32_t*)&pBuf->v;
if (isMinFunc) {
__COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p);
} else {
__COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p);
} }
pBuf->assign = true;
numOfElems += 1;
} }
}
if (isMinFunc) { // min pBuf->assign = true;
for (; i < start + numOfRows; ++i) { }
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
if (*val > pData[i]) { static void handleInt64Col(const void* data, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc,
*val = pData[i]; bool signVal) {
if (pCtx->subsidiaries.num > 0) { if (!pBuf->assign) {
updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); pBuf->v = ((int64_t*)data)[0];
} }
}
numOfElems += 1;
}
} else { // max function if (signVal) {
for (; i < start + numOfRows; ++i) { const int64_t* p = (const int64_t*)data;
if (colDataIsNull_f(pCol->nullbitmap, i)) { int64_t* v = &pBuf->v;
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 } else {
// AVX2 version to speedup the loop const uint64_t* p = (const uint64_t*)data;
if (tsAVX2Enable && tsSIMDEnable) { uint64_t* v = (uint64_t*)&pBuf->v;
*val = i32VectorCmpAVX2(pData, numOfRows, isMinFunc);
if (isMinFunc) {
__COMPARE_EXTRACT_MIN(start, start + numOfRows, *v, p);
} else { } else {
if (!pBuf->assign) { __COMPARE_EXTRACT_MAX(start, start + numOfRows, *v, p);
*val = pData[0]; }
pBuf->assign = true; }
} }
if (isMinFunc) { // min static void handleUint8Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf,
for (int32_t i = start; i < start + numOfRows; ++i) { bool isMinFunc) {
if (*val > pData[i]) { const uint8_t* pData = (uint8_t*)pCol->pData;
*val = pData[i]; uint8_t* val = (uint8_t*)&pBuf->v;
}
} // AVX2 version to speedup the loop
} else { // max if (tsAVX2Enable && tsSIMDEnable) {
for (int32_t i = start; i < start + numOfRows; ++i) { *val = i8VectorCmpAVX2(pData, numOfRows, isMinFunc, false);
if (*val < pData[i]) { } else {
*val = pData[i]; if (!pBuf->assign) {
} *val = pData[0];
}
}
} }
numOfElems = numOfRows; if (isMinFunc) { // min
__COMPARE_EXTRACT_MIN(start, start + numOfRows, *val, pData);
} else {
__COMPARE_EXTRACT_MAX(start, start + numOfRows, *val, pData);
}
} }
return numOfElems; pBuf->assign = true;
} }
static int32_t handleInt64Col(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, static void handleFloatCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SMinmaxResInfo* pBuf, bool isMinFunc) {
SMinmaxResInfo* pBuf, bool isMinFunc) { float* pData = (float*)pCol->pData;
int32_t* pData = (int32_t*)pCol->pData; float* val = (float*)&pBuf->v;
int32_t* val = (int32_t*)&pBuf->v;
int32_t numOfElems = 0;
if (pCol->hasNull || pCtx->subsidiaries.num > 0) {
int32_t i = findFirstVal(pCol, start, numOfRows);
if ((i < (start + numOfRows)) && (!pBuf->assign)) { // AVX version to speedup the loop
*val = pData[i]; if (tsAVXEnable && tsSIMDEnable) {
if (pCtx->subsidiaries.num > 0) { *val = floatVectorCmpAVX(pData, numOfRows, isMinFunc);
pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); } else {
} if (!pBuf->assign) {
pBuf->assign = true; *val = pData[0];
numOfElems += 1;
} }
if (isMinFunc) { // min if (isMinFunc) { // min
for (; i < start + numOfRows; ++i) { for (int32_t i = start; i < start + numOfRows; ++i) {
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
if (*val > pData[i]) { if (*val > pData[i]) {
*val = pData[i]; *val = pData[i];
if (pCtx->subsidiaries.num > 0) {
updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
}
} }
numOfElems += 1;
} }
} else { // max
} else { // max function for (int32_t i = start; i < start + numOfRows; ++i) {
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]) { if (*val < pData[i]) {
*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
pBuf->assign = true;
}
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;
// AVX version to speedup the loop
if (tsAVXEnable && tsSIMDEnable) {
*val = (double)doubleVectorCmpAVX(pData, numOfRows, isMinFunc);
} else {
if (!pBuf->assign) { if (!pBuf->assign) {
*val = pData[0]; *val = pData[0];
pBuf->assign = true;
} }
if (isMinFunc) { // min if (isMinFunc) { // min
...@@ -657,182 +573,153 @@ static int32_t handleInt64Col(SColumnInfoData* pCol, int32_t start, int32_t numO ...@@ -657,182 +573,153 @@ 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, pBuf->assign = true;
SMinmaxResInfo* pBuf, bool isMinFunc) { }
float* pData = (float*)pCol->pData;
float* val = (float*)&pBuf->v;
int32_t numOfElems = 0; static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, const char* tval) {
if (pCol->hasNull || numOfRows < 8 || pCtx->subsidiaries.num > 0) { // the data is loaded, not only the block SMA value
int32_t i = findFirstVal(pCol, start, numOfRows); for (int32_t i = start; i < num + start; ++i) {
if ((i < (start + numOfRows)) && (!pBuf->assign)) { char* p = colDataGetData(pCol, i);
*val = pData[i]; if (memcmp((void*)tval, p, pCol->info.bytes) == 0) {
if (pCtx->subsidiaries.num > 0) { return i;
pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL);
}
pBuf->assign = true;
numOfElems += 1;
} }
}
if (isMinFunc) { // min // if reach here means real data of block SMA is not set in pCtx->input.
for (; i < start + numOfRows; ++i) { return -1;
if (colDataIsNull_f(pCol->nullbitmap, i)) { }
continue;
}
if (*val > pData[i]) { static void doExtractVal(SColumnInfoData* pCol, int32_t i, int32_t end, SqlFunctionCtx* pCtx, SMinmaxResInfo* pBuf,
*val = pData[i]; bool isMinFunc) {
if (pCtx->subsidiaries.num > 0) { if (isMinFunc) {
updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); switch (pCol->info.type) {
} case TSDB_DATA_TYPE_BOOL:
} case TSDB_DATA_TYPE_TINYINT: {
numOfElems += 1; 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;
} }
} else { // max function
for (; i < start + numOfRows; ++i) {
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
// ignore the equivalent data value case TSDB_DATA_TYPE_SMALLINT: {
// NOTE: An faster version to avoid one additional comparison with FPU. const int16_t* pData = (const int16_t*)pCol->pData;
if (*val < pData[i]) { __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(int16_t*)&(pBuf->v), &pBuf->tuplePos)
*val = pData[i]; break;
if (pCtx->subsidiaries.num > 0) {
updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
}
}
numOfElems += 1;
} }
}
} else { // not has null value case TSDB_DATA_TYPE_INT: {
// AVX version to speedup the loop const int32_t* pData = (const int32_t*)pCol->pData;
if (tsAVXEnable && tsSIMDEnable) { __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(int32_t*)&(pBuf->v), &pBuf->tuplePos)
*val = (double) floatVectorCmpAVX(pData, numOfRows, isMinFunc); break;
} else {
if (!pBuf->assign) {
*val = pData[0];
pBuf->assign = true;
} }
if (isMinFunc) { // min case TSDB_DATA_TYPE_BIGINT: {
for (int32_t i = start; i < start + numOfRows; ++i) { const int64_t* pData = (const int64_t*)pCol->pData;
if (*val > pData[i]) { __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, (pBuf->v), &pBuf->tuplePos)
*val = pData[i]; break;
}
}
} else { // max
for (int32_t i = start; i < start + numOfRows; ++i) {
if (*val < pData[i]) {
*val = pData[i];
}
}
} }
}
numOfElems = numOfRows; 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;
}
return numOfElems; 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;
}
static int32_t handleDoubleCol(SColumnInfoData* pCol, int32_t start, int32_t numOfRows, SqlFunctionCtx* pCtx, case TSDB_DATA_TYPE_UINT: {
SMinmaxResInfo* pBuf, bool isMinFunc) { const uint32_t* pData = (const uint32_t*)pCol->pData;
double* pData = (double*)pCol->pData; __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(uint32_t*)&(pBuf->v), &pBuf->tuplePos)
double* val = (double*)&pBuf->v; break;
}
int32_t numOfElems = 0; case TSDB_DATA_TYPE_UBIGINT: {
if (pCol->hasNull || numOfRows < 4 || pCtx->subsidiaries.num > 0) { const uint64_t* pData = (const uint64_t*)pCol->pData;
int32_t i = findFirstVal(pCol, start, numOfRows); __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(uint64_t*)&(pBuf->v), &pBuf->tuplePos)
break;
}
if ((i < (start + numOfRows)) && (!pBuf->assign)) { case TSDB_DATA_TYPE_FLOAT: {
*val = pData[i]; const float* pData = (const float*)pCol->pData;
if (pCtx->subsidiaries.num > 0) { __COMPARE_ACQUIRED_MIN(i, end, pCol->nullbitmap, pData, pCtx, *(float*)&(pBuf->v), &pBuf->tuplePos)
pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); 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;
} }
pBuf->assign = true;
numOfElems += 1;
} }
} 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;
}
if (isMinFunc) { // min case TSDB_DATA_TYPE_SMALLINT: {
for (; i < start + numOfRows; ++i) { const int16_t* pData = (const int16_t*)pCol->pData;
if (colDataIsNull_f(pCol->nullbitmap, i)) { __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(int16_t*)&(pBuf->v), &pBuf->tuplePos)
continue; break;
} }
if (*val > pData[i]) { case TSDB_DATA_TYPE_INT: {
*val = pData[i]; const int16_t* pData = (const int16_t*)pCol->pData;
if (pCtx->subsidiaries.num > 0) { __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(int32_t*)&(pBuf->v), &pBuf->tuplePos)
updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos); break;
}
}
numOfElems += 1;
} }
} else { // max function
for (; i < start + numOfRows; ++i) {
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
// ignore the equivalent data value case TSDB_DATA_TYPE_BIGINT: {
// NOTE: An faster version to avoid one additional comparison with FPU. const int64_t* pData = (const int64_t*)pCol->pData;
if (*val < pData[i]) { __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, (pBuf->v), &pBuf->tuplePos)
*val = pData[i]; break;
if (pCtx->subsidiaries.num > 0) {
updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
}
}
numOfElems += 1;
} }
}
} else { // not has null value case TSDB_DATA_TYPE_UTINYINT: {
// AVX version to speedup the loop const uint8_t* pData = (const uint8_t*)pCol->pData;
if (tsAVXEnable && tsSIMDEnable) { __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(uint8_t*)&(pBuf->v), &pBuf->tuplePos)
*val = (double) doubleVectorCmpAVX(pData, numOfRows, isMinFunc); break;
} else {
if (!pBuf->assign) {
*val = pData[0];
pBuf->assign = true;
} }
if (isMinFunc) { // min case TSDB_DATA_TYPE_USMALLINT: {
for (int32_t i = start; i < start + numOfRows; ++i) { const uint16_t* pData = (const uint16_t*)pCol->pData;
if (*val > pData[i]) { __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(uint16_t*)&(pBuf->v), &pBuf->tuplePos)
*val = pData[i]; break;
}
}
} else { // max
for (int32_t i = start; i < start + numOfRows; ++i) {
if (*val < pData[i]) {
*val = pData[i];
}
}
} }
}
numOfElems = numOfRows; 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;
}
return numOfElems; 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;
}
static int32_t findRowIndex(int32_t start, int32_t num, SColumnInfoData* pCol, const char* tval) { case TSDB_DATA_TYPE_FLOAT: {
// the data is loaded, not only the block SMA value const float* pData = (const float*)pCol->pData;
for (int32_t i = start; i < num + start; ++i) { __COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(float*)&(pBuf->v), &pBuf->tuplePos)
char* p = colDataGetData(pCol, i); break;
if (memcmp((void*)tval, p, pCol->info.bytes) == 0) { }
return i;
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;
}
} }
} }
// 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 doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
...@@ -857,6 +744,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { ...@@ -857,6 +744,7 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
if (pInput->colDataSMAIsSet) { if (pInput->colDataSMAIsSet) {
numOfElems = pInput->numOfRows - pAgg->numOfNull; numOfElems = pInput->numOfRows - pAgg->numOfNull;
ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0); ASSERT(pInput->numOfRows == pInput->totalRows && numOfElems >= 0);
if (numOfElems == 0) { if (numOfElems == 0) {
return numOfElems; return numOfElems;
} }
...@@ -945,212 +833,80 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) { ...@@ -945,212 +833,80 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc) {
int32_t start = pInput->startRowIndex; int32_t start = pInput->startRowIndex;
int32_t numOfRows = pInput->numOfRows; int32_t numOfRows = pInput->numOfRows;
int32_t end = start + numOfRows;
if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) { if (pCol->hasNull || numOfRows < 32 || pCtx->subsidiaries.num > 0) {
if (type == TSDB_DATA_TYPE_TINYINT || type == TSDB_DATA_TYPE_BOOL) { int32_t i = findFirstValPosition(pCol, start, numOfRows);
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);
}
} 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 ((i < end) && (!pBuf->assign)) {
if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { memcpy(&pBuf->v, pCol->pData + (pCol->info.bytes * i), pCol->info.bytes);
continue;
}
if (!pBuf->assign) { if (pCtx->subsidiaries.num > 0) {
*val = pData[i]; pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL);
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) { pBuf->assign = true;
uint16_t* pData = (uint16_t*)pCol->pData; numOfElems = 1;
uint16_t* val = (uint16_t*)&pBuf->v; }
for (int32_t i = start; i < start + numOfRows; ++i) { if (i >= end) {
if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) { ASSERT(numOfElems == 0);
continue; return numOfElems;
} }
if (!pBuf->assign) { doExtractVal(pCol, i, end, pCtx, pBuf, isMinFunc);
*val = pData[i]; } else {
if (pCtx->subsidiaries.num > 0) { numOfElems = numOfRows;
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; 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_UINT) { case TSDB_DATA_TYPE_SMALLINT: {
uint32_t* pData = (uint32_t*)pCol->pData; handleInt16Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, true);
uint32_t* val = (uint32_t*)&pBuf->v; break;
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) { case TSDB_DATA_TYPE_INT: {
uint64_t* pData = (uint64_t*)pCol->pData; handleInt32Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, true);
uint64_t* val = (uint64_t*)&pBuf->v; break;
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: {
} else if (type == TSDB_DATA_TYPE_DOUBLE) { handleInt64Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, true);
double* pData = (double*)pCol->pData; break;
double* val = (double*)&pBuf->v;
for (int32_t i = start; i < start + numOfRows; ++i) {
if ((pCol->hasNull) && colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
} }
case TSDB_DATA_TYPE_UTINYINT: {
if (!pBuf->assign) { handleInt8Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false);
*val = pData[i]; break;
if (pCtx->subsidiaries.num > 0) { }
pBuf->tuplePos = saveTupleData(pCtx, i, pCtx->pSrcBlock, NULL); case TSDB_DATA_TYPE_USMALLINT: {
} handleInt16Col(pCol->pData, start, numOfRows, pBuf, isMinFunc, false);
pBuf->assign = true; break;
} 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);
}
}
}
} }
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;
}
}
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; 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.
先完成此消息的编辑!
想要评论请 注册