Merge pull request #6338 from taosdata/feature/TD-2574
[TD-2574]<enhance>: refactored algorithms for top and bottom functions.
This commit is contained in:
commit
b62632f816
|
@ -1758,6 +1758,49 @@ static void valuePairAssign(tValuePair *dst, int16_t type, const char *val, int6
|
|||
memcpy((dst)->pTags, (src)->pTags, (size_t)(__l)); \
|
||||
} while (0)
|
||||
|
||||
static int32_t topBotComparFn(const void *p1, const void *p2, const void *param)
|
||||
{
|
||||
uint16_t type = *(uint16_t *) param;
|
||||
tValuePair *val1 = *(tValuePair **) p1;
|
||||
tValuePair *val2 = *(tValuePair **) p2;
|
||||
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||
if (val1->v.i64 == val2->v.i64) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (val1->v.i64 > val2->v.i64) ? 1 : -1;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
if (val1->v.u64 == val2->v.u64) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (val1->v.u64 > val2->v.u64) ? 1 : -1;
|
||||
}
|
||||
|
||||
if (val1->v.dKey == val2->v.dKey) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (val1->v.dKey > val2->v.dKey) ? 1 : -1;
|
||||
}
|
||||
|
||||
static void topBotSwapFn(void *dst, void *src, const void *param)
|
||||
{
|
||||
char tag[32768];
|
||||
tValuePair temp;
|
||||
uint16_t tagLen = *(uint16_t *) param;
|
||||
tValuePair *vdst = *(tValuePair **) dst;
|
||||
tValuePair *vsrc = *(tValuePair **) src;
|
||||
|
||||
memset(tag, 0, sizeof(tag));
|
||||
temp.pTags = tag;
|
||||
|
||||
VALUEPAIRASSIGN(&temp, vdst, tagLen);
|
||||
VALUEPAIRASSIGN(vdst, vsrc, tagLen);
|
||||
VALUEPAIRASSIGN(vsrc, &temp, tagLen);
|
||||
}
|
||||
|
||||
static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData, int64_t ts, uint16_t type,
|
||||
SExtTagsInfo *pTagInfo, char *pTags, int16_t stage) {
|
||||
tVariant val = {0};
|
||||
|
@ -1765,61 +1808,19 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData,
|
|||
|
||||
tValuePair **pList = pInfo->res;
|
||||
assert(pList != NULL);
|
||||
|
||||
|
||||
if (pInfo->num < maxLen) {
|
||||
if (pInfo->num == 0 ||
|
||||
(IS_SIGNED_NUMERIC_TYPE(type) && val.i64 >= pList[pInfo->num - 1]->v.i64) ||
|
||||
(IS_UNSIGNED_NUMERIC_TYPE(type) && val.u64 >= pList[pInfo->num - 1]->v.u64) ||
|
||||
(IS_FLOAT_TYPE(type) && val.dKey >= pList[pInfo->num - 1]->v.dKey)) {
|
||||
valuePairAssign(pList[pInfo->num], type, (const char*)&val.i64, ts, pTags, pTagInfo, stage);
|
||||
} else {
|
||||
int32_t i = pInfo->num - 1;
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||
while (i >= 0 && pList[i]->v.i64 > val.i64) {
|
||||
VALUEPAIRASSIGN(pList[i + 1], pList[i], pTagInfo->tagsLen);
|
||||
i -= 1;
|
||||
}
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
while (i >= 0 && pList[i]->v.u64 > val.u64) {
|
||||
VALUEPAIRASSIGN(pList[i + 1], pList[i], pTagInfo->tagsLen);
|
||||
i -= 1;
|
||||
}
|
||||
} else {
|
||||
while (i >= 0 && pList[i]->v.dKey > val.dKey) {
|
||||
VALUEPAIRASSIGN(pList[i + 1], pList[i], pTagInfo->tagsLen);
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
valuePairAssign(pList[i + 1], type, (const char*) &val.i64, ts, pTags, pTagInfo, stage);
|
||||
}
|
||||
|
||||
valuePairAssign(pList[pInfo->num], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage);
|
||||
|
||||
taosheapsort((void *) pList, sizeof(tValuePair **), pInfo->num + 1, (const void *) &type, topBotComparFn, (const void *) &pTagInfo->tagsLen, topBotSwapFn, 0);
|
||||
|
||||
pInfo->num++;
|
||||
} else {
|
||||
int32_t i = 0;
|
||||
|
||||
if ((IS_SIGNED_NUMERIC_TYPE(type) && val.i64 > pList[0]->v.i64) ||
|
||||
(IS_UNSIGNED_NUMERIC_TYPE(type) && val.u64 > pList[0]->v.u64) ||
|
||||
(IS_FLOAT_TYPE(type) && val.dKey > pList[0]->v.dKey)) {
|
||||
// find the appropriate the slot position
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||
while (i + 1 < maxLen && pList[i + 1]->v.i64 < val.i64) {
|
||||
VALUEPAIRASSIGN(pList[i], pList[i + 1], pTagInfo->tagsLen);
|
||||
i += 1;
|
||||
}
|
||||
} if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
while (i + 1 < maxLen && pList[i + 1]->v.u64 < val.u64) {
|
||||
VALUEPAIRASSIGN(pList[i], pList[i + 1], pTagInfo->tagsLen);
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
while (i + 1 < maxLen && pList[i + 1]->v.dKey < val.dKey) {
|
||||
VALUEPAIRASSIGN(pList[i], pList[i + 1], pTagInfo->tagsLen);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
valuePairAssign(pList[i], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage);
|
||||
valuePairAssign(pList[0], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage);
|
||||
taosheapadjust((void *) pList, sizeof(tValuePair **), 0, maxLen - 1, (const void *) &type, topBotComparFn, (const void *) &pTagInfo->tagsLen, topBotSwapFn, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1833,57 +1834,17 @@ static void do_bottom_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pDa
|
|||
assert(pList != NULL);
|
||||
|
||||
if (pInfo->num < maxLen) {
|
||||
if (pInfo->num == 0) {
|
||||
valuePairAssign(pList[pInfo->num], type, (const char*) &val.i64, ts, pTags, pTagInfo, stage);
|
||||
} else {
|
||||
int32_t i = pInfo->num - 1;
|
||||
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||
while (i >= 0 && pList[i]->v.i64 < val.i64) {
|
||||
VALUEPAIRASSIGN(pList[i + 1], pList[i], pTagInfo->tagsLen);
|
||||
i -= 1;
|
||||
}
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
while (i >= 0 && pList[i]->v.u64 < val.u64) {
|
||||
VALUEPAIRASSIGN(pList[i + 1], pList[i], pTagInfo->tagsLen);
|
||||
i -= 1;
|
||||
}
|
||||
} else {
|
||||
while (i >= 0 && pList[i]->v.dKey < val.dKey) {
|
||||
VALUEPAIRASSIGN(pList[i + 1], pList[i], pTagInfo->tagsLen);
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
valuePairAssign(pList[i + 1], type, (const char*)&val.i64, ts, pTags, pTagInfo, stage);
|
||||
}
|
||||
|
||||
valuePairAssign(pList[pInfo->num], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage);
|
||||
|
||||
taosheapsort((void *) pList, sizeof(tValuePair **), pInfo->num + 1, (const void *) &type, topBotComparFn, (const void *) &pTagInfo->tagsLen, topBotSwapFn, 1);
|
||||
|
||||
pInfo->num++;
|
||||
} else {
|
||||
int32_t i = 0;
|
||||
|
||||
if ((IS_SIGNED_NUMERIC_TYPE(type) && val.i64 < pList[0]->v.i64) ||
|
||||
(IS_UNSIGNED_NUMERIC_TYPE(type) && val.u64 < pList[0]->v.u64) ||
|
||||
(IS_FLOAT_TYPE(type) && val.dKey < pList[0]->v.dKey)) {
|
||||
// find the appropriate the slot position
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||
while (i + 1 < maxLen && pList[i + 1]->v.i64 > val.i64) {
|
||||
VALUEPAIRASSIGN(pList[i], pList[i + 1], pTagInfo->tagsLen);
|
||||
i += 1;
|
||||
}
|
||||
} if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
while (i + 1 < maxLen && pList[i + 1]->v.u64 > val.u64) {
|
||||
VALUEPAIRASSIGN(pList[i], pList[i + 1], pTagInfo->tagsLen);
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
while (i + 1 < maxLen && pList[i + 1]->v.dKey > val.dKey) {
|
||||
VALUEPAIRASSIGN(pList[i], pList[i + 1], pTagInfo->tagsLen);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
valuePairAssign(pList[i], type, (const char*)&val.i64, ts, pTags, pTagInfo, stage);
|
||||
valuePairAssign(pList[0], type, (const char *)&val.i64, ts, pTags, pTagInfo, stage);
|
||||
taosheapadjust((void *) pList, sizeof(tValuePair **), 0, maxLen - 1, (const void *) &type, topBotComparFn, (const void *) &pTagInfo->tagsLen, topBotSwapFn, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ typedef int (*__compar_fn_t) (const void *, const void *);
|
|||
#define elePtrAt(base, size, idx) (void *)((char *)(base) + (size) * (idx))
|
||||
|
||||
typedef int32_t (*__ext_compar_fn_t)(const void *p1, const void *p2, const void *param);
|
||||
typedef void (*__ext_swap_fn_t)(void *p1, void *p2, const void *param);
|
||||
|
||||
/**
|
||||
* quick sort, with the compare function requiring additional parameters support
|
||||
|
@ -59,6 +60,38 @@ void taosqsort(void *src, size_t numOfElem, size_t size, const void* param, __ex
|
|||
*/
|
||||
void *taosbsearch(const void *key, const void *base, size_t nmemb, size_t size, __compar_fn_t fn, int flags);
|
||||
|
||||
/**
|
||||
* adjust heap
|
||||
*
|
||||
* @param base: the start address of array
|
||||
* @param size: size of every item in array
|
||||
* @param start: the first index
|
||||
* @param end: the last index
|
||||
* @param parcompar: parameters for compare function
|
||||
* @param compar: user defined compare function
|
||||
* @param parswap: parameters for swap function
|
||||
* @param swap: user defined swap function, the default swap function doswap will be used if swap is NULL
|
||||
* @param maxroot: if heap is max root heap
|
||||
* @return
|
||||
*/
|
||||
void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const void *parcompar, __ext_compar_fn_t compar, const void *parswap, __ext_swap_fn_t swap, bool maxroot);
|
||||
|
||||
/**
|
||||
* sort heap to make sure it is a max/min root heap
|
||||
*
|
||||
* @param base: the start address of array
|
||||
* @param size: size of every item in array
|
||||
* @param len: the length of array
|
||||
* @param parcompar: parameters for compare function
|
||||
* @param compar: user defined compare function
|
||||
* @param parswap: parameters for swap function
|
||||
* @param swap: user defined swap function, the default swap function doswap will be used if swap is NULL
|
||||
* @param maxroot: if heap is max root heap
|
||||
* @return
|
||||
*/
|
||||
void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar, __ext_compar_fn_t compar, const void *parswap, __ext_swap_fn_t swap, bool maxroot);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -225,3 +225,89 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const void *parcompar, __ext_compar_fn_t compar, const void *parswap, __ext_swap_fn_t swap, bool maxroot)
|
||||
{
|
||||
int32_t parent;
|
||||
int32_t child;
|
||||
char *buf;
|
||||
|
||||
if (base && size > 0 && compar) {
|
||||
parent = start;
|
||||
child = 2 * parent + 1;
|
||||
|
||||
if (swap == NULL) {
|
||||
buf = calloc(1, size);
|
||||
if (buf == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxroot) {
|
||||
while (child <= end) {
|
||||
if (child + 1 <= end && (*compar)(elePtrAt(base, size, child), elePtrAt(base, size, child + 1), parcompar) < 0) {
|
||||
child++;
|
||||
}
|
||||
|
||||
if ((*compar)(elePtrAt(base, size, parent), elePtrAt(base, size, child), parcompar) > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (swap == NULL) {
|
||||
doswap(elePtrAt(base, size, parent), elePtrAt(base, size, child), size, buf);
|
||||
} else {
|
||||
(*swap)(elePtrAt(base, size, parent), elePtrAt(base, size, child), parswap);
|
||||
}
|
||||
|
||||
parent = child;
|
||||
child = 2 * parent + 1;
|
||||
}
|
||||
} else {
|
||||
while (child <= end) {
|
||||
if (child + 1 <= end && (*compar)(elePtrAt(base, size, child), elePtrAt(base, size, child + 1), parcompar) > 0) {
|
||||
child++;
|
||||
}
|
||||
|
||||
if ((*compar)(elePtrAt(base, size, parent), elePtrAt(base, size, child), parcompar) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (swap == NULL) {
|
||||
doswap(elePtrAt(base, size, parent), elePtrAt(base, size, child), size, buf);
|
||||
} else {
|
||||
(*swap)(elePtrAt(base, size, parent), elePtrAt(base, size, child), parswap);
|
||||
}
|
||||
|
||||
parent = child;
|
||||
child = 2 * parent + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (swap == NULL) {
|
||||
tfree(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar, __ext_compar_fn_t compar, const void *parswap, __ext_swap_fn_t swap, bool maxroot)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if (base && size > 0) {
|
||||
for (i = len / 2 - 1; i >= 0; i--) {
|
||||
taosheapadjust(base, size, i, len - 1, parcompar, compar, parswap, swap, maxroot);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
char *buf = calloc(1, size);
|
||||
|
||||
for (i = len - 1; i > 0; i--) {
|
||||
doswap(elePtrAt(base, size, 0), elePtrAt(base, size, i));
|
||||
taosheapadjust(base, size, 0, i - 1, parcompar, compar, parswap, swap, maxroot);
|
||||
}
|
||||
|
||||
tfree(buf);
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
|
@ -190,32 +190,32 @@ if $rows != 12800 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
sql select top(c1, 100), tbname, t1, t2 from select_tags_mt0;
|
||||
if $rows != 100 then
|
||||
sql select top(c1, 80), tbname, t1, t2 from select_tags_mt0;
|
||||
if $rows != 80 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != @70-01-01 08:03:30.100@ then
|
||||
if $data00 != @70-01-01 08:03:40.100@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != @70-01-01 08:03:30.200@ then
|
||||
if $data10 != @70-01-01 08:03:40.200@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 110 then
|
||||
if $data01 != 111 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != @select_tags_tb11@ then
|
||||
if $data02 != @select_tags_tb12@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 11 then
|
||||
if $data03 != 12 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data04 != @abc11@ then
|
||||
if $data04 != @abc12@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -248,8 +248,8 @@ if $data04 != @abc12@ then
|
|||
return -1
|
||||
endi
|
||||
|
||||
sql select bottom(c1, 100), tbname, t1, t2 from select_tags_mt0;
|
||||
if $rows != 100 then
|
||||
sql select bottom(c1, 72), tbname, t1, t2 from select_tags_mt0;
|
||||
if $rows != 72 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
Loading…
Reference in New Issue