提交 6494ed76 编写于 作者: S Shengliang Guan

talgo

上级 c7e5ee34
...@@ -13,16 +13,18 @@ ...@@ -13,16 +13,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _TD_UTIL_TALGO_H #ifndef _TD_UTIL_TALGO_H_
#define _TD_UTIL_TALGO_H #define _TD_UTIL_TALGO_H_
#include "os.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#ifndef __COMPAR_FN_T #ifndef __COMPAR_FN_T
# define __COMPAR_FN_T #define __COMPAR_FN_T
typedef int (*__compar_fn_t) (const void *, const void *); typedef int32_t (*__compar_fn_t)(const void *, const void *);
#endif #endif
#define TD_EQ 0x1 #define TD_EQ 0x1
...@@ -45,7 +47,7 @@ typedef void (*__ext_swap_fn_t)(void *p1, void *p2, const void *param); ...@@ -45,7 +47,7 @@ typedef void (*__ext_swap_fn_t)(void *p1, void *p2, const void *param);
* @param param * @param param
* @param comparFn * @param comparFn
*/ */
void taosqsort(void *src, size_t numOfElem, size_t size, const void* param, __ext_compar_fn_t comparFn); void taosqsort(void *src, int64_t numOfElem, int64_t size, const void *param, __ext_compar_fn_t comparFn);
/** /**
* binary search, with range support * binary search, with range support
...@@ -58,7 +60,7 @@ void taosqsort(void *src, size_t numOfElem, size_t size, const void* param, __ex ...@@ -58,7 +60,7 @@ void taosqsort(void *src, size_t numOfElem, size_t size, const void* param, __ex
* @param flags * @param flags
* @return * @return
*/ */
void *taosbsearch(const void *key, const void *base, size_t nmemb, size_t size, __compar_fn_t fn, int flags); void *taosbsearch(const void *key, const void *base, int64_t nmemb, int64_t size, __compar_fn_t fn, int32_t flags);
/** /**
* adjust heap * adjust heap
...@@ -74,7 +76,8 @@ void *taosbsearch(const void *key, const void *base, size_t nmemb, size_t size, ...@@ -74,7 +76,8 @@ void *taosbsearch(const void *key, const void *base, size_t nmemb, size_t size,
* @param maxroot: if heap is max root heap * @param maxroot: if heap is max root heap
* @return * @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); 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 * sort heap to make sure it is a max/min root heap
...@@ -89,10 +92,11 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const ...@@ -89,10 +92,11 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const
* @param maxroot: if heap is max root heap * @param maxroot: if heap is max root heap
* @return * @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); 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 #ifdef __cplusplus
} }
#endif #endif
#endif /*_TD_UTIL_TALGO_H*/
#endif /*_TD_UTIL_TALGO_H_*/
...@@ -13,30 +13,33 @@ ...@@ -13,30 +13,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "os.h" #define _DEFAULT_SOURCE
#include "talgo.h" #include "talgo.h"
#define doswap(__left, __right, __size, __buf) do {\ #define doswap(__left, __right, __size, __buf) \
memcpy((__buf), (__left), (__size));\ do { \
memcpy((__left), (__right),(__size));\ memcpy((__buf), (__left), (__size)); \
memcpy((__right), (__buf), (__size));\ memcpy((__left), (__right), (__size)); \
} while (0); memcpy((__right), (__buf), (__size)); \
} while (0);
static void median(void *src, size_t size, size_t s, size_t e, const void *param, __ext_compar_fn_t comparFn, void* buf) { static void median(void *src, int64_t size, int64_t s, int64_t e, const void *param, __ext_compar_fn_t comparFn,
void *buf) {
int32_t mid = ((int32_t)(e - s) >> 1u) + (int32_t)s; int32_t mid = ((int32_t)(e - s) >> 1u) + (int32_t)s;
if (comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), param) == 1) { if (comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), param) == 1) {
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, s), size, buf); doswap(elePtrAt(src, size, mid), elePtrAt(src, size, s), size, buf);
} }
if (comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, e), param) == 1) { if (comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, e), param) == 1) {
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, s), size, buf); doswap(elePtrAt(src, size, mid), elePtrAt(src, size, s), size, buf);
doswap(elePtrAt(src, size, mid), elePtrAt(src, size, e), size, buf); doswap(elePtrAt(src, size, mid), elePtrAt(src, size, e), size, buf);
} else if (comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param) == 1) { } else if (comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param) == 1) {
doswap(elePtrAt(src, size, s), elePtrAt(src, size, e), size, buf); doswap(elePtrAt(src, size, s), elePtrAt(src, size, e), size, buf);
} }
assert(comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), param) <= 0 && comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param) <= 0); assert(comparFn(elePtrAt(src, size, mid), elePtrAt(src, size, s), param) <= 0 &&
comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param) <= 0);
#ifdef _DEBUG_VIEW #ifdef _DEBUG_VIEW
// tTagsPrints(src[s], pOrderDesc->pColumnModel, &pOrderDesc->orderIdx); // tTagsPrints(src[s], pOrderDesc->pColumnModel, &pOrderDesc->orderIdx);
...@@ -45,8 +48,8 @@ static void median(void *src, size_t size, size_t s, size_t e, const void *param ...@@ -45,8 +48,8 @@ static void median(void *src, size_t size, size_t s, size_t e, const void *param
#endif #endif
} }
static void tInsertSort(void *src, size_t size, int32_t s, int32_t e, const void *param, __ext_compar_fn_t comparFn, static void tInsertSort(void *src, int64_t size, int32_t s, int32_t e, const void *param, __ext_compar_fn_t comparFn,
void* buf) { void *buf) {
for (int32_t i = s + 1; i <= e; ++i) { for (int32_t i = s + 1; i <= e; ++i) {
for (int32_t j = i; j > s; --j) { for (int32_t j = i; j > s; --j) {
if (comparFn(elePtrAt(src, size, j), elePtrAt(src, size, j - 1), param) == -1) { if (comparFn(elePtrAt(src, size, j), elePtrAt(src, size, j - 1), param) == -1) {
...@@ -58,117 +61,117 @@ static void tInsertSort(void *src, size_t size, int32_t s, int32_t e, const void ...@@ -58,117 +61,117 @@ static void tInsertSort(void *src, size_t size, int32_t s, int32_t e, const void
} }
} }
static void tqsortImpl(void *src, int32_t start, int32_t end, size_t size, const void *param, __ext_compar_fn_t comparFn, static void tqsortImpl(void *src, int32_t start, int32_t end, int64_t size, const void *param,
void* buf) { __ext_compar_fn_t comparFn, void *buf) {
// short array sort, incur another sort procedure instead of quick sort process // short array sort, incur another sort procedure instead of quick sort process
const int32_t THRESHOLD_SIZE = 6; const int32_t THRESHOLD_SIZE = 6;
if (end - start + 1 <= THRESHOLD_SIZE) { if (end - start + 1 <= THRESHOLD_SIZE) {
tInsertSort(src, size, start, end, param, comparFn, buf); tInsertSort(src, size, start, end, param, comparFn, buf);
return; return;
} }
median(src, size, start, end, param, comparFn, buf); median(src, size, start, end, param, comparFn, buf);
int32_t s = start, e = end; int32_t s = start, e = end;
int32_t endRightS = end, startLeftS = start; int32_t endRightS = end, startLeftS = start;
while (s < e) { while (s < e) {
while (e > s) { while (e > s) {
int32_t ret = comparFn(elePtrAt(src, size, e), elePtrAt(src, size, s), param); int32_t ret = comparFn(elePtrAt(src, size, e), elePtrAt(src, size, s), param);
if (ret < 0) { if (ret < 0) {
break; break;
} }
//move the data that equals to pivotal value to the right end of the list // move the data that equals to pivotal value to the right end of the list
if (ret == 0 && e != endRightS) { if (ret == 0 && e != endRightS) {
doswap(elePtrAt(src, size, e), elePtrAt(src, size, endRightS), size, buf); doswap(elePtrAt(src, size, e), elePtrAt(src, size, endRightS), size, buf);
endRightS--; endRightS--;
} }
e--; e--;
} }
if (e != s) { if (e != s) {
doswap(elePtrAt(src, size, e), elePtrAt(src, size, s), size, buf); doswap(elePtrAt(src, size, e), elePtrAt(src, size, s), size, buf);
} }
while (s < e) { while (s < e) {
int32_t ret = comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param); int32_t ret = comparFn(elePtrAt(src, size, s), elePtrAt(src, size, e), param);
if (ret > 0) { if (ret > 0) {
break; break;
} }
if (ret == 0 && s != startLeftS) { if (ret == 0 && s != startLeftS) {
doswap(elePtrAt(src, size, s), elePtrAt(src, size, startLeftS), size, buf); doswap(elePtrAt(src, size, s), elePtrAt(src, size, startLeftS), size, buf);
startLeftS++; startLeftS++;
} }
s++; s++;
} }
if (e != s) { if (e != s) {
doswap(elePtrAt(src, size, s), elePtrAt(src, size, e), size, buf); doswap(elePtrAt(src, size, s), elePtrAt(src, size, e), size, buf);
} }
} }
int32_t rightPartStart = e + 1; int32_t rightPartStart = e + 1;
if (endRightS != end && e < end) { if (endRightS != end && e < end) {
int32_t left = rightPartStart; int32_t left = rightPartStart;
int32_t right = end; int32_t right = end;
while (right > endRightS && left <= endRightS) { while (right > endRightS && left <= endRightS) {
doswap(elePtrAt(src, size, left), elePtrAt(src, size, right), size, buf); doswap(elePtrAt(src, size, left), elePtrAt(src, size, right), size, buf);
left++; left++;
right--; right--;
} }
rightPartStart += (end - endRightS); rightPartStart += (end - endRightS);
} }
int32_t leftPartEnd = e - 1; int32_t leftPartEnd = e - 1;
if (startLeftS != end && s > start) { if (startLeftS != end && s > start) {
int32_t left = start; int32_t left = start;
int32_t right = leftPartEnd; int32_t right = leftPartEnd;
while (left < startLeftS && right >= startLeftS) { while (left < startLeftS && right >= startLeftS) {
doswap(elePtrAt(src, size, left), elePtrAt(src, size, right), size, buf); doswap(elePtrAt(src, size, left), elePtrAt(src, size, right), size, buf);
left++; left++;
right--; right--;
} }
leftPartEnd -= (startLeftS - start); leftPartEnd -= (startLeftS - start);
} }
if (leftPartEnd > start) { if (leftPartEnd > start) {
tqsortImpl(src, start, leftPartEnd, size, param, comparFn, buf); tqsortImpl(src, start, leftPartEnd, size, param, comparFn, buf);
} }
if (rightPartStart < end) { if (rightPartStart < end) {
tqsortImpl(src, rightPartStart, end, size, param, comparFn, buf); tqsortImpl(src, rightPartStart, end, size, param, comparFn, buf);
} }
} }
void taosqsort(void *src, size_t numOfElem, size_t size, const void* param, __ext_compar_fn_t comparFn) { void taosqsort(void *src, int64_t numOfElem, int64_t size, const void *param, __ext_compar_fn_t comparFn) {
char *buf = calloc(1, size); // prepare the swap buffer char *buf = calloc(1, size); // prepare the swap buffer
tqsortImpl(src, 0, (int32_t)numOfElem - 1, (int32_t)size, param, comparFn, buf); tqsortImpl(src, 0, (int32_t)numOfElem - 1, (int32_t)size, param, comparFn, buf);
tfree(buf); tfree(buf);
} }
void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size, __compar_fn_t compar, int flags) { void *taosbsearch(const void *key, const void *base, int64_t nmemb, int64_t size, __compar_fn_t compar, int flags) {
// TODO: need to check the correctness of this function // TODO: need to check the correctness of this function
int l = 0; int l = 0;
int r = (int)nmemb; int r = (int)nmemb;
int idx = 0; int idx = 0;
int comparison; int comparison;
if (flags == TD_EQ) { if (flags == TD_EQ) {
return bsearch(key, base, nmemb, size, compar); return bsearch(key, base, nmemb, size, compar);
} else if (flags == TD_GE) { } else if (flags == TD_GE) {
if (nmemb <= 0) return NULL; if (nmemb <= 0) return NULL;
if ((*compar)(key, elePtrAt(base, size, 0)) <= 0) return elePtrAt(base, size, 0); if ((*compar)(key, elePtrAt(base, size, 0)) <= 0) return elePtrAt(base, size, 0);
if ((*compar)(key, elePtrAt(base, size, nmemb - 1)) > 0) return NULL; if ((*compar)(key, elePtrAt(base, size, nmemb - 1)) > 0) return NULL;
while (l < r) { while (l < r) {
idx = (l + r) / 2; idx = (l + r) / 2;
comparison = (*compar)(key, elePtrAt(base, size, idx)); comparison = (*compar)(key, elePtrAt(base, size, idx));
...@@ -180,7 +183,7 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size, ...@@ -180,7 +183,7 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size,
return elePtrAt(base, size, idx); return elePtrAt(base, size, idx);
} }
} }
if ((*compar)(key, elePtrAt(base, size, idx)) < 0) { if ((*compar)(key, elePtrAt(base, size, idx)) < 0) {
return elePtrAt(base, size, idx); return elePtrAt(base, size, idx);
} else { } else {
...@@ -194,7 +197,7 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size, ...@@ -194,7 +197,7 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size,
if (nmemb <= 0) return NULL; if (nmemb <= 0) return NULL;
if ((*compar)(key, elePtrAt(base, size, nmemb - 1)) >= 0) return elePtrAt(base, size, nmemb - 1); if ((*compar)(key, elePtrAt(base, size, nmemb - 1)) >= 0) return elePtrAt(base, size, nmemb - 1);
if ((*compar)(key, elePtrAt(base, size, 0)) < 0) return NULL; if ((*compar)(key, elePtrAt(base, size, 0)) < 0) return NULL;
while (l < r) { while (l < r) {
idx = (l + r) / 2; idx = (l + r) / 2;
comparison = (*compar)(key, elePtrAt(base, size, idx)); comparison = (*compar)(key, elePtrAt(base, size, idx));
...@@ -206,7 +209,7 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size, ...@@ -206,7 +209,7 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size,
return elePtrAt(base, size, idx); return elePtrAt(base, size, idx);
} }
} }
if ((*compar)(key, elePtrAt(base, size, idx)) > 0) { if ((*compar)(key, elePtrAt(base, size, idx)) > 0) {
return elePtrAt(base, size, idx); return elePtrAt(base, size, idx);
} else { } else {
...@@ -216,20 +219,20 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size, ...@@ -216,20 +219,20 @@ void * taosbsearch(const void *key, const void *base, size_t nmemb, size_t size,
return elePtrAt(base, size, idx - 1); return elePtrAt(base, size, idx - 1);
} }
} }
} else { } else {
assert(0); assert(0);
return NULL; return NULL;
} }
return NULL; 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) 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 parent;
int32_t child; int32_t child;
char *buf; char *buf;
if (base && size > 0 && compar) { if (base && size > 0 && compar) {
parent = start; parent = start;
...@@ -244,7 +247,8 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const ...@@ -244,7 +247,8 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const
if (maxroot) { if (maxroot) {
while (child <= end) { while (child <= end) {
if (child + 1 <= end && (*compar)(elePtrAt(base, size, child), elePtrAt(base, size, child + 1), parcompar) < 0) { if (child + 1 <= end &&
(*compar)(elePtrAt(base, size, child), elePtrAt(base, size, child + 1), parcompar) < 0) {
child++; child++;
} }
...@@ -263,7 +267,8 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const ...@@ -263,7 +267,8 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const
} }
} else { } else {
while (child <= end) { while (child <= end) {
if (child + 1 <= end && (*compar)(elePtrAt(base, size, child), elePtrAt(base, size, child + 1), parcompar) > 0) { if (child + 1 <= end &&
(*compar)(elePtrAt(base, size, child), elePtrAt(base, size, child + 1), parcompar) > 0) {
child++; child++;
} }
...@@ -288,9 +293,9 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const ...@@ -288,9 +293,9 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const
} }
} }
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) 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; int32_t i;
if (base && size > 0) { if (base && size > 0) {
for (i = len / 2 - 1; i >= 0; i--) { for (i = len / 2 - 1; i >= 0; i--) {
...@@ -298,15 +303,14 @@ void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar, ...@@ -298,15 +303,14 @@ void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar,
} }
} }
/* /*
char *buf = calloc(1, size); char *buf = calloc(1, size);
for (i = len - 1; i > 0; i--) { for (i = len - 1; i > 0; i--) {
doswap(elePtrAt(base, size, 0), elePtrAt(base, size, i)); doswap(elePtrAt(base, size, 0), elePtrAt(base, size, i));
taosheapadjust(base, size, 0, i - 1, parcompar, compar, parswap, swap, maxroot); taosheapadjust(base, size, 0, i - 1, parcompar, compar, parswap, swap, maxroot);
} }
tfree(buf); tfree(buf);
*/ */
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册