From: Peter Stamfest Date: Wed, 27 Aug 2014 06:28:01 +0000 (+0200) Subject: add custom quicksort, where the comparison function takes an extra argument for param... X-Git-Tag: v1.5.0-rc1~42^2~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=71d2b32159c03e0ee9d1af64d5df686b4e4f6700;p=thirdparty%2Frrdtool-1.x.git add custom quicksort, where the comparison function takes an extra argument for parameters Using quicksort might in practice actually be overkill, because most of the time we will sort rather short arrays anyway. --- diff --git a/src/Makefile.am b/src/Makefile.am index 5d9a6cf4..5bf3f327 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,7 +36,8 @@ UPD_C_FILES = \ rrd_utils.c \ rrd_snprintf.c \ rrd_update.c \ - rrd_modify.c + rrd_modify.c \ + quicksort.c RRD_C_FILES = \ rrd_version.c \ @@ -72,7 +73,8 @@ noinst_HEADERS = \ rrd_restore.h rrd_create.h \ fnv.h rrd_graph.h \ rrd_is_thread_safe.h \ - rrd_modify.h rrd_update.h rrd_config.h + rrd_modify.h rrd_update.h rrd_config.h \ + quicksort.h if BUILD_LIBDBI RRD_C_FILES += rrd_fetch_libdbi.c diff --git a/src/quicksort.c b/src/quicksort.c new file mode 100644 index 00000000..1bcadafc --- /dev/null +++ b/src/quicksort.c @@ -0,0 +1,57 @@ +/* + * File: quicksort.c + * Author: Peter Stamfest + * + * Created on August 26, 2014, 6:02 PM + * + * This file is in the public domain. + */ + +#include +#include +#include + +#include "quicksort.h" + +static void swap(void *x, void *y, size_t l) { + char *a = x, *b = y, c; + while(l--) { + c = *a; + *a++ = *b; + *b++ = c; + } +} + +static void sort(char *array, size_t size, compar_ex_t cmp, int begin, int end, void *extra) { + if (begin >= end) return; + // begin < end + + int l = begin + size, r = end; + void *p = array + begin; // pivot element + + while (l < r) { + if (cmp(array + l, p, extra) <= 0) { + l += size; + } else if(cmp(array + r, p, extra) >= 0) { + r -= size; + } else { + swap(array + l, array + r, size); + } + } + + if (cmp(array + l, p, extra) <= 0) { + swap(array + l, p, size); + l -= size; + } else { + l -= size; + swap(array + l, p, size); + } + + // recurse + sort(array, size, cmp, begin, l, extra); + sort(array, size, cmp, r, end, extra); +} + +void quick_sort(void *array, size_t size, size_t nitems, compar_ex_t *cmp, void *extra) { + sort(array, size, cmp, 0, (nitems - 1) * size, extra); +} diff --git a/src/quicksort.h b/src/quicksort.h new file mode 100644 index 00000000..844c9d8b --- /dev/null +++ b/src/quicksort.h @@ -0,0 +1,36 @@ +/* + * File: quicksort.h + * Author: Peter Stamfest + * + * Created on August 26, 2014, 6:07 PM + * + * This file is in the public domain. + */ + +#ifndef QUICKSORT_H +#define QUICKSORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int compar_ex_t(const void *a, const void *b, const void *extra); + +/** + * An extended quick sort algorithm compared to stdlib qsort. Takes an extra + * parameter passed through to the comparation function (of type compar_ex_t). + * + * @param array The array to sort + * @param size The size of array elements + * @param nitems The number of array elements to sort + * @param cmp The comparation function. + * @param extra Extra data passed to the comparation function + */ +void quick_sort(void *array, size_t size, size_t nitems, compar_ex_t *cmp, void *extra); + +#ifdef __cplusplus +} +#endif + +#endif /* QUICKSORT_H */ +