diff options
Diffstat (limited to 'toxcore')
-rw-r--r-- | toxcore/DHT.c | 49 | ||||
-rw-r--r-- | toxcore/DHT.h | 6 | ||||
-rw-r--r-- | toxcore/misc_tools.h | 38 |
3 files changed, 72 insertions, 21 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 529456a2..307b1e33 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include "DHT.h" | 26 | #include "DHT.h" |
27 | #include "ping.h" | 27 | #include "ping.h" |
28 | #include "misc_tools.h" | ||
28 | 29 | ||
29 | /* The number of seconds for a non responsive node to become bad. */ | 30 | /* The number of seconds for a non responsive node to become bad. */ |
30 | #define BAD_NODE_TIMEOUT 70 | 31 | #define BAD_NODE_TIMEOUT 70 |
@@ -86,6 +87,17 @@ static int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2) | |||
86 | return 0; | 87 | return 0; |
87 | } | 88 | } |
88 | 89 | ||
90 | /* Turns the result of id_closest into something quick_sort can use. | ||
91 | * Assumes p1->c1 == p2->c1. | ||
92 | */ | ||
93 | static int client_id_cmp(ClientPair p1, ClientPair p2) | ||
94 | { | ||
95 | int c = id_closest(p1.c1.client_id, p1.c2.client_id, p2.c2.client_id); | ||
96 | if (c == 2) | ||
97 | return -1; | ||
98 | return c; | ||
99 | } | ||
100 | |||
89 | static int ipport_equal(IP_Port a, IP_Port b) | 101 | static int ipport_equal(IP_Port a, IP_Port b) |
90 | { | 102 | { |
91 | return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port); | 103 | return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port); |
@@ -277,33 +289,28 @@ static int replace_bad( Client_data *list, | |||
277 | 289 | ||
278 | return 1; | 290 | return 1; |
279 | } | 291 | } |
280 | /* Sort the list. It will be sorted from furthest to closest. | 292 | |
281 | TODO: this is innefficient and needs to be optimized. */ | 293 | /*Sort the list. It will be sorted from furthest to closest. |
294 | * Turns list into data that quick sort can use and reverts it back. | ||
295 | */ | ||
282 | static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id) | 296 | static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id) |
283 | { | 297 | { |
284 | if (length == 0) | 298 | Client_data cd; |
285 | return; | 299 | ClientPair pairs[length]; |
286 | 300 | uint32_t i; | |
287 | uint32_t i, count; | ||
288 | |||
289 | while (1) { | ||
290 | count = 0; | ||
291 | |||
292 | for (i = 0; i < (length - 1); ++i) { | ||
293 | if (id_closest(comp_client_id, list[i].client_id, list[i + 1].client_id) == 1) { | ||
294 | Client_data temp = list[i + 1]; | ||
295 | list[i + 1] = list[i]; | ||
296 | list[i] = temp; | ||
297 | ++count; | ||
298 | } | ||
299 | } | ||
300 | 301 | ||
301 | if (count == 0) | 302 | /* Create the quicksort function. See misc_tools.h for the definition. */ |
302 | return; | 303 | make_quick_sort(ClientPair); |
304 | memcpy(cd.client_id, comp_client_id, CLIENT_ID_SIZE); | ||
305 | for (i = 0; i < length; ++i) { | ||
306 | pairs[i].c1 = cd; | ||
307 | pairs[i].c2 = list[i]; | ||
303 | } | 308 | } |
309 | ClientPair_quick_sort(pairs, length, client_id_cmp); | ||
310 | for (i = 0; i < length; ++i) | ||
311 | list[i] = pairs[i].c2; | ||
304 | } | 312 | } |
305 | 313 | ||
306 | |||
307 | /* Replace the first good node that is further to the comp_client_id than that of the client_id in the list */ | 314 | /* Replace the first good node that is further to the comp_client_id than that of the client_id in the list */ |
308 | static int replace_good( Client_data *list, | 315 | static int replace_good( Client_data *list, |
309 | uint32_t length, | 316 | uint32_t length, |
diff --git a/toxcore/DHT.h b/toxcore/DHT.h index b53801b5..d0afda35 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h | |||
@@ -55,6 +55,12 @@ typedef struct { | |||
55 | uint64_t ret_timestamp; | 55 | uint64_t ret_timestamp; |
56 | } Client_data; | 56 | } Client_data; |
57 | 57 | ||
58 | /* Used in the comparison function for sorting lists of Client_data. */ | ||
59 | typedef struct { | ||
60 | Client_data c1; | ||
61 | Client_data c2; | ||
62 | } ClientPair; | ||
63 | |||
58 | /*----------------------------------------------------------------------------------*/ | 64 | /*----------------------------------------------------------------------------------*/ |
59 | 65 | ||
60 | typedef struct { | 66 | typedef struct { |
diff --git a/toxcore/misc_tools.h b/toxcore/misc_tools.h index 5f4cfea4..4d62a856 100644 --- a/toxcore/misc_tools.h +++ b/toxcore/misc_tools.h | |||
@@ -186,4 +186,42 @@ static inline void tox_array_pop(tox_array *arr, uint32_t num) | |||
186 | type *tmp_name = &tox_array_get(arr, 0, type); uint32_t tmp_name ## _i = 0; \ | 186 | type *tmp_name = &tox_array_get(arr, 0, type); uint32_t tmp_name ## _i = 0; \ |
187 | for (; tmp_name ## _i < (arr)->len; tmp_name = &tox_array_get(arr, ++ tmp_name ## _i, type)) | 187 | for (; tmp_name ## _i < (arr)->len; tmp_name = &tox_array_get(arr, ++ tmp_name ## _i, type)) |
188 | 188 | ||
189 | /****************************Algorithms*************************** | ||
190 | * Macro/generic definitions for useful algorithms | ||
191 | *****************************************************************/ | ||
192 | |||
193 | /* Creates a new quick_sort implementation for arrays of the specified type. | ||
194 | * For a type T (eg: int, char), creates a function named T_quick_sort. | ||
195 | * | ||
196 | * Quick Sort: Complexity O(nlogn) | ||
197 | * arr - the array to sort | ||
198 | * n - the sort index (should be called with n = length(arr)) | ||
199 | * cmpfn - a function that compares two values of type type. | ||
200 | * Must return -1, 0, 1 for a < b, a == b, and a > b respectively. | ||
201 | */ | ||
202 | #define make_quick_sort(type) \ | ||
203 | void type##_quick_sort(type *arr, int n, int (*cmpfn)(type, type)) \ | ||
204 | { \ | ||
205 | if ((n) < 2) \ | ||
206 | return; \ | ||
207 | type _p_ = (arr)[(n) / 2]; \ | ||
208 | type *_l_ = (arr); \ | ||
209 | type *_r_ = (arr) + n - 1; \ | ||
210 | while (_l_ <= _r_) { \ | ||
211 | if (cmpfn(*_l_, _p_) == -1) { \ | ||
212 | ++_l_; \ | ||
213 | continue; \ | ||
214 | } \ | ||
215 | if (cmpfn(*_r_, _p_) == 1) { \ | ||
216 | --_r_; \ | ||
217 | continue; \ | ||
218 | } \ | ||
219 | type _t_ = *_l_; \ | ||
220 | *_l_++ = *_r_; \ | ||
221 | *_r_-- = _t_; \ | ||
222 | } \ | ||
223 | type##_quick_sort((arr), _r_ - (arr) + 1, cmpfn); \ | ||
224 | type##_quick_sort(_l_, (arr) + n - _l_, cmpfn); \ | ||
225 | } | ||
226 | |||
189 | #endif // MISC_TOOLS_H | 227 | #endif // MISC_TOOLS_H |