refactor trimmers to their own files

This commit is contained in:
zzz
2012-08-29 14:05:02 +00:00
parent d05f1ca2c8
commit d2a7af2884
9 changed files with 99 additions and 69 deletions

View File

@ -53,7 +53,7 @@ class KBucketImpl<T extends SimpleDataStructure> implements KBucket<T> {
/** include if no bits higher than this bit (inclusive) are set */
private final int _end;
private final int _max;
private final KBucketSet.KBucketTrimmer _trimmer;
private final KBucketTrimmer _trimmer;
/** when did we last shake things up */
private long _lastChanged;
private final I2PAppContext _context;
@ -62,7 +62,7 @@ class KBucketImpl<T extends SimpleDataStructure> implements KBucket<T> {
* All entries in this bucket will have at least one bit different
* from us in the range [begin, end] inclusive.
*/
public KBucketImpl(I2PAppContext context, int begin, int end, int max, KBucketSet.KBucketTrimmer trimmer) {
public KBucketImpl(I2PAppContext context, int begin, int end, int max, KBucketTrimmer trimmer) {
if (begin > end)
throw new IllegalArgumentException(begin + " > " + end);
_context = context;

View File

@ -768,70 +768,6 @@ public class KBucketSet<T extends SimpleDataStructure> {
}
}
/**
* Called when a kbucket can no longer be split and is too big
*/
public interface KBucketTrimmer<K extends SimpleDataStructure> {
/**
* Called from add() just before adding the entry.
* You may call getEntries() and/or remove() from here.
* Do NOT call add().
* To always discard a newer entry, always return false.
*
* @param kbucket the kbucket that is now too big
* @return true to actually add the entry.
*/
public boolean trim(KBucket<K> kbucket, K toAdd);
}
/**
* Removes a random element. Not resistant to flooding.
*/
public static class RandomTrimmer<T extends SimpleDataStructure> implements KBucketTrimmer<T> {
protected final I2PAppContext _ctx;
private final int _max;
public RandomTrimmer(I2PAppContext ctx, int max) {
_ctx = ctx;
_max = max;
}
public boolean trim(KBucket<T> kbucket, T toAdd) {
List<T> e = new ArrayList(kbucket.getEntries());
int sz = e.size();
// concurrency
if (sz < _max)
return true;
T toRemove = e.get(_ctx.random().nextInt(sz));
return kbucket.remove(toRemove);
}
}
/**
* Removes a random element, but only if the bucket hasn't changed in 5 minutes.
*/
public static class RandomIfOldTrimmer<T extends SimpleDataStructure> extends RandomTrimmer<T> {
public RandomIfOldTrimmer(I2PAppContext ctx, int max) {
super(ctx, max);
}
public boolean trim(KBucket<T> kbucket, T toAdd) {
if (kbucket.getLastChanged() > _ctx.clock().now() - 5*60*1000)
return false;
return super.trim(kbucket, toAdd);
}
}
/**
* Removes nothing and always rejects the add. Flood resistant..
*/
public static class RejectTrimmer<T extends SimpleDataStructure> implements KBucketTrimmer<T> {
public boolean trim(KBucket<T> kbucket, T toAdd) {
return false;
}
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder(1024);

View File

@ -0,0 +1,20 @@
package net.i2p.kademlia;
import net.i2p.data.SimpleDataStructure;
/**
* Called when a kbucket can no longer be split and is too big
* @since 0.9.2
*/
public interface KBucketTrimmer<K extends SimpleDataStructure> {
/**
* Called from add() just before adding the entry.
* You may call getEntries() and/or remove() from here.
* Do NOT call add().
* To always discard a newer entry, always return false.
*
* @param kbucket the kbucket that is now too big
* @return true to actually add the entry.
*/
public boolean trim(KBucket<K> kbucket, K toAdd);
}

View File

@ -0,0 +1,21 @@
package net.i2p.kademlia;
import net.i2p.I2PAppContext;
import net.i2p.data.SimpleDataStructure;
/**
* Removes a random element, but only if the bucket hasn't changed in 5 minutes.
* @since 0.9.2
*/
public class RandomIfOldTrimmer<T extends SimpleDataStructure> extends RandomTrimmer<T> {
public RandomIfOldTrimmer(I2PAppContext ctx, int max) {
super(ctx, max);
}
public boolean trim(KBucket<T> kbucket, T toAdd) {
if (kbucket.getLastChanged() > _ctx.clock().now() - 5*60*1000)
return false;
return super.trim(kbucket, toAdd);
}
}

View File

@ -0,0 +1,31 @@
package net.i2p.kademlia;
import java.util.ArrayList;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.data.SimpleDataStructure;
/**
* Removes a random element. Not resistant to flooding.
* @since 0.9.2
*/
public class RandomTrimmer<T extends SimpleDataStructure> implements KBucketTrimmer<T> {
protected final I2PAppContext _ctx;
private final int _max;
public RandomTrimmer(I2PAppContext ctx, int max) {
_ctx = ctx;
_max = max;
}
public boolean trim(KBucket<T> kbucket, T toAdd) {
List<T> e = new ArrayList(kbucket.getEntries());
int sz = e.size();
// concurrency
if (sz < _max)
return true;
T toRemove = e.get(_ctx.random().nextInt(sz));
return kbucket.remove(toRemove);
}
}

View File

@ -0,0 +1,13 @@
package net.i2p.kademlia;
import net.i2p.data.SimpleDataStructure;
/**
* Removes nothing and always rejects the add. Flood resistant..
* @since 0.9.2
*/
public class RejectTrimmer<T extends SimpleDataStructure> implements KBucketTrimmer<T> {
public boolean trim(KBucket<T> kbucket, T toAdd) {
return false;
}
}

View File

@ -4,12 +4,12 @@ import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.kademlia.KBucket;
import net.i2p.kademlia.KBucketSet;
import net.i2p.kademlia.KBucketTrimmer;
/**
* Removes an element older than 15 minutes, but only if the bucket hasn't changed in 5 minutes.
*/
class KBTrimmer implements KBucketSet.KBucketTrimmer<NID> {
class KBTrimmer implements KBucketTrimmer<NID> {
private final I2PAppContext _ctx;
private final int _max;

View File

@ -1,3 +1,12 @@
2012-08-297 zzz
* ClientManager: Cleanups
* i2psnark:
- Fix NPE on destroy() if init() failed
- Add new flood-resistant KBucket trim policy
- Limit received MsgID size
* NTCP: Reduce lock contention (ticket #697)
* RandomIterator: Workaround for Android bug (ticket #703)
2012-08-27 zzz
* i2psnark:
- Notify threads awaiting DHT replies at shutdown

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 20;
public final static long BUILD = 21;
/** for example "-test" */
public final static String EXTRA = "";