2 ** Copyright (C) 2006- Sami Kerola <kerolasa@iki.fi>
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU General Public License for more details.
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include "dhcpd-pools.h"
31 /* Sort functions for range sorting */
32 int intcomp(const void *x, const void *y)
34 if (*(unsigned long int *) x < *(unsigned long int *) y)
36 else if (*(unsigned long int *) y < *(unsigned long int *) x)
42 int rangecomp(const void *r1, const void *r2)
44 if ((((struct range_t *) r1)->first_ip) <
45 (((struct range_t *) r2)->first_ip))
47 else if ((((struct range_t *) r2)->first_ip) <
48 (((struct range_t *) r1)->first_ip))
54 unsigned long int ret_ip(struct range_t r)
59 unsigned long int ret_cur(struct range_t r)
64 unsigned long int ret_max(struct range_t r)
66 return (r.last_ip - r.first_ip);
69 unsigned long int ret_percent(struct range_t r)
72 f = (float) r.count / (r.last_ip - r.first_ip - 1);
73 return ((unsigned long int) (f * 100000));
76 unsigned long int ret_touched(struct range_t r)
81 unsigned long int ret_tc(struct range_t r)
83 return (r.count + r.touched);
86 unsigned long int ret_tcperc(struct range_t r)
89 f = (float) (r.count + r.touched) / (r.last_ip - r.first_ip - 1);
90 return ((unsigned long int) (f * 10000));
93 void field_selector(char c)
108 returner = ret_percent;
111 returner = ret_touched;
117 returner = ret_tcperc;
121 "field_selector: unknown sort order `%c'",
126 /* Needed to support multiple key sorting. */
127 int get_order(struct range_t *left, struct range_t *right)
130 unsigned long int lint, rint;
132 len = strlen(config.sort);
133 for (i = 0; i < len; i++) {
134 /* Handling strings is case of it's own */
135 if (config.sort[i] == 'n') {
137 strcmp(left->shared_net->name,
138 right->shared_net->name);
141 } else if (ret < 0) {
148 /* Select which function is pointed by returner */
149 field_selector(config.sort[i]);
150 lint = returner(*left);
151 rint = returner(*right);
152 /* If fields are equal use next sort method */
162 /* If all returners where equal */
166 void mergesort_ranges(struct range_t *orig, int size, struct range_t *temp)
171 if (size < MIN_MERGE_SIZE) {
172 for (left = 0; left < size; left++) {
173 hold = *(orig + left);
174 for (right = left - 1; 0 <= right; right--) {
175 if (get_order((orig + right), &hold)) {
178 *(orig + right + 1) = *(orig + right);
180 *(orig + right + 1) = hold;
185 mergesort_ranges(orig, size / 2, temp);
186 mergesort_ranges(orig + size / 2, size - size / 2, temp);
192 while (left < size / 2 && right < size) {
193 if (get_order((orig + left), (orig + right))) {
194 *(temp + i) = *(orig + left);
197 *(temp + i) = *(orig + right);
202 while (left < size / 2) {
203 *(temp + i) = *(orig + left);
207 while (right < size) {
208 *(temp + i) = *(orig + right);
213 memcpy(orig, temp, size * sizeof(struct range_t));