* i2psnark:

- Split buckets correctly
   - More exploration fixes
This commit is contained in:
zzz
2012-11-02 15:58:26 +00:00
parent f29a45a2c2
commit eee38a626d
4 changed files with 21 additions and 15 deletions

View File

@@ -209,10 +209,10 @@ public class KBucketSet<T extends SimpleDataStructure> {
int s1, e1, s2, e2; int s1, e1, s2, e2;
s1 = b0.getRangeBegin(); s1 = b0.getRangeBegin();
e2 = b0.getRangeEnd(); e2 = b0.getRangeEnd();
if (B_FACTOR > 1 && if (B_VALUE == 1 ||
(s1 & (B_FACTOR - 1)) == 0 && ((s1 & (B_FACTOR - 1)) == 0 &&
((e2 + 1) & (B_FACTOR - 1)) == 0 && ((e2 + 1) & (B_FACTOR - 1)) == 0 &&
e2 > s1 + B_FACTOR) { e2 > s1 + B_FACTOR)) {
// The bucket is a "whole" kbucket with a range > B_FACTOR, // The bucket is a "whole" kbucket with a range > B_FACTOR,
// so it should be split into two "whole" kbuckets each with // so it should be split into two "whole" kbuckets each with
// a range >= B_FACTOR. // a range >= B_FACTOR.
@@ -526,17 +526,14 @@ public class KBucketSet<T extends SimpleDataStructure> {
public List<T> getExploreKeys(long age) { public List<T> getExploreKeys(long age) {
List<T> rv = new ArrayList(_buckets.size()); List<T> rv = new ArrayList(_buckets.size());
long old = _context.clock().now() - age; long old = _context.clock().now() - age;
int prevSize = -1;
getReadLock(); getReadLock();
try { try {
for (KBucket b : _buckets) { for (KBucket b : _buckets) {
int curSize = b.getKeyCount(); int curSize = b.getKeyCount();
// The first few buckets are all empty, we only need one // Always explore the closest bucket
// explore key for all of them. if ((b.getRangeBegin() == 0) ||
if ((prevSize != 0 || curSize != 0) &&
(b.getLastChanged() < old || curSize < BUCKET_SIZE * 3 / 4)) (b.getLastChanged() < old || curSize < BUCKET_SIZE * 3 / 4))
rv.add(generateRandomKey(b)); rv.add(generateRandomKey(b));
prevSize = curSize;
} }
} finally { releaseReadLock(); } } finally { releaseReadLock(); }
return rv; return rv;
@@ -765,8 +762,8 @@ public class KBucketSet<T extends SimpleDataStructure> {
public String toString() { public String toString() {
StringBuilder buf = new StringBuilder(1024); StringBuilder buf = new StringBuilder(1024);
buf.append("Bucket set rooted on: ").append(_us.toString()) buf.append("Bucket set rooted on: ").append(_us.toString())
.append(" K= ").append(BUCKET_SIZE) .append(" K=").append(BUCKET_SIZE)
.append(" B= ").append(B_VALUE) .append(" B=").append(B_VALUE)
.append(" with ").append(size()) .append(" with ").append(size())
.append(" keys in ").append(_buckets.size()).append(" buckets:\n"); .append(" keys in ").append(_buckets.size()).append(" buckets:\n");
getReadLock(); getReadLock();

View File

@@ -89,8 +89,13 @@ class DHTNodes {
* @return the old value if present, else null * @return the old value if present, else null
*/ */
public NodeInfo putIfAbsent(NodeInfo nInfo) { public NodeInfo putIfAbsent(NodeInfo nInfo) {
_kad.add(nInfo.getNID()); NodeInfo rv = _nodeMap.putIfAbsent(nInfo.getNID(), nInfo);
return _nodeMap.putIfAbsent(nInfo.getNID(), nInfo); // ensure same object in both places
if (rv != null)
_kad.add(rv.getNID());
else
_kad.add(nInfo.getNID());
return rv;
} }
public NodeInfo remove(NID nid) { public NodeInfo remove(NID nid) {

View File

@@ -1108,8 +1108,12 @@ public class KRPC implements I2PSessionMuxedListener, DHT {
if (nInfo.equals(_myNodeInfo)) if (nInfo.equals(_myNodeInfo))
return _myNodeInfo; return _myNodeInfo;
NodeInfo rv = _knownNodes.putIfAbsent(nInfo); NodeInfo rv = _knownNodes.putIfAbsent(nInfo);
if (rv == null) if (rv == null) {
rv = nInfo; rv = nInfo;
// if we didn't know about it before, set the timestamp
// so it isn't immediately removed by the DHTNodes cleaner
rv.getNID().setLastSeen();
}
return rv; return rv;
} }

View File

@@ -1638,7 +1638,7 @@ public class I2PSnarkServlet extends DefaultServlet {
out.write("\" ></td></tr>\n" + out.write("\" ></td></tr>\n" +
"<tr><td>"); "<tr><td>");
out.write(_("Enable DHT") + " (**BETA**)"); out.write(_("Enable DHT"));
out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"useDHT\" value=\"true\" " out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"useDHT\" value=\"true\" "
+ (useDHT ? "checked " : "") + (useDHT ? "checked " : "")
+ "title=\""); + "title=\"");