summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/DHT.c49
-rw-r--r--toxcore/DHT.h6
-rw-r--r--toxcore/misc_tools.h38
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 */
93static 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
89static int ipport_equal(IP_Port a, IP_Port b) 101static 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 */
282static void sort_list(Client_data *list, uint32_t length, uint8_t *comp_client_id) 296static 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 */
308static int replace_good( Client_data *list, 315static 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. */
59typedef struct {
60 Client_data c1;
61 Client_data c2;
62} ClientPair;
63
58/*----------------------------------------------------------------------------------*/ 64/*----------------------------------------------------------------------------------*/
59 65
60typedef struct { 66typedef 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) \
203void 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