From 2b4490d8a7083dd835d74bb72d1535125415dba9 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 27 Jan 2020 03:49:49 +0800 Subject: [PATCH 1/3] Use faster hash function qHash(QString) will need to hash/loop through all the data while the new code will only need one memcpy() and a few bit manipulations. --- src/base/bittorrent/infohash.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/base/bittorrent/infohash.cpp b/src/base/bittorrent/infohash.cpp index 122d4e88f..e050efbb8 100644 --- a/src/base/bittorrent/infohash.cpp +++ b/src/base/bittorrent/infohash.cpp @@ -89,5 +89,9 @@ bool BitTorrent::operator!=(const InfoHash &left, const InfoHash &right) uint BitTorrent::qHash(const InfoHash &key, const uint seed) { +#if (LIBTORRENT_VERSION_NUM < 10200) return ::qHash(static_cast(key), seed); +#else + return ::qHash((std::hash {})(key), seed); +#endif } From 1740f968df5b717ea4e22e47b6499219606b7b45 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 27 Jan 2020 03:51:58 +0800 Subject: [PATCH 2/3] Revise qHash function Instead of xor and narrowing the integers ourselves, now we let qHash() from Qt do the job properly. --- src/base/bittorrent/torrenthandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 683e1fd64..442821fdf 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -82,7 +82,7 @@ namespace libtorrent template uint qHash(const strong_typedef &key, const uint seed) { - return static_cast((std::hash> {})(key) ^ seed); + return ::qHash((std::hash> {})(key), seed); } } } From 5905c085c6e92670686bb830c318938af86ec7c1 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 27 Jan 2020 04:04:02 +0800 Subject: [PATCH 3/3] Use systematic approach to generate hash The basic idea is to hash each class member and then mix them with xor operation. However the `seed` must be handled with care, it should only be introduced once when mixing the hashes of each class member, otherwise under some circumstances the `seed` might xor with itself and thus break the intended effect. --- src/base/bittorrent/trackerentry.cpp | 2 +- src/base/net/downloadmanager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base/bittorrent/trackerentry.cpp b/src/base/bittorrent/trackerentry.cpp index ca13b059a..34ad1bfb0 100644 --- a/src/base/bittorrent/trackerentry.cpp +++ b/src/base/bittorrent/trackerentry.cpp @@ -162,5 +162,5 @@ bool BitTorrent::operator==(const TrackerEntry &left, const TrackerEntry &right) uint BitTorrent::qHash(const TrackerEntry &key, const uint seed) { - return (::qHash(key.url(), seed) ^ key.tier()); + return (::qHash(key.url(), seed) ^ ::qHash(key.tier())); } diff --git a/src/base/net/downloadmanager.cpp b/src/base/net/downloadmanager.cpp index ad6725a94..ffa3c28a7 100644 --- a/src/base/net/downloadmanager.cpp +++ b/src/base/net/downloadmanager.cpp @@ -348,7 +348,7 @@ Net::ServiceID Net::ServiceID::fromURL(const QUrl &url) uint Net::qHash(const ServiceID &serviceID, const uint seed) { - return ::qHash(serviceID.hostName, seed) ^ serviceID.port; + return ::qHash(serviceID.hostName, seed) ^ ::qHash(serviceID.port); } bool Net::operator==(const ServiceID &lhs, const ServiceID &rhs)