From ac70331977d872ce414156a46533ee20013febbc Mon Sep 17 00:00:00 2001 From: szdytom Date: Sun, 16 Jun 2024 20:31:37 +0800 Subject: [PATCH 1/3] add stable_sort --- include/pocketpy/common/algorithm.h | 12 ++++++++ src/common/algorithm.c | 45 +++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/pocketpy/common/algorithm.h b/include/pocketpy/common/algorithm.h index 92a09328..94ed2999 100644 --- a/include/pocketpy/common/algorithm.h +++ b/include/pocketpy/common/algorithm.h @@ -25,6 +25,18 @@ extern "C" { *(out_index) = __first - (T*)(ptr); \ } while(0) +/** + * @brief Sorts an array of elements of the same type, using the given comparison function. + * @param ptr Pointer to the first element of the array. + * @param count Number of elements in the array. + * @param elem_size Size of each element in the array. + * @param cmp Comparison function that takes two elements and returns an integer similar to `strcmp`. + */ +void c11__stable_sort(void* ptr, + int count, + int elem_size, + int (*cmp)(const void* a, const void* b)); + #ifdef __cplusplus } diff --git a/src/common/algorithm.c b/src/common/algorithm.c index efdf9f2f..f922517d 100644 --- a/src/common/algorithm.c +++ b/src/common/algorithm.c @@ -1,2 +1,47 @@ #include "pocketpy/common/algorithm.h" +#include +#include +static void merge(void* a_begin, + void* a_end, + void* b_begin, + void* b_end, + void* res, + int elem_size, + int (*cmp)(const void* a, const void* b)) { + void *a = a_begin, *b = b_begin, *r = res; + while(a < a_end && b < b_end) { + if(cmp(a, b) <= 0) { + memcpy(r, a, elem_size); + a += elem_size; + } else { + memcpy(r, b, elem_size); + b += elem_size; + } + r += elem_size; + } + + // one of the arrays is empty + for(; a < a_end; a += elem_size, r += elem_size) + memcpy(r, a, elem_size); + for(; b < b_end; b += elem_size, r += elem_size) + memcpy(r, b, elem_size); +} + +void c11__stable_sort(void* ptr, + int count, + int elem_size, + int (*cmp)(const void* a, const void* b)) { + // merge sort + void* tmp = malloc(count * elem_size); + for(int seg = 1; seg < count; seg *= 2) { + for(void* a = ptr; a < ptr + (count - seg) * elem_size; a += 2 * seg * elem_size) { + void* b = a + seg * elem_size, *a_end = b, *b_end = b + seg * elem_size; + if (b_end > ptr + count * elem_size) + b_end = ptr + count * elem_size; + merge(a, a_end, b, b_end, tmp, elem_size, cmp); + memcpy(a, tmp, (b_end - a) * elem_size); + } + } + free(tmp); +} From ebdfb794ba75cccf47dcc3d80e52e38f870a0d4f Mon Sep 17 00:00:00 2001 From: szdytom Date: Sun, 16 Jun 2024 20:57:45 +0800 Subject: [PATCH 2/3] fix memcpy length --- src/common/algorithm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/algorithm.c b/src/common/algorithm.c index f922517d..74013d20 100644 --- a/src/common/algorithm.c +++ b/src/common/algorithm.c @@ -40,7 +40,7 @@ void c11__stable_sort(void* ptr, if (b_end > ptr + count * elem_size) b_end = ptr + count * elem_size; merge(a, a_end, b, b_end, tmp, elem_size, cmp); - memcpy(a, tmp, (b_end - a) * elem_size); + memcpy(a, tmp, b_end - a); } } free(tmp); From 3728c02b87f2044b4bc63a113996fd7b1dd13e3b Mon Sep 17 00:00:00 2001 From: szdytom Date: Sun, 16 Jun 2024 21:36:50 +0800 Subject: [PATCH 3/3] fix for cl --- src/common/algorithm.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/common/algorithm.c b/src/common/algorithm.c index 74013d20..e99c7e69 100644 --- a/src/common/algorithm.c +++ b/src/common/algorithm.c @@ -2,14 +2,14 @@ #include #include -static void merge(void* a_begin, - void* a_end, - void* b_begin, - void* b_end, - void* res, +static void merge(char* a_begin, + char* a_end, + char* b_begin, + char* b_end, + char* res, int elem_size, int (*cmp)(const void* a, const void* b)) { - void *a = a_begin, *b = b_begin, *r = res; + char *a = a_begin, *b = b_begin, *r = res; while(a < a_end && b < b_end) { if(cmp(a, b) <= 0) { memcpy(r, a, elem_size); @@ -28,15 +28,15 @@ static void merge(void* a_begin, memcpy(r, b, elem_size); } -void c11__stable_sort(void* ptr, +void c11__stable_sort(void* ptr_, int count, int elem_size, int (*cmp)(const void* a, const void* b)) { // merge sort - void* tmp = malloc(count * elem_size); + char* ptr = ptr_, *tmp = malloc(count * elem_size); for(int seg = 1; seg < count; seg *= 2) { - for(void* a = ptr; a < ptr + (count - seg) * elem_size; a += 2 * seg * elem_size) { - void* b = a + seg * elem_size, *a_end = b, *b_end = b + seg * elem_size; + for(char* a = ptr; a < ptr + (count - seg) * elem_size; a += 2 * seg * elem_size) { + char* b = a + seg * elem_size, *a_end = b, *b_end = b + seg * elem_size; if (b_end > ptr + count * elem_size) b_end = ptr + count * elem_size; merge(a, a_end, b, b_end, tmp, elem_size, cmp);