mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Wrote a quicksort macro and modified sort_list to use it
This commit is contained in:
parent
dcabd6421c
commit
4247eec969
@ -25,6 +25,7 @@
|
||||
|
||||
#include "DHT.h"
|
||||
#include "ping.h"
|
||||
#include "misc_tools.h"
|
||||
|
||||
/* The number of seconds for a non responsive node to become bad. */
|
||||
#define BAD_NODE_TIMEOUT 70
|
||||
@ -86,6 +87,17 @@ static int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Turns the result of id_closest into something quick_sort can use.
|
||||
* Assumes p1->c1 == p2->c1.
|
||||
*/
|
||||
static int client_id_cmp(ClientPair p1, ClientPair p2)
|
||||
{
|
||||
int c = id_closest(p1.c1.client_id, p1.c2.client_id, p2.c2.client_id);
|
||||
if (c == 2)
|
||||
return -1;
|
||||
return c;
|
||||
}
|
||||
|
||||
static int ipport_equal(IP_Port a, IP_Port b)
|
||||
{
|
||||
return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port);
|
||||
@ -277,33 +289,28 @@ static int replace_bad( Client_data *list,
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* Sort the list. It will be sorted from furthest to closest.
|
||||
TODO: this is innefficient and needs to be optimized. */
|
||||
|
||||
/*Sort the list. It will be sorted from furthest to closest.
|
||||
* Turns list into data that quick sort can use and reverts it back.
|
||||
*/
|
||||
static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
Client_data cd;
|
||||
ClientPair pairs[length];
|
||||
uint32_t i;
|
||||
|
||||
uint32_t i, count;
|
||||
|
||||
while (1) {
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < (length - 1); ++i) {
|
||||
if (id_closest(comp_client_id, list[i].client_id, list[i + 1].client_id) == 1) {
|
||||
Client_data temp = list[i + 1];
|
||||
list[i + 1] = list[i];
|
||||
list[i] = temp;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
/* Create the quicksort function. See misc_tools.h for the definition. */
|
||||
make_quick_sort(ClientPair);
|
||||
memcpy(cd.client_id, comp_client_id, CLIENT_ID_SIZE);
|
||||
for (i = 0; i < length; ++i) {
|
||||
pairs[i].c1 = cd;
|
||||
pairs[i].c2 = list[i];
|
||||
}
|
||||
ClientPair_quick_sort(pairs, length, client_id_cmp);
|
||||
for (i = 0; i < length; ++i)
|
||||
list[i] = pairs[i].c2;
|
||||
}
|
||||
|
||||
|
||||
/* Replace the first good node that is further to the comp_client_id than that of the client_id in the list */
|
||||
static int replace_good( Client_data *list,
|
||||
uint32_t length,
|
||||
|
@ -55,6 +55,12 @@ typedef struct {
|
||||
uint64_t ret_timestamp;
|
||||
} Client_data;
|
||||
|
||||
/* Used in the comparison function for sorting lists of Client_data. */
|
||||
typedef struct {
|
||||
Client_data c1;
|
||||
Client_data c2;
|
||||
} ClientPair;
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
|
@ -186,4 +186,42 @@ static inline void tox_array_pop(tox_array *arr, uint32_t num)
|
||||
type *tmp_name = &tox_array_get(arr, 0, type); uint32_t tmp_name ## _i = 0; \
|
||||
for (; tmp_name ## _i < (arr)->len; tmp_name = &tox_array_get(arr, ++ tmp_name ## _i, type))
|
||||
|
||||
/****************************Algorithms***************************
|
||||
* Macro/generic definitions for useful algorithms
|
||||
*****************************************************************/
|
||||
|
||||
/* Creates a new quick_sort implementation for arrays of the specified type.
|
||||
* For a type T (eg: int, char), creates a function named T_quick_sort.
|
||||
*
|
||||
* Quick Sort: Complexity O(nlogn)
|
||||
* arr - the array to sort
|
||||
* n - the sort index (should be called with n = length(arr))
|
||||
* cmpfn - a function that compares two values of type type.
|
||||
* Must return -1, 0, 1 for a < b, a == b, and a > b respectively.
|
||||
*/
|
||||
#define make_quick_sort(type) \
|
||||
void type##_quick_sort(type *arr, int n, int (*cmpfn)(type, type)) \
|
||||
{ \
|
||||
if ((n) < 2) \
|
||||
return; \
|
||||
type _p_ = (arr)[(n) / 2]; \
|
||||
type *_l_ = (arr); \
|
||||
type *_r_ = (arr) + n - 1; \
|
||||
while (_l_ <= _r_) { \
|
||||
if (cmpfn(*_l_, _p_) == -1) { \
|
||||
++_l_; \
|
||||
continue; \
|
||||
} \
|
||||
if (cmpfn(*_r_, _p_) == 1) { \
|
||||
--_r_; \
|
||||
continue; \
|
||||
} \
|
||||
type _t_ = *_l_; \
|
||||
*_l_++ = *_r_; \
|
||||
*_r_-- = _t_; \
|
||||
} \
|
||||
type##_quick_sort((arr), _r_ - (arr) + 1, cmpfn); \
|
||||
type##_quick_sort(_l_, (arr) + n - _l_, cmpfn); \
|
||||
}
|
||||
|
||||
#endif // MISC_TOOLS_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user