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:
Cheer Xiao 2013-01-05 23:08:03 +08:00
parent 4051a953bd
commit 137c1d37c2
2 changed files with 75 additions and 44 deletions

View file

@ -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);

View file

@ -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);
} }