From d868ca47403215a33005d3a99da7557afed9a925 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Wed, 8 Apr 2015 14:40:53 +0000 Subject: [PATCH] Tunnels: Add new Bloom filter size, increase bandwidth limit (ticket #1505) --- .../transport/FIFOBandwidthRefiller.java | 8 +++++-- .../router/tunnel/BloomFilterIVValidator.java | 9 +++++++ .../i2p/router/util/DecayingBloomFilter.java | 24 ++++++++++++++----- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/FIFOBandwidthRefiller.java b/router/java/src/net/i2p/router/transport/FIFOBandwidthRefiller.java index 3dc610b781..190c3b6416 100644 --- a/router/java/src/net/i2p/router/transport/FIFOBandwidthRefiller.java +++ b/router/java/src/net/i2p/router/transport/FIFOBandwidthRefiller.java @@ -70,8 +70,12 @@ public class FIFOBandwidthRefiller implements Runnable { public static final int MIN_INBOUND_BANDWIDTH_PEAK = 3; /** For now, until there is some tuning and safe throttling, we set the floor at a 3KBps during burst */ public static final int MIN_OUTBOUND_BANDWIDTH_PEAK = 3; - /** Max for reasonable bloom filter false positive rate. See util/DecayingBloomFilter and tunnel/BloomFilterIVValidator */ - public static final int MAX_OUTBOUND_BANDWIDTH = 4096; + /** + * Max for reasonable Bloom filter false positive rate. + * Do not increase without adding a new Bloom filter size! + * See util/DecayingBloomFilter and tunnel/BloomFilterIVValidator. + */ + public static final int MAX_OUTBOUND_BANDWIDTH = 8192; /** * how often we replenish the queues. diff --git a/router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java b/router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java index a987152811..8958c64e13 100644 --- a/router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java +++ b/router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java @@ -29,12 +29,17 @@ class BloomFilterIVValidator implements IVValidator { private static final int MIN_SHARE_KBPS_TO_USE_BLOOM = 64; private static final int MIN_SHARE_KBPS_FOR_BIG_BLOOM = 512; private static final int MIN_SHARE_KBPS_FOR_HUGE_BLOOM = 1536; + private static final int MIN_SHARE_KBPS_FOR_HUGE2_BLOOM = 4096; private static final long MIN_MEM_TO_USE_BLOOM = 64*1024*1024l; private static final long MIN_MEM_FOR_BIG_BLOOM = 128*1024*1024l; private static final long MIN_MEM_FOR_HUGE_BLOOM = 256*1024*1024l; + private static final long MIN_MEM_FOR_HUGE2_BLOOM = 384*1024*1024l; /** for testing */ private static final String PROP_FORCE = "router.forceDecayingBloomFilter"; + /** + * @param Kbps share bandwidth + */ public BloomFilterIVValidator(RouterContext ctx, int KBps) { _context = ctx; // Select the filter based on share bandwidth and memory. @@ -48,7 +53,11 @@ class BloomFilterIVValidator implements IVValidator { if (KBps >= MIN_SHARE_KBPS_TO_USE_BLOOM) warn(maxMemory, KBps, MIN_MEM_TO_USE_BLOOM, MIN_SHARE_KBPS_TO_USE_BLOOM); _filter = new DecayingHashSet(ctx, HALFLIFE_MS, 16, "TunnelIVV"); // appx. 4MB max + } else if (KBps >= MIN_SHARE_KBPS_FOR_HUGE2_BLOOM && maxMemory >= MIN_MEM_FOR_HUGE2_BLOOM) { + _filter = new DecayingBloomFilter(ctx, HALFLIFE_MS, 16, "TunnelIVV", 26); // 16MB fixed } else if (KBps >= MIN_SHARE_KBPS_FOR_HUGE_BLOOM && maxMemory >= MIN_MEM_FOR_HUGE_BLOOM) { + if (KBps >= MIN_SHARE_KBPS_FOR_HUGE2_BLOOM) + warn(maxMemory, KBps, MIN_MEM_FOR_HUGE2_BLOOM, MIN_SHARE_KBPS_FOR_HUGE2_BLOOM); _filter = new DecayingBloomFilter(ctx, HALFLIFE_MS, 16, "TunnelIVV", 25); // 8MB fixed } else if (KBps >= MIN_SHARE_KBPS_FOR_BIG_BLOOM && maxMemory >= MIN_MEM_FOR_BIG_BLOOM) { if (KBps >= MIN_SHARE_KBPS_FOR_HUGE_BLOOM) diff --git a/router/java/src/net/i2p/router/util/DecayingBloomFilter.java b/router/java/src/net/i2p/router/util/DecayingBloomFilter.java index 9aa9c6715f..a5910e36ef 100644 --- a/router/java/src/net/i2p/router/util/DecayingBloomFilter.java +++ b/router/java/src/net/i2p/router/util/DecayingBloomFilter.java @@ -372,6 +372,9 @@ public class DecayingBloomFilter { * * Following stats for m=25, k=10: * 1792 2.4E-6; 4096 0.14%; 5120 0.6%; 6144 1.7%; 8192 6.8%; 10240 15% + * + * Following stats for m=26, k=10: + * 4096 7.3E-6; 5120 4.5E-5; 6144 1.8E-4; 8192 0.14%; 10240 0.6%, 12288 1.7% *</pre> */ /***** @@ -400,16 +403,23 @@ public class DecayingBloomFilter { } private static void testByLong(int kbps, int m, int numRuns) { + System.out.println("Starting 8 byte test"); int messages = 60 * 10 * kbps; - Random r = new Random(); + java.util.Random r = new java.util.Random(); DecayingBloomFilter filter = new DecayingBloomFilter(I2PAppContext.getGlobalContext(), 600*1000, 8, "test", m); int falsePositives = 0; long totalTime = 0; double fpr = 0d; for (int j = 0; j < numRuns; j++) { + // screen out birthday paradoxes (waste of time and space?) + java.util.Set<Long> longs = new java.util.HashSet<Long>(messages); long start = System.currentTimeMillis(); for (int i = 0; i < messages; i++) { - if (filter.add(r.nextLong())) { + long rand; + do { + rand = r.nextLong(); + } while (!longs.add(Long.valueOf(rand))); + if (filter.add(rand)) { falsePositives++; //System.out.println("False positive " + falsePositives + " (testByLong j=" + j + " i=" + i + ")"); } @@ -422,13 +432,14 @@ public class DecayingBloomFilter { System.out.println("False postive rate should be " + fpr); System.out.println("After " + numRuns + " runs pushing " + messages + " entries in " + DataHelper.formatDuration(totalTime/numRuns) + " per run, there were " - + falsePositives + " false positives"); - + + falsePositives + " false positives (" + + (((double) falsePositives) / messages) + ')'); } private static void testByBytes(int kbps, int m, int numRuns) { + System.out.println("Starting 16 byte test"); byte iv[][] = new byte[60*10*kbps][16]; - Random r = new Random(); + java.util.Random r = new java.util.Random(); for (int i = 0; i < iv.length; i++) r.nextBytes(iv[i]); @@ -452,7 +463,8 @@ public class DecayingBloomFilter { System.out.println("False postive rate should be " + fpr); System.out.println("After " + numRuns + " runs pushing " + iv.length + " entries in " + DataHelper.formatDuration(totalTime/numRuns) + " per run, there were " - + falsePositives + " false positives"); + + falsePositives + " false positives (" + + (((double) falsePositives) / iv.length) + ')'); //System.out.println("inserted: " + bloom.size() + " with " + bloom.capacity() // + " (" + bloom.falsePositives()*100.0d + "% false positive)"); } -- GitLab