]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
add custom quicksort, where the comparison function takes an extra argument for param...
authorPeter Stamfest <peter@stamfest.at>
Wed, 27 Aug 2014 06:28:01 +0000 (08:28 +0200)
committerPeter Stamfest <peter@stamfest.at>
Sun, 31 Aug 2014 20:19:23 +0000 (22:19 +0200)
Using quicksort might in practice actually be overkill, because most of the time we will
sort rather short arrays anyway.

src/Makefile.am
src/quicksort.c [new file with mode: 0644]
src/quicksort.h [new file with mode: 0644]

index 5d9a6cf430f66be14845b398dd1a2652e1a13910..5bf3f327859a03055bb528eec76b286a3cc79ea6 100644 (file)
@@ -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 (file)
index 0000000..1bcadaf
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 (file)
index 0000000..844c9d8
--- /dev/null
@@ -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 */
+