2 * collectd - src/sn_network.c
3 * Copyright (C) 2008 Florian octo Forster
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Florian octo Forster <octo at verplant.org>
29 #include "sn_network.h"
30 #include "sn_random.h"
32 sn_network_t *sn_network_create (int inputs_num)
36 n = (sn_network_t *) malloc (sizeof (sn_network_t));
39 memset (n, '\0', sizeof (sn_network_t));
41 n->inputs_num = inputs_num;
44 } /* sn_network_t *sn_network_create */
46 void sn_network_destroy (sn_network_t *n)
51 if (n->stages != NULL)
54 for (i = 0; i < n->stages_num; i++)
56 sn_stage_destroy (n->stages[i]);
64 } /* void sn_network_destroy */
66 int sn_network_stage_add (sn_network_t *n, sn_stage_t *s)
70 temp = (sn_stage_t **) realloc (n->stages, (n->stages_num + 1)
71 * sizeof (sn_stage_t *));
76 SN_STAGE_DEPTH (s) = n->stages_num;
77 n->stages[n->stages_num] = s;
81 } /* int sn_network_stage_add */
83 int sn_network_stage_remove (sn_network_t *n, int s_num)
85 int nmemb = n->stages_num - (s_num + 1);
88 assert (s_num < n->stages_num);
90 sn_stage_destroy (n->stages[s_num]);
91 n->stages[s_num] = NULL;
95 memmove (n->stages + s_num, n->stages + (s_num + 1),
96 nmemb * sizeof (sn_stage_t *));
97 n->stages[n->stages_num - 1] = NULL;
101 /* Free the unused memory */
102 if (n->stages_num == 0)
109 temp = (sn_stage_t **) realloc (n->stages,
110 n->stages_num * sizeof (sn_stage_t *));
117 } /* int sn_network_stage_remove */
119 sn_network_t *sn_network_clone (const sn_network_t *n)
121 sn_network_t *n_copy;
124 n_copy = sn_network_create (n->inputs_num);
128 for (i = 0; i < n->stages_num; i++)
133 s = sn_stage_clone (n->stages[i]);
137 status = sn_network_stage_add (n_copy, s);
142 if (i < n->stages_num)
144 sn_network_destroy (n_copy);
149 } /* sn_network_t *sn_network_clone */
151 int sn_network_show (sn_network_t *n)
155 for (i = 0; i < n->stages_num; i++)
156 sn_stage_show (n->stages[i]);
159 } /* int sn_network_show */
161 int sn_network_invert (sn_network_t *n)
165 for (i = 0; i < n->stages_num; i++)
166 sn_stage_invert (n->stages[i]);
169 } /* int sn_network_invert */
171 int sn_network_compress (sn_network_t *n)
177 for (i = 1; i < n->stages_num; i++)
183 for (j = 0; j < SN_STAGE_COMP_NUM (s); j++)
185 sn_comparator_t *c = SN_STAGE_COMP_GET (s, j);
188 for (k = i - 1; k >= 0; k--)
192 conflict = sn_stage_comparator_check_conflict (n->stages[k], c);
207 sn_stage_comparator_add (n->stages[move_to], c);
208 sn_stage_comparator_remove (s, j);
214 while ((n->stages_num > 0)
215 && (SN_STAGE_COMP_NUM (n->stages[n->stages_num - 1]) == 0))
216 sn_network_stage_remove (n, n->stages_num - 1);
219 } /* int sn_network_compress */
221 int sn_network_normalize (sn_network_t *n)
225 for (i = n->stages_num - 1; i >= 0; i--)
232 for (j = 0; j < SN_STAGE_COMP_NUM (s); j++)
238 c = SN_STAGE_COMP_GET (s, j);
247 for (k = i; k >= 0; k--)
248 sn_stage_swap (n->stages[k], min, max);
250 } /* for (j = 0 .. #comparators) */
251 } /* for (i = n->stages_num - 1 .. 0) */
254 } /* int sn_network_normalize */
256 int sn_network_cut_at (sn_network_t *n, int input, enum sn_network_cut_dir_e dir)
259 int position = input;
261 for (i = 0; i < n->stages_num; i++)
267 new_position = sn_stage_cut_at (s, position, dir);
269 if (position != new_position)
273 for (j = 0; j < i; j++)
274 sn_stage_swap (n->stages[j], position, new_position);
277 position = new_position;
280 assert (((dir == DIR_MIN) && (position == 0))
281 || ((dir == DIR_MAX) && (position == (n->inputs_num - 1))));
283 for (i = 0; i < n->stages_num; i++)
284 sn_stage_remove_input (n->stages[i], position);
289 } /* int sn_network_cut_at */
291 static int sn_network_add_bitonic_merger_recursive (sn_network_t *n,
301 s = sn_stage_create (n->stages_num);
307 for (i = low; i < (low + m); i++)
314 sn_stage_comparator_add (s, &c);
317 sn_network_stage_add (n, s);
319 sn_network_add_bitonic_merger_recursive (n, low, m);
320 sn_network_add_bitonic_merger_recursive (n, low + m, m);
323 } /* int sn_network_add_bitonic_merger_recursive */
325 static int sn_network_add_bitonic_merger (sn_network_t *n)
331 s = sn_stage_create (n->stages_num);
335 m = n->inputs_num / 2;
337 for (i = 0; i < m; i++)
342 c.max = n->inputs_num - (i + 1);
344 sn_stage_comparator_add (s, &c);
347 sn_network_stage_add (n, s);
349 sn_network_add_bitonic_merger_recursive (n, 0, m);
350 sn_network_add_bitonic_merger_recursive (n, m, m);
353 } /* int sn_network_add_bitonic_merger */
355 static int sn_network_add_odd_even_merger_recursive (sn_network_t *n,
356 int *indizes, int indizes_num)
362 int indizes_half_num;
367 indizes_half_num = indizes_num / 2;
368 indizes_half = (int *) malloc (indizes_num * sizeof (int));
369 if (indizes_half == NULL)
372 for (i = 0; i < indizes_half_num; i++)
374 indizes_half[i] = indizes[2 * i];
375 indizes_half[indizes_half_num + i] = indizes[(2 * i) + 1];
378 status = sn_network_add_odd_even_merger_recursive (n,
379 indizes_half, indizes_half_num);
386 status = sn_network_add_odd_even_merger_recursive (n,
387 indizes_half + indizes_half_num, indizes_half_num);
396 s = sn_stage_create (n->stages_num);
400 for (i = 1; i < (indizes_num - 2); i += 2)
403 c.max = indizes[i + 1];
405 sn_stage_comparator_add (s, &c);
408 sn_network_stage_add (n, s);
415 assert (indizes_num == 2);
420 s = sn_stage_create (n->stages_num);
424 sn_stage_comparator_add (s, &c);
425 sn_network_stage_add (n, s);
429 } /* int sn_network_add_odd_even_merger_recursive */
431 static int sn_network_add_odd_even_merger (sn_network_t *n)
438 indizes_num = n->inputs_num;
439 indizes = (int *) malloc (indizes_num * sizeof (int));
443 for (i = 0; i < indizes_num; i++)
446 status = sn_network_add_odd_even_merger_recursive (n,
447 indizes, indizes_num);
451 } /* int sn_network_add_bitonic_merger */
453 sn_network_t *sn_network_combine (sn_network_t *n0, sn_network_t *n1)
460 stages_num = (n0->stages_num > n1->stages_num)
464 n = sn_network_create (n0->inputs_num + n1->inputs_num);
468 for (i = 0; i < stages_num; i++)
470 sn_stage_t *s = sn_stage_create (i);
472 if (i < n0->stages_num)
473 for (j = 0; j < SN_STAGE_COMP_NUM (n0->stages[i]); j++)
475 sn_comparator_t *c = SN_STAGE_COMP_GET (n0->stages[i], j);
476 sn_stage_comparator_add (s, c);
479 if (i < n1->stages_num)
480 for (j = 0; j < SN_STAGE_COMP_NUM (n1->stages[i]); j++)
482 sn_comparator_t *c_orig = SN_STAGE_COMP_GET (n1->stages[i], j);
483 sn_comparator_t c_copy;
485 SN_COMP_MIN(&c_copy) = SN_COMP_MIN(c_orig) + n0->inputs_num;
486 SN_COMP_MAX(&c_copy) = SN_COMP_MAX(c_orig) + n0->inputs_num;
488 sn_stage_comparator_add (s, &c_copy);
491 sn_network_stage_add (n, s);
494 if (sn_bounded_random (0, 1) == 0)
496 sn_network_add_bitonic_merger (n);
500 sn_network_add_odd_even_merger (n);
503 sn_network_compress (n);
506 } /* sn_network_t *sn_network_combine */
508 sn_network_t *sn_network_read (FILE *fh)
515 while (fgets (buffer, sizeof (buffer), fh) != NULL)
517 char *str_key = buffer;
518 char *str_value = NULL;
519 int buffer_len = strlen (buffer);
521 while ((buffer_len > 0) && ((buffer[buffer_len - 1] == '\n')
522 || (buffer[buffer_len - 1] == '\r')))
525 buffer[buffer_len] = '\0';
530 str_value = strchr (buffer, ':');
531 if (str_value == NULL)
533 printf ("Cannot parse line: %s\n", buffer);
537 *str_value = '\0'; str_value++;
538 while ((*str_value != '\0') && (isspace (*str_value) != 0))
541 if (strcasecmp ("Inputs", str_key) == 0)
542 opt_inputs = atoi (str_value);
544 printf ("Unknown key: %s\n", str_key);
545 } /* while (fgets) */
550 n = sn_network_create (opt_inputs);
556 s = sn_stage_read (fh);
560 sn_network_stage_add (n, s);
563 if (SN_NETWORK_STAGE_NUM (n) < 1)
565 sn_network_destroy (n);
570 } /* sn_network_t *sn_network_read */
572 sn_network_t *sn_network_read_file (const char *file)
577 fh = fopen (file, "r");
581 n = sn_network_read (fh);
586 } /* sn_network_t *sn_network_read_file */
588 int sn_network_write (sn_network_t *n, FILE *fh)
592 fprintf (fh, "Inputs: %i\n", n->inputs_num);
595 for (i = 0; i < n->stages_num; i++)
596 sn_stage_write (n->stages[i], fh);
599 } /* int sn_network_write */
601 int sn_network_write_file (sn_network_t *n, const char *file)
606 fh = fopen (file, "w");
610 status = sn_network_write (n, fh);
615 } /* int sn_network_write_file */
617 /* vim: set shiftwidth=2 softtabstop=2 : */