/**
- * collectd - src/sn_network.c
+ * libsortnetwork - src/sn_network.c
* Copyright (C) 2008-2010 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
#include <strings.h>
#include <ctype.h>
#include <assert.h>
+#include <errno.h>
#include "sn_network.h"
#include "sn_random.h"
}
} /* }}} sn_network_t *sn_network_create_odd_even_mergesort */
+static int sn_network_create_pairwise_internal (sn_network_t *n, /* {{{ */
+ int *inputs, int inputs_num)
+{
+ int i;
+ int inputs_copy[inputs_num];
+ int m;
+
+ for (i = 1; i < inputs_num; i += 2)
+ {
+ sn_comparator_t *c = sn_comparator_create (inputs[i-1], inputs[i]);
+ sn_network_comparator_add (n, c);
+ sn_comparator_destroy (c);
+ }
+
+ if (inputs_num <= 2)
+ return (0);
+
+ /* Sort "pairs" recursively. Like with odd-even mergesort, odd and even lines
+ * are handled recursively and later reunited. */
+ for (i = 0; i < inputs_num; i += 2)
+ inputs_copy[(int) (i / 2)] = inputs[i];
+ /* Recursive call #1 with first set of lines */
+ sn_network_create_pairwise_internal (n, inputs_copy,
+ (int) ((inputs_num + 1) / 2));
+
+ for (i = 1; i < inputs_num; i += 2)
+ inputs_copy[(int) (i / 2)] = inputs[i];
+ /* Recursive call #2 with second set of lines */
+ sn_network_create_pairwise_internal (n, inputs_copy,
+ (int) (inputs_num/ 2));
+
+ /* m is the "amplitude" of the sorted pairs. This is a bit tricky to read due
+ * to different indices being used in the paper, unfortunately. */
+ m = inputs_num / 2;
+ while (m > 1)
+ {
+ for (i = 1; (i + (m - 1)) < inputs_num; i += 2)
+ {
+ int left = i;
+ int right = i + (m - 1);
+ sn_comparator_t *c;
+
+ assert (left < right);
+ c = sn_comparator_create (inputs[left], inputs[right]);
+ sn_network_comparator_add (n, c);
+ sn_comparator_destroy (c);
+ }
+
+ m = m / 2;
+ } /* while (m > 1) */
+
+ return (0);
+} /* }}} int sn_network_create_pairwise_internal */
+
+sn_network_t *sn_network_create_pairwise (int inputs_num) /* {{{ */
+{
+ sn_network_t *n = sn_network_create (inputs_num);
+ int inputs[inputs_num];
+ int i;
+
+ if (n == NULL)
+ return (NULL);
+
+ for (i = 0; i < inputs_num; i++)
+ inputs[i] = i;
+
+ sn_network_create_pairwise_internal (n, inputs, inputs_num);
+ sn_network_compress (n);
+
+ return (n);
+} /* }}} sn_network_t *sn_network_create_pairwise */
+
int sn_network_stage_add (sn_network_t *n, sn_stage_t *s) /* {{{ */
{
sn_stage_t **temp;
+ if ((n == NULL) || (s == NULL))
+ return (EINVAL);
+
temp = (sn_stage_t **) realloc (n->stages, (n->stages_num + 1)
* sizeof (sn_stage_t *));
if (temp == NULL)
int nmemb = n->stages_num - (s_num + 1);
sn_stage_t **temp;
- assert (s_num < n->stages_num);
+ if ((n == NULL) || (s_num >= n->stages_num))
+ return (EINVAL);
sn_stage_destroy (n->stages[s_num]);
n->stages[s_num] = NULL;
sn_stage_t *s;
if ((n == NULL) || (c == NULL))
- return (-1);
+ return (EINVAL);
if (n->stages_num > 0)
{
{
int i;
+ if (n == NULL)
+ return (EINVAL);
+
for (i = 0; i < n->stages_num; i++)
sn_stage_invert (n->stages[i]);
{
int i;
+ if ((n == NULL) || (sw < 0))
+ return (EINVAL);
+
+ if (sw == 0)
+ return (0);
+
for (i = 0; i < n->stages_num; i++)
sn_stage_shift (n->stages[i], sw, SN_NETWORK_INPUT_NUM (n));
return (n);
} /* }}} sn_network_t *sn_network_combine_bitonic_shift */
-sn_network_t *sn_network_combine_bitonic (sn_network_t *n0, /* {{{ */
+sn_network_t *sn_network_combine_bitonic_merge (sn_network_t *n0, /* {{{ */
sn_network_t *n1)
{
return (sn_network_combine_bitonic_shift (n0, n1, /* do_shift = */ 0));
-} /* }}} sn_network_t *sn_network_combine_bitonic */
+} /* }}} sn_network_t *sn_network_combine_bitonic_merge */
sn_network_t *sn_network_combine_odd_even_merge (sn_network_t *n0, /* {{{ */
sn_network_t *n1)
sn_network_compress (n);
return (n);
-} /* }}} sn_network_t *sn_network_combine */
+} /* }}} sn_network_t *sn_network_combine_odd_even_merge */
sn_network_t *sn_network_combine (sn_network_t *n0, /* {{{ */
- sn_network_t *n1, int is_power_of_two)
+ sn_network_t *n1)
{
- sn_network_t *n;
-
- if ((is_power_of_two != 0) && (sn_bounded_random (0, 9) == 0))
- {
- DPRINTF ("sn_network_combine: Using the bitonic merger.\n");
- n = sn_network_combine_bitonic_shift (n0, n1, /* do_shift = */ 1);
- }
- else
- {
- DPRINTF ("sn_network_combine: Using the odd-even merger.\n");
- n = sn_network_combine_odd_even_merge (n0, n1);
- }
-
- sn_network_compress (n);
-
- return (n);
+ return (sn_network_combine_odd_even_merge (n0, n1));
} /* }}} sn_network_t *sn_network_combine */
int sn_network_sort (sn_network_t *n, int *values) /* {{{ */
#define SNPRINTF_OR_FAIL(...) \
status = snprintf (buffer, buffer_size, __VA_ARGS__); \
- if ((status < 1) || (status >= buffer_size)) \
+ if ((status < 1) || (((size_t) status) >= buffer_size)) \
return (-1); \
buffer += status; \
buffer_size -= status;