1 /* http://dhcpd-pools.sourceforge.net/
2 ** Copyright 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 3 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, see <http://www.gnu.org/licenses/>.
28 #include "dhcpd-pools.h"
30 /* Sort functions for range sorting */
31 int intcomp(const void *x, const void *y)
33 if (*(unsigned long int *) x < *(unsigned long int *) y)
35 else if (*(unsigned long int *) y < *(unsigned long int *) x)
41 int rangecomp(const void *r1, const void *r2)
43 if ((((struct range_t *) r1)->first_ip) <
44 (((struct range_t *) r2)->first_ip))
46 else if ((((struct range_t *) r2)->first_ip) <
47 (((struct range_t *) r1)->first_ip))
53 unsigned long int ret_ip(struct range_t r)
58 unsigned long int ret_cur(struct range_t r)
63 unsigned long int ret_max(struct range_t r)
65 return (r.last_ip - r.first_ip);
68 unsigned long int ret_percent(struct range_t r)
71 f = (float) r.count / (r.last_ip - r.first_ip - 1);
72 return ((unsigned long int) (f * 100000));
75 unsigned long int ret_touched(struct range_t r)
80 unsigned long int ret_tc(struct range_t r)
82 return (r.count + r.touched);
85 unsigned long int ret_tcperc(struct range_t r)
88 f = (float) (r.count + r.touched) / (r.last_ip - r.first_ip - 1);
89 return ((unsigned long int) (f * 10000));
92 void field_selector(char c)
107 returner = ret_percent;
110 returner = ret_touched;
116 returner = ret_tcperc;
119 warnx("field_selector: unknown sort order `%c'", c);
120 errx(EXIT_FAILURE, "Try `%s --help' for more information.",
121 program_invocation_short_name);
125 /* Needed to support multiple key sorting. */
126 int get_order(struct range_t *left, struct range_t *right)
129 unsigned long int lint, rint;
131 len = strlen(config.sort);
132 for (i = 0; i < len; i++) {
133 /* Handling strings is case of it's own */
134 if (config.sort[i] == 'n') {
136 strcmp(left->shared_net->name,
137 right->shared_net->name);
140 } else if (ret < 0) {
147 /* Select which function is pointed by returner */
148 field_selector(config.sort[i]);
149 lint = returner(*left);
150 rint = returner(*right);
151 /* If fields are equal use next sort method */
161 /* If all returners where equal */
165 void mergesort_ranges(struct range_t *orig, int size, struct range_t *temp)
169 /* Merge sort split size */
170 static const int MIN_MERGE_SIZE = 8;
172 if (size < MIN_MERGE_SIZE) {
173 for (left = 0; left < size; left++) {
174 hold = *(orig + left);
175 for (right = left - 1; 0 <= right; right--) {
176 if (get_order((orig + right), &hold)) {
179 *(orig + right + 1) = *(orig + right);
181 *(orig + right + 1) = hold;
186 mergesort_ranges(orig, size / 2, temp);
187 mergesort_ranges(orig + size / 2, size - size / 2, temp);
193 while (left < size / 2 && right < size) {
194 if (get_order((orig + left), (orig + right))) {
195 *(temp + i) = *(orig + left);
198 *(temp + i) = *(orig + right);
203 while (left < size / 2) {
204 *(temp + i) = *(orig + left);
208 while (right < size) {
209 *(temp + i) = *(orig + right);
214 memcpy(orig, temp, size * sizeof(struct range_t));