Update of /cvsroot/freenet/freenet/src/freenet
In directory sc8-pr-cvs1:/tmp/cvs-serv24104/src/freenet

Modified Files:
        ConnectionHandler.java OpenConnectionManager.java 
Log Message:
Move KillSurplusConnections back out of a thread, but do it smarter.  We will now keep 
a queue of closed connections to try and avoid even needing to search for closed 
connections to remove from the OCM.  Many other speedups to KillSurplusConnections
MultiValueTable has a new method - countAll(id) to get a count of connections to a 
peer (or whatever)

Index: ConnectionHandler.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/ConnectionHandler.java,v
retrieving revision 1.160
retrieving revision 1.161
diff -u -r1.160 -r1.161
--- ConnectionHandler.java      23 Sep 2003 00:55:09 -0000      1.160
+++ ConnectionHandler.java      26 Sep 2003 22:38:34 -0000      1.161
@@ -1022,6 +1022,7 @@
                                Core.logger.log(this, "Trailer chunk send failed for 
"+this+
                                                                ", closing", 
Logger.MINOR);
                                sendClosed.change(true);
+                ocm.markClosed(this);
                                sendingCount = 0;
                                synchronized(trailerSendLock) {
                                        sendingTrailerChunk = false;

Index: OpenConnectionManager.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/OpenConnectionManager.java,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -r1.108 -r1.109
--- OpenConnectionManager.java  26 Sep 2003 02:02:08 -0000      1.108
+++ OpenConnectionManager.java  26 Sep 2003 22:38:34 -0000      1.109
@@ -53,6 +53,8 @@
     private int openConns;
        private Object openConnsSync = new Object();
     
+    private LinkedList closedList = new LinkedList();
+    
     private final LRUQueue lru = new LRUQueue();
     // Queue of blacklisted peers
     private final BlackLRUQueue blq = new BlackLRUQueue(60000,100,3);
@@ -73,10 +75,6 @@
                logDEBUG = Core.logger.shouldLog(Logger.DEBUG, this);
         chs = new MultiValueTable(50, 3);
         openConns = 0;
-        SurplusKiller sk = new SurplusKiller(lru,maxConnections);
-        Thread skt = new Thread(sk,"Surplus connection killing thread");
-        skt.setDaemon(true);
-        skt.start();
     }
 
     /**
@@ -108,8 +106,11 @@
                synchronized(openConnsSync) {
                        openConns++;
                }
+        if ( maxConnections != 0 && lru.size() < maxConnections ) return;
                synchronized(lru) {
-            lru.notifyAll();
+            /* At toad's request moving back to diong this in every thred. */
+//            lru.notifyAll();
+            KillSurplusConnections();
         }
     }
     
@@ -231,6 +232,12 @@
                                                        id, Logger.DEBUG);
                return null;
     }
+    
+    public void markClosed(ConnectionHandler ch) {
+        synchronized(closedList) {
+            closedList.addFirst(ch);
+        }
+    }
        
     /**
      * This attempts to search for the open connection to id best suited for
@@ -303,13 +310,8 @@
        }
        
        protected final boolean onlyRTNodeConn(Identity id) {
-               if(!Main.node.rt.references(id))
-                       return false;
-               Enumeration e = chs.getAll(id);
-               if(!e.hasMoreElements()) return true; // it has zero
-               e.nextElement();
-               if(!e.hasMoreElements()) return true; // it has one
-               else return false; // it has more than one
+               if ( chs.countAll(id) <= 1 && Main.node.rt.references(id) ) return 
true;
+               else return false; // it has more than one or is not in the route
        }
        
     public int countOutboundConnections(Identity id) {
@@ -476,74 +478,71 @@
         * Kills off one or more connections to ensure that we stay below the 
connection limit
         * This method is appropriate to call after a connection has been added to the 
OCM 
         */
-    private class SurplusKiller implements Runnable {
-
-        private LRUQueue lru;
-        private int maxConnections;
-        
-        public SurplusKiller(LRUQueue lru,int maxConnections) {
-            this.lru = lru;
-            this.maxConnections = maxConnections;
-        }
-        
-        public void run() {
-            while (true) {
-                // Dump LRU idle connection.
-                //
-                // Note: You don't want to dump the simple LRU connection
-                //       because under heavy load the LRU connections are
-                //       the ones that are transferring data.
-                //       
-                ConnectionHandler oldest = null;
-                while (true) {
-                    synchronized (lru) {
-                        if ( !(maxConnections > 0 && lru.size() > maxConnections) ) {
-                            try {
-                                // wait till we are awakened - no more need to die
-                                lru.wait();
-                            } catch ( InterruptedException ie ) {
+    private void KillSurplusConnections() {
+        // Dump LRU idle connection.
+        //
+        // Note: You don't want to dump the simple LRU connection
+        //       because under heavy load the LRU connections are
+        //       the ones that are transferring data.
+        //       
+        ConnectionHandler oldest = null;
+        ConnectionHandler cached = null;
+        boolean oldestCache = false;
+        boolean candidateCache = false;
+        while (true) {
+            if ( maxConnections > 0 && lru.size() > maxConnections ) {
+                synchronized(closedList) {
+                    if ( !closedList.isEmpty() ) {
+                         oldest = (ConnectionHandler)closedList.removeLast();
+                    }
+                }
+                // Dump an idle connection if possible.
+                if ( oldest == null ) for (Enumeration e = lru.elements(); 
e.hasMoreElements();) {
+                    ConnectionHandler candidate = 
+                        (ConnectionHandler)e.nextElement();
+                    if (!(candidate.sending() || candidate.receiving())) {
+                        // If the oldest is open and the candidate is closed...
+                        if( !candidate.isOpen() ) {
+                            oldest = candidate;
+                            break;
+                        } else if ( oldest != null ) {
+                            //This can only happen if it closes during the run of
+                            //this loop, very unlikely but _anything_ which could
+                            //keep us from running onlyRTNodeConn is a good thing
+                            //because that involves locking hashtables, BigInteger
+                            //math and badness like that.
+                            if ( oldest != null && (!oldest.isOpen()) )
+                                break;
+                            // If the oldest is an only-conn-to-this-RTNode and the 
+                            // candidate is not... then use the candidate
+                            if ( ( ( oldest == cached && oldestCache ) ||
+                                   ( oldestCache = onlyRTNodeConn(oldest) ) ) && 
+                                 ! ( candidateCache = onlyRTNodeConn(candidate) ) ) {
+                                oldest = candidate;
+                                oldestCache = candidateCache;
                             }
+                            cached = oldest;
                         } else {
-                            // Dump an idle connection if possible.
-                            for (Enumeration e = lru.elements(); 
e.hasMoreElements();) {
-                                ConnectionHandler candidate = 
-                                    (ConnectionHandler)e.nextElement();
-                                if (!(candidate.sending() || candidate.receiving())) {
-                                    // If the oldest is open and the candidate is 
closed...
-                                    if( !candidate.isOpen() ) {
-                                        oldest = candidate;
-                                        break;
-                                    } else if ( oldest != null ) {
-                                        //This can only happen if it closes during 
the run of
-                                        //this loop, very unlikely but _anything_ 
which could
-                                        //keep us from running onlyRTNodeConn is a 
good thing
-                                        //because that involves locking hashtables, 
BigInteger
-                                        //math and badness like that.
-                                        if ( oldest != null && (!oldest.isOpen()) )
-                                            break;
-                                        // If the oldest is an 
only-conn-to-this-RTNode and the 
-                                        // candidate is not... then use the candidate
-                                        if(onlyRTNodeConn(oldest) && 
(!onlyRTNodeConn(candidate)) )
-                                            oldest = candidate;
-                                    } else {
-                                        oldest = candidate;
-                                    }
-                                }
-                            }
-                            if (oldest == null) {
-                                // Not good. This connection will most likely
-                                // be restarted, causing even more traffic :-(
-                                oldest = (ConnectionHandler)lru.pop();
-                            }
-
+                            oldest = candidate;
                         }
                     }
-                    if (oldest != null) {
-                        Core.diagnostics.occurrenceBinomial("connectionTimedout", 1, 
0);
-                        oldest.terminate();
-                        oldest = null;
-                    }
                 }
+                if (oldest == null) {
+                    // Not good. This connection will most likely
+                    // be restarted, causing even more traffic :-(
+                    oldest = (ConnectionHandler)lru.pop();
+                } else {
+                    lru.remove(oldest);
+                }
+
+            } else {
+                //We have killed enough connections
+                return;
+            }
+            if (oldest != null) {
+                Core.diagnostics.occurrenceBinomial("connectionTimedout", 1, 0);
+                oldest.terminate();
+                oldest = null;
             }
         }
     }

_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to