Author: toad
Date: 2008-02-08 18:38:16 +0000 (Fri, 08 Feb 2008)
New Revision: 17707
Modified:
trunk/freenet/src/freenet/node/FailureTable.java
trunk/freenet/src/freenet/node/FailureTableEntry.java
Log:
Remove the entry as well if it's empty.
Modified: trunk/freenet/src/freenet/node/FailureTable.java
===================================================================
--- trunk/freenet/src/freenet/node/FailureTable.java 2008-02-08 18:33:37 UTC
(rev 17706)
+++ trunk/freenet/src/freenet/node/FailureTable.java 2008-02-08 18:38:16 UTC
(rev 17707)
@@ -24,6 +24,9 @@
// Otherwise it will be much too easy to trace a request if an attacker busts
the node afterwards.
// We can use an HMAC or something to authenticate offers.
+// LOCKING: Always take the FailureTable lock first if you need both. Take the
FailureTableEntry
+// lock only on cheap internal operations.
+
/**
* Tracks recently DNFed keys, where they were routed to, what the location
was at the time, who requested them.
* Implements Ultra-Lightweight Persistent Requests: Refuse requests for a key
for 10 minutes after it's DNFed
@@ -473,9 +476,13 @@
entriesByKey.toArray(entries);
}
for(int i=0;i<entries.length;i++) {
- entries[i].cleanup();
- // FIXME how to safely remove them if empty?
- // I suppose we'll have to establish a lock
taking order...
+ if(entries[i].cleanup()) {
+ synchronized(FailureTable.this) {
+ if(entries[i].isEmpty()) {
+
entriesByKey.removeKey(entries[i].key);
+ }
+ }
+ }
}
long endTime = System.currentTimeMillis();
if(logMINOR) Logger.minor(this, "Finished FailureTable
cleanup took "+(endTime-startTime)+"ms");
Modified: trunk/freenet/src/freenet/node/FailureTableEntry.java
===================================================================
--- trunk/freenet/src/freenet/node/FailureTableEntry.java 2008-02-08
18:33:37 UTC (rev 17706)
+++ trunk/freenet/src/freenet/node/FailureTableEntry.java 2008-02-08
18:38:16 UTC (rev 17707)
@@ -429,7 +429,8 @@
return -1; // not timed out
}
- public synchronized void cleanup() {
+ public synchronized boolean cleanup() {
+ boolean empty = true;
int x = 0;
long now = System.currentTimeMillis(); // don't pass in as a
pass over the whole FT may take a while. get it in the method.
for(int i=0;i<requestorNodes.length;i++) {
@@ -441,6 +442,7 @@
if(bootID != requestorBootIDs[i]) continue;
if(!pn.isConnected()) continue;
if(now - requestorTimes[i] >
MAX_TIME_BETWEEN_REQUEST_AND_OFFER) continue;
+ empty = false;
requestorNodes[x] = requestorNodes[i];
requestorTimes[x] = requestorTimes[i];
requestorBootIDs[x] = requestorBootIDs[i];
@@ -467,6 +469,7 @@
if(bootID != requestedBootIDs[i]) continue;
if(!pn.isConnected()) continue;
if(now - requestedTimes[i] >
MAX_TIME_BETWEEN_REQUEST_AND_OFFER) continue;
+ empty = false;
requestedNodes[x] = requestedNodes[i];
requestedTimes[x] = requestedTimes[i];
requestedBootIDs[x] = requestedBootIDs[i];
@@ -494,6 +497,11 @@
requestedTimeouts = newRequestedTimeouts;
requestedTimeoutHTLs = newRequestedTimeoutHTLs;
}
+ return empty;
}
+ public boolean isEmpty() {
+ return isEmpty(System.currentTimeMillis());
+ }
+
}
\ No newline at end of file