diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-08-09 12:21:37 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-08-09 12:21:37 -0400 |
commit | e106812a778f53760c819ab20a214ac3222b3b15 (patch) | |
tree | 38d5ff9ade183c3cfa93a2dd75ecf9a935a6d12c /src/common | |
parent | 91b52a259a271df7ceeea6d8bf7adbd4d7e15a6c (diff) | |
download | tor-e106812a778f53760c819ab20a214ac3222b3b15.tar tor-e106812a778f53760c819ab20a214ac3222b3b15.tar.gz |
Change smartlist_choose_node_by_bandwidth to avoid double
This should make our preferred solution to #6538 easier to
implement, avoid a bunch of potential nastiness with excessive
int-vs-double math, and generally make the code there a little less
scary.
"But wait!" you say. "Is it really safe to do this? Won't the
results come out differently?"
Yes, but not much. We now round every weighted bandwidth to the
nearest byte before computing on it. This will make every node that
had a fractional part of its weighted bandwidth before either
slighty more likely or slightly less likely. Further, the rand_bw
value was only ever set with integer precision, so it can't
accurately sample routers with tiny fractional bandwidth values
anyway. Finally, doing repeated double-vs-uint64 comparisons is
just plain sad; it will involve an implicit cast to double, which is
never a fun thing.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/util.c | 15 | ||||
-rw-r--r-- | src/common/util.h | 1 |
2 files changed, 16 insertions, 0 deletions
diff --git a/src/common/util.c b/src/common/util.c index a0dff2e35..60222f408 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -378,6 +378,21 @@ tor_lround(double d) #endif } +/** Return the 64-bit integer closest to d. We define this wrapper here so + * that not all users of math.h need to use the right incancations to get the + * c99 functions. */ +int64_t +tor_llround(double d) +{ +#if defined(HAVE_LLROUND) + return (int64_t)llround(d); +#elif defined(HAVE_RINT) + return (int64_t)rint(d); +#else + return (int64_t)(d > 0 ? d + 0.5 : ceil(d - 0.5)); +#endif +} + /** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */ int tor_log2(uint64_t u64) diff --git a/src/common/util.h b/src/common/util.h index a2ab0ccac..f700e9f4c 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -161,6 +161,7 @@ void tor_log_mallinfo(int severity); /* Math functions */ double tor_mathlog(double d) ATTR_CONST; long tor_lround(double d) ATTR_CONST; +int64_t tor_llround(double d) ATTR_CONST; int tor_log2(uint64_t u64) ATTR_CONST; uint64_t round_to_power_of_2(uint64_t u64); unsigned round_to_next_multiple_of(unsigned number, unsigned divisor); |