mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-16 15:57:00 +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)
|
||||
__attribute__ ((nonnull(1, 2)));
|
||||
/* sort function pointer and functions */
|
||||
unsigned long int (*returner) (struct range_t r);
|
||||
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);
|
||||
int (*comparer) (struct range_t *r1, struct range_t *r2);
|
||||
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_tcperc(struct range_t r);
|
||||
void field_selector(char c);
|
||||
|
|
|
|||
113
src/sort.c
113
src/sort.c
|
|
@ -3,6 +3,7 @@
|
|||
* BSD License" or "FreeBSD License".
|
||||
*
|
||||
* Copyright 2006- Sami Kerola. All rights reserved.
|
||||
* Copyright 2012 Cheer Xiao.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*! \brief Return IP.
|
||||
* \param r A range structure.
|
||||
* \return First IP in the range, perhaps?? maybe?
|
||||
* FIXME: This function is not implemented, yet.
|
||||
/*! \brief Compare two unsigned long.
|
||||
* \param u1,u2 Data to compare.
|
||||
* \return Like strcmp.
|
||||
*/
|
||||
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.
|
||||
* \param r A range structure.
|
||||
* \return Number of addresses that are in use in the given range.
|
||||
/*! \brief Compare two range_t by their first_ip.
|
||||
* \param r1,r2 Pointers to data to compare.
|
||||
* \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.
|
||||
* \param r A range structure.
|
||||
* \return Maximum number of addresses that can be in the given range.
|
||||
/*! \brief Compare two range_t by their capacity.
|
||||
* \param r1,r2 Pointers to data to compare.
|
||||
* \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.
|
||||
|
|
@ -126,15 +171,6 @@ unsigned long int ret_percent(struct range_t r)
|
|||
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
|
||||
* \param r A range structure.
|
||||
* \return Number of touched or in use addresses in the given range.
|
||||
|
|
@ -167,25 +203,25 @@ void field_selector(char c)
|
|||
case 'n':
|
||||
break;
|
||||
case 'i':
|
||||
returner = ret_ip;
|
||||
comparer = comp_ip;
|
||||
break;
|
||||
case 'm':
|
||||
returner = ret_max;
|
||||
comparer = comp_max;
|
||||
break;
|
||||
case 'c':
|
||||
returner = ret_cur;
|
||||
comparer = comp_cur;
|
||||
break;
|
||||
case 'p':
|
||||
returner = ret_percent;
|
||||
comparer = comp_percent;
|
||||
break;
|
||||
case 't':
|
||||
returner = ret_touched;
|
||||
comparer = comp_touched;
|
||||
break;
|
||||
case 'T':
|
||||
returner = ret_tc;
|
||||
comparer = comp_tc;
|
||||
break;
|
||||
case 'e':
|
||||
returner = ret_tcperc;
|
||||
comparer = comp_tcperc;
|
||||
break;
|
||||
default:
|
||||
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)
|
||||
{
|
||||
int i, len, ret;
|
||||
unsigned long int lint, rint;
|
||||
int cmp;
|
||||
|
||||
len = strlen(config.sort);
|
||||
for (i = 0; i < len; i++) {
|
||||
|
|
@ -218,21 +254,20 @@ static int merge(struct range_t *restrict left, struct range_t *restrict right)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Select which function is pointed by returner */
|
||||
/* Select which function is pointed by comparer */
|
||||
field_selector(config.sort[i]);
|
||||
lint = returner(*left);
|
||||
rint = returner(*right);
|
||||
cmp = comparer(left, right);
|
||||
/* If fields are equal use next sort method */
|
||||
if (lint == rint) {
|
||||
if (cmp == 0) {
|
||||
continue;
|
||||
}
|
||||
if (lint < rint) {
|
||||
if (cmp < 0) {
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* If all returners where equal */
|
||||
/* If all comparers where equal */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue