Author: toad
Date: 2005-11-12 22:10:01 +0000 (Sat, 12 Nov 2005)
New Revision: 7539
Modified:
trunk/freenet/src/freenet/client/BlockInserter.java
trunk/freenet/src/freenet/client/FileInserter.java
trunk/freenet/src/freenet/client/InserterException.java
trunk/freenet/src/freenet/client/SplitInserter.java
trunk/freenet/src/freenet/client/StandardOnionFECCodec.java
trunk/freenet/src/freenet/io/comm/LowLevelFilter.java
trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
trunk/freenet/src/freenet/node/FNPPacketMangler.java
trunk/freenet/src/freenet/node/InsertSender.java
trunk/freenet/src/freenet/node/KeyTracker.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/node/Version.java
trunk/freenet/src/freenet/support/DoublyLinkedListImpl.java
trunk/freenet/src/freenet/support/UpdatableSortedLinkedList.java
trunk/freenet/src/freenet/support/UpdatableSortedLinkedListWithForeignIndex.java
Log:
177:
Crazy debugging.
Found the reason why list.size() was negative. We were removing from it after
clear(). It couldn't detect this. It can now.
Modified: trunk/freenet/src/freenet/client/BlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/BlockInserter.java 2005-11-12 21:25:51 UTC
(rev 7538)
+++ trunk/freenet/src/freenet/client/BlockInserter.java 2005-11-12 22:10:01 UTC
(rev 7539)
@@ -108,7 +108,7 @@
}
private void fatalError(Throwable t, int code) {
- fatalError(new InserterException(code, t.toString()), code);
+ fatalError(new InserterException(code, t), code);
}
private void nonfatalError(InserterException e, int code) {
Modified: trunk/freenet/src/freenet/client/FileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/FileInserter.java 2005-11-12 21:25:51 UTC
(rev 7538)
+++ trunk/freenet/src/freenet/client/FileInserter.java 2005-11-12 22:10:01 UTC
(rev 7539)
@@ -146,14 +146,14 @@
private void translateException(LowLevelPutException e) throws
InserterException {
switch(e.code) {
case LowLevelPutException.INTERNAL_ERROR:
- throw new
InserterException(InserterException.INTERNAL_ERROR);
+ throw new
InserterException(InserterException.INTERNAL_ERROR, e);
case LowLevelPutException.REJECTED_OVERLOAD:
throw new
InserterException(InserterException.REJECTED_OVERLOAD);
case LowLevelPutException.ROUTE_NOT_FOUND:
throw new
InserterException(InserterException.ROUTE_NOT_FOUND);
default:
Logger.error(this, "Unknown LowLevelPutException code:
"+e.code+" on "+this);
- throw new
InserterException(InserterException.INTERNAL_ERROR);
+ throw new
InserterException(InserterException.INTERNAL_ERROR, e);
}
}
Modified: trunk/freenet/src/freenet/client/InserterException.java
===================================================================
--- trunk/freenet/src/freenet/client/InserterException.java 2005-11-12
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/client/InserterException.java 2005-11-12
22:10:01 UTC (rev 7539)
@@ -2,6 +2,7 @@
import java.io.IOException;
+import freenet.node.LowLevelPutException;
import freenet.support.Logger;
public class InserterException extends Exception {
@@ -30,7 +31,7 @@
errorCodes = null;
}
- public InserterException(int mode, IOException e) {
+ public InserterException(int mode, Throwable e) {
super(getMessage(mode)+": "+e.getMessage());
Logger.minor(this, "Creating InserterException:
"+getMessage(mode)+": "+e, e);
this.mode = mode;
Modified: trunk/freenet/src/freenet/client/SplitInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/SplitInserter.java 2005-11-12 21:25:51 UTC
(rev 7538)
+++ trunk/freenet/src/freenet/client/SplitInserter.java 2005-11-12 22:10:01 UTC
(rev 7539)
@@ -84,7 +84,7 @@
Logger.error(this, "Caught "+t, t);
tracker.kill();
if(t instanceof InserterException) throw
(InserterException)t;
- throw new
InserterException(InserterException.INTERNAL_ERROR, t.toString());
+ throw new
InserterException(InserterException.INTERNAL_ERROR, t);
}
}
Modified: trunk/freenet/src/freenet/client/StandardOnionFECCodec.java
===================================================================
--- trunk/freenet/src/freenet/client/StandardOnionFECCodec.java 2005-11-12
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/client/StandardOnionFECCodec.java 2005-11-12
22:10:01 UTC (rev 7539)
@@ -266,6 +266,12 @@
private void realEncode(SplitfileBlock[] dataBlockStatus,
SplitfileBlock[] checkBlockStatus, int blockLength,
BucketFactory bf)
throws IOException {
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ long memUsedAtStart = Runtime.getRuntime().totalMemory() -
Runtime.getRuntime().freeMemory();
+ Logger.minor(this, "Memory in use at start: "+memUsedAtStart);
System.err.println("************* Encoding " +
dataBlockStatus.length
+ " -> " + checkBlockStatus.length + "
*************");
Logger.minor(this, "Doing encode: " + dataBlockStatus.length
@@ -334,7 +340,19 @@
// Do the encode
// Not shuffled
long startTime =
System.currentTimeMillis();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ long memUsedBeforeStripe =
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+ Logger.minor(this, "Memory in use
before stripe: "+memUsedBeforeStripe);
code.encode(dataPackets, checkPackets,
toEncode);
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().runFinalization();
+ long memUsedAfterStripe =
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+ Logger.minor(this, "Memory in use after
stripe: "+memUsedAfterStripe);
long endTime =
System.currentTimeMillis();
Logger.minor(this, "Stripe encode took "
+ (endTime - startTime)
+ " ms for k=" + k + ", n="
Modified: trunk/freenet/src/freenet/io/comm/LowLevelFilter.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/LowLevelFilter.java 2005-11-12
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/io/comm/LowLevelFilter.java 2005-11-12
22:10:01 UTC (rev 7539)
@@ -1,6 +1,8 @@
package freenet.io.comm;
+import freenet.node.PacketSequenceException;
+
/**
* Filter interface used by Freenet to decrypt incoming packets.
*/
@@ -28,8 +30,9 @@
* @param offset The offset to start reading from.
* @param length The length in bytes to read.
* @param peer The PeerContext the messages will be sent to.
+ * @throws PacketSequenceException
*/
- void processOutgoing(byte[] buf, int offset, int length, PeerContext peer)
throws NotConnectedException;
+ void processOutgoing(byte[] buf, int offset, int length, PeerContext peer)
throws NotConnectedException, LowLevelFilterException;
/**
* Is the given connection closed?
Modified: trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/UdpSocketManager.java 2005-11-12
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/io/comm/UdpSocketManager.java 2005-11-12
22:10:01 UTC (rev 7539)
@@ -46,6 +46,29 @@
protected UdpSocketManager() {
}
+ public void start() {
+ super.start();
+ Thread checker = new Thread(new USMChecker());
+ checker.setDaemon(true);
+ checker.start();
+ }
+
+ public class USMChecker implements Runnable {
+ public void run() {
+ while(true) {
+ try {
+ Thread.sleep(10*1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ if(UdpSocketManager.this.isAlive())
+ Logger.minor(this, "PING on
"+UdpSocketManager.this);
+ else
+ Logger.error(this, "MAIN LOOP
TERMINATED");
+ }
+ }
+ }
+
public UdpSocketManager(int listenPort) throws SocketException {
super("UdpSocketManager sender thread on port " + listenPort);
try {
@@ -64,6 +87,7 @@
}
public void run() { // Listen for packets
+ try {
while (_active) {
try {
DatagramPacket packet = getPacket();
@@ -78,6 +102,7 @@
if(lowLevelFilter != null) {
try {
lowLevelFilter.process(data, offset,
length, peer);
+ Logger.minor(this, "Successfully handled
packet length "+length);
} catch (Throwable t) {
Logger.error(this, "Caught "+t+" from
"+lowLevelFilter, t);
}
@@ -88,15 +113,19 @@
if(m != null)
checkFilters(m);
}
- }
+ } else
+ Logger.minor(this, "Null packet");
} catch (Throwable t) {
Logger.error(this, "Caught "+t, t);
}
}
+ } finally {
+ Logger.error(this, "run() exiting");
synchronized (this) {
_isDone = true;
notifyAll();
}
+ }
}
/**
@@ -361,7 +390,7 @@
try {
lowLevelFilter.processOutgoing(blockToSend, 0,
blockToSend.length, destination);
return;
- } catch (Throwable t) {
+ } catch (LowLevelFilterException t) {
Logger.error(this, "Caught "+t+" sending "+m+"
to "+destination, t);
destination.forceDisconnect();
throw new NotConnectedException("Error
"+t.toString()+" forced disconnect");
@@ -395,6 +424,7 @@
}
public void close(boolean exit) {
+ Logger.error(this, "Closing.", new Exception("error"));
_active = false;
synchronized (this) {
while (!_isDone) {
Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java 2005-11-12
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java 2005-11-12
22:10:01 UTC (rev 7539)
@@ -12,11 +12,6 @@
import freenet.crypt.EntropySource;
import freenet.crypt.PCFBMode;
import freenet.io.comm.*;
-import freenet.io.comm.LowLevelFilter;
-import freenet.io.comm.Message;
-import freenet.io.comm.Peer;
-import freenet.io.comm.PeerContext;
-import freenet.io.comm.UdpSocketManager;
import freenet.support.Fields;
import freenet.support.HexUtil;
import freenet.support.Logger;
@@ -723,6 +718,7 @@
}
int ackRequestsCount = decrypted[ptr++] & 0xff;
+ Logger.minor(this, "Ack requests: "+ackRequestsCount);
// These two are relative to our outgoing packet number
// Because they relate to packets we have sent.
@@ -737,7 +733,7 @@
}
int forgottenCount = decrypted[ptr++] & 0xff;
- //Logger.minor(this, "Forgotten packets: "+forgottenCount);
+ Logger.minor(this, "Forgotten packets: "+forgottenCount);
for(int i=0;i<forgottenCount;i++) {
int offset = decrypted[ptr++] & 0xff;
@@ -748,7 +744,10 @@
tracker.destForgotPacket(realSeqNo);
}
- if(seqNumber == -1) return;
+ if(seqNumber == -1) {
+ Logger.minor(this, "Returning because seqno = "+seqNumber);
+ return;
+ }
// No sequence number == no messages
int messages = decrypted[ptr++] & 0xff;
@@ -771,6 +770,7 @@
usm.checkFilters(m);
}
}
+ Logger.minor(this, "Done");
}
/**
@@ -915,8 +915,9 @@
* @param length Number of messages to read.
* @param bufferLength Size of the buffer to write into.
* @param pn Node to send the messages to.
+ * @throws PacketSequenceException
*/
- private void innerProcessOutgoing(byte[][] messageData, int start, int
length, int bufferLength, PeerNode pn, boolean neverWaitForPacketNumber,
AsyncMessageCallback[] callbacks) throws NotConnectedException,
WouldBlockException {
+ private void innerProcessOutgoing(byte[][] messageData, int start, int
length, int bufferLength, PeerNode pn, boolean neverWaitForPacketNumber,
AsyncMessageCallback[] callbacks) throws NotConnectedException,
WouldBlockException, PacketSequenceException {
Logger.minor(this,
"innerProcessOutgoing(...,"+start+","+length+","+bufferLength+")");
byte[] buf = new byte[bufferLength];
buf[0] = (byte)length;
@@ -935,8 +936,10 @@
/**
* Build a packet and send it. From a Message recently converted into
byte[],
* but with no outer formatting.
+ * @throws PacketSequenceException
*/
- public void processOutgoing(byte[] buf, int offset, int length,
PeerContext peer) throws NotConnectedException {
+ public void processOutgoing(byte[] buf, int offset, int length,
PeerContext peer) throws NotConnectedException, PacketSequenceException {
+ Logger.minor(this, "processOutgoing(buf, "+offset+", "+length+",
"+peer.getPeer());
if(!(peer instanceof PeerNode))
throw new IllegalArgumentException();
PeerNode pn = (PeerNode)peer;
@@ -948,8 +951,9 @@
/**
* Build a packet and send it. From a Message recently converted into
byte[],
* but with no outer formatting.
+ * @throws PacketSequenceException
*/
- public void processOutgoing(byte[] buf, int offset, int length, KeyTracker
tracker) throws KeyChangedException, NotConnectedException {
+ public void processOutgoing(byte[] buf, int offset, int length, KeyTracker
tracker) throws KeyChangedException, NotConnectedException,
PacketSequenceException {
byte[] newBuf = preformat(buf, offset, length);
processOutgoingPreformatted(newBuf, 0, newBuf.length, tracker, -1,
null);
}
@@ -957,8 +961,9 @@
/**
* Send a packet, with a packet number.
+ * @throws PacketSequenceException
*/
- public void processOutgoing(byte[] buf, int offset, int length, KeyTracker
tracker, int packetNo, AsyncMessageCallback[] callbacks) throws
KeyChangedException, NotConnectedException {
+ public void processOutgoing(byte[] buf, int offset, int length, KeyTracker
tracker, int packetNo, AsyncMessageCallback[] callbacks) throws
KeyChangedException, NotConnectedException, PacketSequenceException {
byte[] newBuf = preformat(buf, offset, length);
processOutgoingPreformatted(newBuf, 0, newBuf.length, tracker,
packetNo, callbacks);
}
@@ -966,10 +971,12 @@
/**
* Send a packet using the current key. Retry if it fails solely because
* the key changes.
+ * @throws PacketSequenceException
*/
- void processOutgoingPreformatted(byte[] buf, int offset, int length,
PeerNode peer, int k, AsyncMessageCallback[] callbacks) throws
NotConnectedException {
+ void processOutgoingPreformatted(byte[] buf, int offset, int length,
PeerNode peer, int k, AsyncMessageCallback[] callbacks) throws
NotConnectedException, PacketSequenceException {
while(true) {
try {
+ Logger.minor(this, "At beginning of processOutgoingPreformatted
loop for "+peer.getPeer());
KeyTracker tracker = peer.getCurrentKeyTracker();
if(tracker == null) {
Logger.normal(this, "Dropping packet: Not connected yet");
@@ -978,6 +985,7 @@
processOutgoingPreformatted(buf, offset, length, tracker, k,
callbacks);
return;
} catch (KeyChangedException e) {
+ Logger.normal(this, "Key changed");
// Go around again
}
}
@@ -986,8 +994,9 @@
/**
* Send a packet using the current key. Retry if it fails solely because
* the key changes.
+ * @throws PacketSequenceException
*/
- void processOutgoingPreformatted(byte[] buf, int offset, int length,
PeerNode peer, boolean neverWaitForPacketNumber, AsyncMessageCallback[]
callbacks) throws NotConnectedException, WouldBlockException {
+ void processOutgoingPreformatted(byte[] buf, int offset, int length,
PeerNode peer, boolean neverWaitForPacketNumber, AsyncMessageCallback[]
callbacks) throws NotConnectedException, WouldBlockException,
PacketSequenceException {
while(true) {
try {
KeyTracker tracker = peer.getCurrentKeyTracker();
@@ -1038,8 +1047,9 @@
* Means this is a resend of a dropped packet.
* @throws NotConnectedException If the node is not connected.
* @throws KeyChangedException If the primary key changes while we are
trying to send this packet.
+ * @throws PacketSequenceException
*/
- public void processOutgoingPreformatted(byte[] buf, int offset, int
length, KeyTracker tracker, int packetNumber, AsyncMessageCallback[] callbacks)
throws KeyChangedException, NotConnectedException {
+ public void processOutgoingPreformatted(byte[] buf, int offset, int
length, KeyTracker tracker, int packetNumber, AsyncMessageCallback[] callbacks)
throws KeyChangedException, NotConnectedException, PacketSequenceException {
if(Logger.shouldLog(Logger.MINOR, this)) {
String log =
"processOutgoingPreformatted("+Fields.hashCode(buf)+",
"+offset+","+length+","+tracker+","+packetNumber+",";
if(callbacks == null) log += "null";
@@ -1120,8 +1130,8 @@
Logger.minor(this, "Acking "+ackSeq);
int offsetSeq = otherSideSeqNumber - ackSeq;
if(offsetSeq > 255 || offsetSeq < 0)
- throw new IllegalStateException("bad ack offset "+offsetSeq+
- " - seqNumber="+otherSideSeqNumber+",
ackNumber="+ackSeq);
+ throw new PacketSequenceException("bad ack offset "+offsetSeq+
+ " - seqNumber="+otherSideSeqNumber+",
ackNumber="+ackSeq+" talking to "+tracker.pn.getPeer());
plaintext[ptr++] = (byte)offsetSeq;
}
@@ -1131,8 +1141,8 @@
Logger.minor(this, "Resend req: "+reqSeq);
int offsetSeq = otherSideSeqNumber - reqSeq;
if(offsetSeq > 255 || offsetSeq < 0)
- throw new IllegalStateException("bad resend request offset
"+offsetSeq+
- " - reqSeq="+reqSeq+",
otherSideSeqNumber="+otherSideSeqNumber);
+ throw new PacketSequenceException("bad resend request offset
"+offsetSeq+
+ " - reqSeq="+reqSeq+",
otherSideSeqNumber="+otherSideSeqNumber+" talking to "+tracker.pn.getPeer());
plaintext[ptr++] = (byte)offsetSeq;
}
@@ -1145,8 +1155,8 @@
// a packet we sent to them.
int offsetSeq = realSeqNumber - ackReqSeq;
if(offsetSeq > 255 || offsetSeq < 0)
- throw new IllegalStateException("bad ack requests offset:
"+offsetSeq+
- " - ackReqSeq="+ackReqSeq+",
packetNumber="+realSeqNumber);
+ throw new PacketSequenceException("bad ack requests offset:
"+offsetSeq+
+ " - ackReqSeq="+ackReqSeq+",
packetNumber="+realSeqNumber+" talking to "+tracker.pn.getPeer());
plaintext[ptr++] = (byte)offsetSeq;
}
Modified: trunk/freenet/src/freenet/node/InsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/InsertSender.java 2005-11-12 21:25:51 UTC
(rev 7538)
+++ trunk/freenet/src/freenet/node/InsertSender.java 2005-11-12 22:10:01 UTC
(rev 7539)
@@ -27,7 +27,7 @@
this.prb = prb;
this.fromStore = fromStore;
this.closestLocation = closestLocation;
- Thread t = new Thread(this, "InsertSender for UID "+uid+" on
"+node.portNumber);
+ Thread t = new Thread(this, "InsertSender for UID "+uid+" on
"+node.portNumber+" at "+System.currentTimeMillis());
t.setDaemon(true);
t.start();
}
Modified: trunk/freenet/src/freenet/node/KeyTracker.java
===================================================================
--- trunk/freenet/src/freenet/node/KeyTracker.java 2005-11-12 21:25:51 UTC
(rev 7538)
+++ trunk/freenet/src/freenet/node/KeyTracker.java 2005-11-12 22:10:01 UTC
(rev 7539)
@@ -320,7 +320,12 @@
* @param seqNumber The packet's serial number.
*/
public synchronized void receivedPacket(int seqNumber) {
- pn.receivedPacket();
+ try {
+ pn.receivedPacket();
+ } catch (NotConnectedException e) {
+ Logger.minor(this, "Ignoring, because disconnected");
+ return;
+ }
if(seqNumber == -1) return;
receivedPacketNumber(seqNumber);
if(packetNumbersReceived.contains(seqNumber)) {
@@ -449,9 +454,9 @@
pn.node.ps.queuedResendPacket();
} else {
String msg = "Asking me to resend packet "+seqNumber+
- " which we haven't sent yet or which they have already
acked";
+ " which we haven't sent yet or which they have already
acked (next="+nextPacketNumber+")";
// Can have a race condition
- if(seqNumber < nextPacketNumber && seqNumber > nextPacketNumber-16)
+ if(seqNumber < nextPacketNumber && seqNumber > nextPacketNumber-64)
Logger.minor(this, msg);
else
Logger.error(this, msg);
@@ -622,7 +627,7 @@
int packetNumber = qrr.packetNumber;
if(qrr.activeTime <= now) {
if(sentPacketsContents.get(packetNumber) == null) {
- Logger.error(this, "Asking to ack packet which has
already been acked: "+packetNumber+" on "+this+".grabAckRequests");
+ Logger.minor(this, "Asking to ack packet which has
already been acked: "+packetNumber+" on "+this+".grabAckRequests");
ackRequestQueue.remove(qrr);
continue;
}
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2005-11-12 21:25:51 UTC
(rev 7538)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2005-11-12 22:10:01 UTC
(rev 7539)
@@ -325,9 +325,11 @@
currentTracker = previousTracker = unverifiedTracker = null;
}
node.lm.lostOrRestartedNode(this);
+ sendHandshakeTime = System.currentTimeMillis();
}
public void forceDisconnect() {
+ Logger.error(this, "Forcing disconnect on "+this, new
Exception("debug"));
disconnected();
}
@@ -554,10 +556,12 @@
/**
* Update timeLastReceivedPacket
+ * @throws NotConnectedException
*/
- synchronized void receivedPacket() {
+ synchronized void receivedPacket() throws NotConnectedException {
if(isConnected == false && unverifiedTracker == null) {
Logger.error(this, "Received packet while disconnected!: "+this,
new Exception("error"));
+ throw new NotConnectedException();
}
timeLastReceivedPacket = System.currentTimeMillis();
randomizeMaxTimeBetweenPacketReceives();
@@ -644,7 +648,12 @@
ctx = null;
}
Logger.normal(this, "Completed handshake with "+this+" on "+replyTo+"
- current: "+currentTracker+" old: "+previousTracker+" unverified:
"+unverifiedTracker+" bootID: "+thisBootID);
- receivedPacket();
+ try {
+ receivedPacket();
+ } catch (NotConnectedException e) {
+ Logger.error(this, "Disconnected in completedHandshake
with "+this);
+ return true; // i suppose
+ }
node.peers.addConnectedPeer(this);
sentInitialMessages = false;
return true;
@@ -795,8 +804,9 @@
/**
* Send a payload-less packet on either key if necessary.
+ * @throws PacketSequenceException
*/
- public void sendAnyUrgentNotifications() {
+ public void sendAnyUrgentNotifications() throws PacketSequenceException {
Logger.minor(this, "sendAnyUrgentNotifications");
long now = System.currentTimeMillis();
KeyTracker cur, prev;
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2005-11-12 21:25:51 UTC (rev
7538)
+++ trunk/freenet/src/freenet/node/Version.java 2005-11-12 22:10:01 UTC (rev
7539)
@@ -20,10 +20,10 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- public static final int buildNumber = 176;
+ public static final int buildNumber = 177;
/** Oldest build of Fred we will talk to */
- public static final int lastGoodBuild = 176;
+ public static final int lastGoodBuild = 177;
/** The highest reported build of fred */
public static int highestSeenBuild = buildNumber;
Modified: trunk/freenet/src/freenet/support/DoublyLinkedListImpl.java
===================================================================
--- trunk/freenet/src/freenet/support/DoublyLinkedListImpl.java 2005-11-12
21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/support/DoublyLinkedListImpl.java 2005-11-12
22:10:01 UTC (rev 7539)
@@ -66,6 +66,20 @@
* Reset the size of the list to zero.
*/
public void clear() {
+ // Help to detect removal after clear().
+ // The check in remove() is enough, strictly,
+ // as long as people don't add elements afterwards.
+ Enumeration e = forwardElements();
+ DoublyLinkedList.Item pos = _headptr.next;
+ DoublyLinkedList.Item opos = _headptr;
+ while(true) {
+ pos.setParent(null);
+ pos.setPrev(null);
+ opos = pos;
+ pos = pos.getNext();
+ opos.setNext(null);
+ if(pos == _tailptr) break;
+ }
_headptr.next = _tailptr;
_tailptr.prev = _headptr;
size = 0;
@@ -222,10 +236,19 @@
* @return this item, or null if the item was not in the list
*/
public DoublyLinkedList.Item remove(DoublyLinkedList.Item i) {
+ if(isEmpty()) {
+ Logger.error(this, "Illegal ERROR: Removing from an empty
list!!");
+ throw new IllegalStateException("Illegal ERROR: Removing from
an empty list!!");
+ }
if (i.getParent() != this)
throw new PromiscuousItemException(i, i.getParent());
DoublyLinkedList.Item next = i.getNext(), prev = i.getPrev();
if (next == null || prev == null) return null; // not in the list
+ if(next.getPrev() != i || prev.getNext() != i) {
+ String msg = "Illegal ERROR: i="+i+", next="+next+",
next.prev="+next.getPrev()+", prev="+prev+", prev.next="+prev.getNext();
+ Logger.error(this, msg);
+ throw new IllegalStateException(msg);
+ }
prev.setNext(next);
next.setPrev(prev);
i.setNext(null);
Modified: trunk/freenet/src/freenet/support/UpdatableSortedLinkedList.java
===================================================================
--- trunk/freenet/src/freenet/support/UpdatableSortedLinkedList.java
2005-11-12 21:25:51 UTC (rev 7538)
+++ trunk/freenet/src/freenet/support/UpdatableSortedLinkedList.java
2005-11-12 22:10:01 UTC (rev 7539)
@@ -21,14 +21,17 @@
Logger.minor(this, "Add("+i+") on "+this);
if(list.isEmpty()) {
list.push(i);
+ checkList();
return;
}
if(i.compareTo(list.tail()) >= 0) {
list.push(i);
+ checkList();
return;
}
if(i.compareTo(list.head()) <= 0) {
list.unshift(i);
+ checkList();
return;
}
// Search the list for a good place to put it
@@ -39,6 +42,7 @@
(UpdatableSortedLinkedListItem) e.nextElement();
if(prev != null && cur.compareTo(i) >= 0 && prev.compareTo(i) <=
0) {
list.insertNext(prev, i);
+ checkList();
return;
}
Logger.minor(this, "Not matching "+cur+" "+prev);
@@ -47,26 +51,59 @@
throw new IllegalStateException("impossible");
}
- public synchronized void remove(UpdatableSortedLinkedListItem i) {
+ private StringBuffer sb = new StringBuffer(1000);
+
+ protected synchronized void checkList() {
+ // FIXME once satisfied that this works, make it only happen
occasionally
+ int statedLength = list.size();
+ int realLength = 0;
+ sb.setLength(0);
+ int x = 0;
+ for(Enumeration e = list.elements();e.hasMoreElements();) {
+ UpdatableSortedLinkedListItem i =
(UpdatableSortedLinkedListItem) e.nextElement();
+ sb.append(x);
+ sb.append("=");
+ sb.append(i);
+ sb.append('\n');
+ realLength++;
+ }
+ if(statedLength != realLength) {
+ String err = "statedLength = "+statedLength+" but realLength =
"+realLength+" on "+this;
+ Logger.error(this, "Illegal ERROR: "+err, new
Exception("error"));
+ Logger.error(this, "Details:\n"+sb.toString());
+ throw new IllegalStateException(err);
+ } else {
+ Logger.minor(this, "checkList() successful: realLength =
statedLength = "+realLength+" on "+this);
+ Logger.minor(this, "Details:\n"+sb.toString());
+ }
+ }
+
+ public synchronized void remove(UpdatableSortedLinkedListItem i) {
Logger.minor(this, "Remove("+i+") on "+this);
+ checkList();
list.remove(i);
+ checkList();
}
public synchronized void update(UpdatableSortedLinkedListItem i) {
Logger.minor(this, "Update("+i+") on "+this);
+ checkList();
if(i.compareTo(list.tail()) > 0) {
list.remove(i);
list.push(i);
+ checkList();
return;
}
if(i.compareTo(list.head()) < 0) {
list.remove(i);
list.unshift(i);
+ checkList();
return;
}
if(list.head() == list.tail() && i != list.head()) {
Logger.error(this, "Only 1 element: "+list.head()+" and updating
"+i+" on "+this, new Exception("error"));
add(i);
+ checkList();
return;
}
// Forwards or backwards?
@@ -94,6 +131,7 @@
if(i.compareTo(next) < 0 && i.compareTo(prev) > 0) {
list.remove(i);
list.insertNext(prev, i);
+ checkList();
return;
}
}
@@ -108,6 +146,7 @@
if(i.compareTo(next) < 0 && i.compareTo(prev) > 0) {
list.remove(i);
list.insertNext(prev, i);
+ checkList();
return;
}
}
@@ -116,6 +155,7 @@
dump();
remove(i);
add(i);
+ checkList();
}
/**
Modified:
trunk/freenet/src/freenet/support/UpdatableSortedLinkedListWithForeignIndex.java
===================================================================
---
trunk/freenet/src/freenet/support/UpdatableSortedLinkedListWithForeignIndex.java
2005-11-12 21:25:51 UTC (rev 7538)
+++
trunk/freenet/src/freenet/support/UpdatableSortedLinkedListWithForeignIndex.java
2005-11-12 22:10:01 UTC (rev 7539)
@@ -30,11 +30,13 @@
}
super.add(i);
map.put(i.indexValue(), item);
+ checkList();
}
public synchronized void remove(UpdatableSortedLinkedListItem item) {
super.remove(item);
map.remove(((IndexableUpdatableSortedLinkedListItem)item).indexValue());
+ checkList();
}
public synchronized boolean containsKey(Object o) {
@@ -48,5 +50,6 @@
IndexableUpdatableSortedLinkedListItem item =
(IndexableUpdatableSortedLinkedListItem) map.get(key);
if(item != null) remove(item);
+ checkList();
}
}