未验证 提交 b62632f8 编写于 作者: H Haojun Liao 提交者: GitHub

Merge pull request #6338 from taosdata/feature/TD-2574

[TD-2574]<enhance>: refactored algorithms for top and bottom functions.
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册