diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-07-12 22:54:39 -0400 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-07-12 22:54:39 -0400 |
commit | c6dd5b239ff30a192c5bc6e784fd5d4b3085646d (patch) | |
tree | 60df6ff8cdf284f301ec9d72c3ad6d19359a72ba /node | |
parent | aa59c1de10b53df8a33d1df99b74b8a20052b9af (diff) | |
download | infinitytier-c6dd5b239ff30a192c5bc6e784fd5d4b3085646d.tar.gz infinitytier-c6dd5b239ff30a192c5bc6e784fd5d4b3085646d.zip |
Minor improvement to multicast propagation algorithm.
Diffstat (limited to 'node')
-rw-r--r-- | node/BloomFilter.hpp | 9 | ||||
-rw-r--r-- | node/Multicaster.hpp | 43 |
2 files changed, 24 insertions, 28 deletions
diff --git a/node/BloomFilter.hpp b/node/BloomFilter.hpp index 182b98ab..60af61ab 100644 --- a/node/BloomFilter.hpp +++ b/node/BloomFilter.hpp @@ -94,17 +94,12 @@ public: /** * @param n Value to set - * @return True if corresponding bit was already set before this operation */ - inline bool set(unsigned int n) + inline void set(unsigned int n) throw() { n %= B; - unsigned char *const x = _field + (n / 8); - const unsigned char m = (1 << (n % 8)); - bool already = ((*x & m)); - *x |= m; - return already; + _field[n / 8] |= (1 << (n % 8)); } /** diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp index b3c16185..aa3bcb16 100644 --- a/node/Multicaster.hpp +++ b/node/Multicaster.hpp @@ -52,7 +52,7 @@ #include "Identity.hpp" // Maximum sample size to pick during choice of multicast propagation peers -#define ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE 32 +#define ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE (ZT_MULTICAST_PROPAGATION_BREADTH * 8) namespace ZeroTier { @@ -224,6 +224,16 @@ public: P toConsider[ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE]; unsigned int sampleSize = 0; + // Decay a few random bits in bloom filter to probabilistically eliminate + // false positives as we go. The odds of decaying an already-set bit + // increases as the bloom filter saturates, so in the early hops of + // propagation this likely won't have any effect. This allows peers with + // bloom filter collisions to be reconsidered, but at positions on the + // network graph likely to be hops away from the original origin of the + // message. + for(unsigned int i=0;i<ZT_MULTICAST_BLOOM_FILTER_DECAY_RATE;++i) + bf.decay(); + { Mutex::Lock _l(_multicastMemberships_m); @@ -259,13 +269,15 @@ public: // If it's not expired and it's from our random sample, add it to the set of peers // to consider. Exclude immediate upstream and original submitter, since we know for - // a fact they've already seen this. + // a fact they've already seen this. Also exclude things in the bloom filter. if ((channelMemberEntry->first != originalSubmitter)&&(channelMemberEntry->first != upstream)) { - P peer = topology.getPeer(channelMemberEntry->first); - if ((peer)&&(peer->hasActiveDirectPath(now))) { - toConsider[sampleSize++] = peer; - if (sampleSize >= ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE) - break; // abort if we have enough candidates + if (!bf.contains(channelMemberEntry->first.sum())) { + P peer = topology.getPeer(channelMemberEntry->first); + if ((peer)&&(peer->hasActiveDirectPath(now))) { + toConsider[sampleSize++] = peer; + if (sampleSize >= ZT_MULTICAST_PICK_MAX_SAMPLE_SIZE) + break; // abort if we have enough candidates + } } } ++channelMemberEntry; @@ -282,22 +294,11 @@ public: // switching." std::sort(toConsider,toConsider + sampleSize,PeerPropagationPrioritySortOrder<P>()); - // Decay a few random bits in bloom filter to probabilistically eliminate - // false positives as we go. The odds of decaying an already-set bit - // increases as the bloom filter saturates, so in the early hops of - // propagation this likely won't have any effect. This allows peers with - // bloom filter collisions to be reconsidered, but at positions on the - // network graph likely to be hops away from the original origin of the - // message. - for(unsigned int i=0;i<ZT_MULTICAST_BLOOM_FILTER_DECAY_RATE;++i) - bf.decay(); - - // Pick peers not in the bloom filter, setting bloom filter bits accordingly to - // remember and pass on these picks. + // Pick the best N peers unsigned int picked = 0; for(unsigned int i=0;((i<sampleSize)&&(picked < max));++i) { - if (!bf.set(toConsider[i]->address().sum())) - peers[picked++] = toConsider[i]; + peers[picked++] = toConsider[i]; + bf.set(toConsider[i]->address().sum()); } // Add a supernode if there's nowhere else to go. Supernodes know of all multicast |