mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-17 16:26:59 +00:00
sort: Use a comparer instead of returner
This resolves the FIXME of sorting ranges according to first_ip in IPv6 mode.
This commit is contained in:
parent
4051a953bd
commit
137c1d37c2
2 changed files with 75 additions and 44 deletions
|
|
@ -223,12 +223,8 @@ int leasecomp(const void *restrict a, const void *restrict b);
|
||||||
int rangecomp(const void *__restrict r1, const void *__restrict r2)
|
int rangecomp(const void *__restrict r1, const void *__restrict r2)
|
||||||
__attribute__ ((nonnull(1, 2)));
|
__attribute__ ((nonnull(1, 2)));
|
||||||
/* sort function pointer and functions */
|
/* sort function pointer and functions */
|
||||||
unsigned long int (*returner) (struct range_t r);
|
int (*comparer) (struct range_t *r1, struct range_t *r2);
|
||||||
unsigned long int ret_ip(struct range_t r);
|
|
||||||
unsigned long int ret_cur(struct range_t r);
|
|
||||||
unsigned long int ret_max(struct range_t r);
|
|
||||||
unsigned long int ret_percent(struct range_t r);
|
unsigned long int ret_percent(struct range_t r);
|
||||||
unsigned long int ret_touched(struct range_t r);
|
|
||||||
unsigned long int ret_tc(struct range_t r);
|
unsigned long int ret_tc(struct range_t r);
|
||||||
unsigned long int ret_tcperc(struct range_t r);
|
unsigned long int ret_tcperc(struct range_t r);
|
||||||
void field_selector(char c);
|
void field_selector(char c);
|
||||||
|
|
|
||||||
113
src/sort.c
113
src/sort.c
|
|
@ -3,6 +3,7 @@
|
||||||
* BSD License" or "FreeBSD License".
|
* BSD License" or "FreeBSD License".
|
||||||
*
|
*
|
||||||
* Copyright 2006- Sami Kerola. All rights reserved.
|
* Copyright 2006- Sami Kerola. All rights reserved.
|
||||||
|
* Copyright 2012 Cheer Xiao.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -87,32 +88,76 @@ int rangecomp(const void *restrict r1, const void *restrict r2)
|
||||||
&((const struct range_t *)r2)->first_ip);
|
&((const struct range_t *)r2)->first_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Return IP.
|
/*! \brief Compare two unsigned long.
|
||||||
* \param r A range structure.
|
* \param u1,u2 Data to compare.
|
||||||
* \return First IP in the range, perhaps?? maybe?
|
* \return Like strcmp.
|
||||||
* FIXME: This function is not implemented, yet.
|
|
||||||
*/
|
*/
|
||||||
unsigned long int ret_ip(struct range_t r)
|
int comp_ulong(unsigned long u1, unsigned long u2)
|
||||||
{
|
{
|
||||||
return (r.first_ip.v4);
|
return u1 < u2 ? -1 : u1 > u2 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief In use in range.
|
/*! \brief Compare two range_t by their first_ip.
|
||||||
* \param r A range structure.
|
* \param r1,r2 Pointers to data to compare.
|
||||||
* \return Number of addresses that are in use in the given range.
|
* \return Like strcmp.
|
||||||
*/
|
*/
|
||||||
unsigned long int ret_cur(struct range_t r)
|
int comp_ip(struct range_t *r1, struct range_t *r2)
|
||||||
{
|
{
|
||||||
return (r.count);
|
return ipcomp(&r1->first_ip, &r2->first_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Range maximum.
|
/*! \brief Compare two range_t by their capacity.
|
||||||
* \param r A range structure.
|
* \param r1,r2 Pointers to data to compare.
|
||||||
* \return Maximum number of addresses that can be in the given range.
|
* \return Like strcmp.
|
||||||
*/
|
*/
|
||||||
unsigned long int ret_max(struct range_t r)
|
int comp_max(struct range_t *r1, struct range_t *r2)
|
||||||
{
|
{
|
||||||
return get_range_size(&r);
|
return comp_ulong(get_range_size(r1), get_range_size(r2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Compare two range_t by their current usage.
|
||||||
|
* \param r1,r2 Pointers to data to compare.
|
||||||
|
* \return Like strcmp.
|
||||||
|
*/
|
||||||
|
int comp_cur(struct range_t *r1, struct range_t *r2)
|
||||||
|
{
|
||||||
|
return comp_ulong(r1->count, r2->count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Compare two range_t by their current usage percentage.
|
||||||
|
* \param r1,r2 Pointers to data to compare.
|
||||||
|
* \return Like strcmp.
|
||||||
|
*/
|
||||||
|
int comp_percent(struct range_t *r1, struct range_t *r2)
|
||||||
|
{
|
||||||
|
return comp_ulong(ret_percent(*r1), ret_percent(*r2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Compare two range_t by their touched addresses.
|
||||||
|
* \param r1,r2 Pointers to data to compare.
|
||||||
|
* \return Like strcmp.
|
||||||
|
*/
|
||||||
|
int comp_touched(struct range_t *r1, struct range_t *r2)
|
||||||
|
{
|
||||||
|
return comp_ulong(r1->touched, r2->touched);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Compare two range_t by their touched and in use addresses.
|
||||||
|
* \param r1,r2 Pointers to data to compare.
|
||||||
|
* \return Like strcmp.
|
||||||
|
*/
|
||||||
|
int comp_tc(struct range_t *r1, struct range_t *r2)
|
||||||
|
{
|
||||||
|
return comp_ulong(ret_tc(*r1), ret_tc(*r2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Compare two range_t by their touched and in use percentage.
|
||||||
|
* \param r1,r2 Pointers to data to compare.
|
||||||
|
* \return Like strcmp.
|
||||||
|
*/
|
||||||
|
int comp_tcperc(struct range_t *r1, struct range_t *r2)
|
||||||
|
{
|
||||||
|
return comp_ulong(ret_tcperc(*r1), ret_tcperc(*r2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Percentage in use in range.
|
/*! \brief Percentage in use in range.
|
||||||
|
|
@ -126,15 +171,6 @@ unsigned long int ret_percent(struct range_t r)
|
||||||
return ((unsigned long int)(f * 100000));
|
return ((unsigned long int)(f * 100000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Touched in range.
|
|
||||||
* \param r A range structure.
|
|
||||||
* \return Number of touched addresses in the given range.
|
|
||||||
*/
|
|
||||||
unsigned long int ret_touched(struct range_t r)
|
|
||||||
{
|
|
||||||
return (r.touched);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief Touched and in use in range
|
/*! \brief Touched and in use in range
|
||||||
* \param r A range structure.
|
* \param r A range structure.
|
||||||
* \return Number of touched or in use addresses in the given range.
|
* \return Number of touched or in use addresses in the given range.
|
||||||
|
|
@ -167,25 +203,25 @@ void field_selector(char c)
|
||||||
case 'n':
|
case 'n':
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
returner = ret_ip;
|
comparer = comp_ip;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
returner = ret_max;
|
comparer = comp_max;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
returner = ret_cur;
|
comparer = comp_cur;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
returner = ret_percent;
|
comparer = comp_percent;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
returner = ret_touched;
|
comparer = comp_touched;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
returner = ret_tc;
|
comparer = comp_tc;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
returner = ret_tcperc;
|
comparer = comp_tcperc;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
warnx("field_selector: unknown sort order `%c'", c);
|
warnx("field_selector: unknown sort order `%c'", c);
|
||||||
|
|
@ -202,7 +238,7 @@ void field_selector(char c)
|
||||||
static int merge(struct range_t *restrict left, struct range_t *restrict right)
|
static int merge(struct range_t *restrict left, struct range_t *restrict right)
|
||||||
{
|
{
|
||||||
int i, len, ret;
|
int i, len, ret;
|
||||||
unsigned long int lint, rint;
|
int cmp;
|
||||||
|
|
||||||
len = strlen(config.sort);
|
len = strlen(config.sort);
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
|
|
@ -218,21 +254,20 @@ static int merge(struct range_t *restrict left, struct range_t *restrict right)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select which function is pointed by returner */
|
/* Select which function is pointed by comparer */
|
||||||
field_selector(config.sort[i]);
|
field_selector(config.sort[i]);
|
||||||
lint = returner(*left);
|
cmp = comparer(left, right);
|
||||||
rint = returner(*right);
|
|
||||||
/* If fields are equal use next sort method */
|
/* If fields are equal use next sort method */
|
||||||
if (lint == rint) {
|
if (cmp == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (lint < rint) {
|
if (cmp < 0) {
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If all returners where equal */
|
/* If all comparers where equal */
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue