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.
27 #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 eprintf("field_selector: unknown sort order: %c",
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)
170 if (size < MIN_MERGE_SIZE) {
171 for (left = 0; left < size; left++) {
172 hold = *(orig + left);
173 for (right = left - 1; right >= 0; right--) {
174 if (get_order((orig + right), &hold)) {
177 *(orig + right + 1) = *(orig + right);
179 *(orig + right + 1) = hold;
184 mergesort_ranges(orig, size / 2, temp);
185 mergesort_ranges(orig + size / 2, size - size / 2, temp);
191 while (left < size / 2 && right < size) {
192 if (get_order((orig + left), (orig + right))) {
193 *(temp + i) = *(orig + left);
196 *(temp + i) = *(orig + right);
201 while (left < size / 2) {
202 *(temp + i) = *(orig + left);
206 while (right < size) {
207 *(temp + i) = *(orig + right);
212 memcpy(orig, temp, size * sizeof(struct range_t));