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

Modified Files:
        Node.java FailureTable.java SmartFailureTable.java Main.java 
Log Message:
6297:
Lots of Iakin's stuff, but on this commit:
New FailureTable - not secondary failtable yet, but new and improved plain fail table.
Have individual FailItem's, within a FailureEntry, for different HTLs, with a separate 
LRU queue,
Use LinkedList's, rather than Heap's, because we don't need an ADT.
Generally a fairly deep rewrite of the same methods.
Initial specs: 20,000 keys, 100,000 items (item is an HTL:time pair).
Don't pass in time - we don't need it, use the current time, and since we are 
synchronized this means we always start at the end of the queue.

Index: Node.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/Node.java,v
retrieving revision 1.238
retrieving revision 1.239
diff -u -w -r1.238 -r1.239
--- Node.java   1 Nov 2003 18:50:38 -0000       1.238
+++ Node.java   1 Nov 2003 22:05:36 -0000       1.239
@@ -110,7 +110,8 @@
 
         config.addOption("messageStoreSize",    1, 10000,   1350);  // 10000 live 
chains
         config.addOption("failureTableSize",    1, 20000,  1360); // 20000 failed 
keys - uses ~ 2.7MB
-        config.addOption("failureTableTime",    1, 1800000l, 1361); // 30 min
+        config.addOption("failureTableItems",  1, 100000, 1361);
+        config.addOption("failureTableTime",    1, 1800000l, 1362); // 30 min
     
         // ARK stuff
         config.addOption("minCP",               1, 0.01F,    1370);

Index: FailureTable.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/FailureTable.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -w -r1.16 -r1.17
--- FailureTable.java   31 Oct 2003 21:45:34 -0000      1.16
+++ FailureTable.java   1 Nov 2003 22:05:37 -0000       1.17
@@ -3,15 +3,16 @@
 import java.io.PrintWriter;
 import java.util.Date;
 import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.Random;
 
 import freenet.Core;
 import freenet.Key;
 import freenet.support.Checkpointed;
-import freenet.support.Heap;
-import freenet.support.Heap.Element;
-import freenet.support.sort.ArraySorter;
-import freenet.support.sort.QuickSorter;
+import freenet.support.DoublyLinkedList;
+import freenet.support.DoublyLinkedListImpl;
+import freenet.support.DoublyLinkedListImpl.Item;
 
 /**
  * Keeps track of keys that have been failed recently, and automatically 
@@ -25,7 +26,7 @@
       public static void main(String[] args) {
        // Determine memory usage for FT of a given size
        final int KEYS = 20000;
-          FailureTable ft = new FailureTable(KEYS, 1800000);
+          FailureTable ft = new FailureTable(KEYS, 5*KEYS, 1800000);
           Random r = new Random();
           Runtime rt = Runtime.getRuntime();
           rt.gc();
@@ -39,7 +40,7 @@
                byte[] keyval = new byte[20];
                r.nextBytes(keyval);
                Key k = new Key(keyval);
-               ft.failedToFind(k, 10, startTime);
+               ft.failedToFind(k, 10);
           }
           long endTime = System.currentTimeMillis();
           rt.gc();
@@ -77,23 +78,29 @@
       }
 
     protected int maxSize;
+       protected int maxItemsSize;
     protected long maxMillis;
     protected long lastCp = 0;
 
-    protected Hashtable failedKeys;
-    protected Heap queue;
+    protected Hashtable failedKeys; // of FailureEntry's
+    // In both cases, most recent is First(), LRU is Last()
+    // Push()/Pop(): MRU
+    // Unshift()/Shift(): LRU
+    DoublyLinkedList entries; // of FailureEntry's
+    DoublyLinkedList items; // of FailItem's
 
     /**
      * Creates a new.
      * @param size     The number of entries to hold.
      * @param millis   The max amount of time to keep an entry.
      */
-    public FailureTable(int size, long millis) {
+    public FailureTable(int size, int itemSize, long millis) {
         maxSize = size;
         maxMillis = millis;
-
+        maxItemsSize = itemSize;
         failedKeys = new Hashtable();
-        queue = new Heap();
+        entries = new DoublyLinkedListImpl();
+        items = new DoublyLinkedListImpl();
     }
 
     /**
@@ -102,27 +109,31 @@
      * @param hopsToLive   The hopsToLive when it could not be found.
      * @param time         The time at which it could not be retreived.
      */
-    public synchronized void failedToFind(Key k, int hopsToLive,
-                                          long time) {
+    public synchronized void failedToFind(Key k, int hopsToLive) {
+       long time = System.currentTimeMillis();
+       // Not an argument because it must be NOW - we don't want to mess with ADTs
+       
         FailureEntry fe = (FailureEntry) failedKeys.get(k);
+        
         if (fe == null) {
-            fe = new FailureEntry(k, hopsToLive, time);
+            fe = new FailureEntry(k, time);
+            fe.failed(hopsToLive, time);
             failedKeys.put(k, fe);
+            entries.push(fe);
         } else {
-            fe.remove();
-            if (hopsToLive > fe.hopsToLive) {
-                fe.time = time;
-                fe.hopsToLive = hopsToLive;
+               entries.remove(fe);
+               fe.failed(hopsToLive, time);
+               entries.push(fe);
             }
-        }
-
-        queue.put(fe);
-        while (queue.size() > maxSize) {
-            fe = (FailureEntry) queue.pop();
+        while (entries.size() > maxSize) {
+            fe = (FailureEntry) entries.shift();
             failedKeys.remove(fe.key);
             Core.diagnostics.occurrenceContinuous("failureTableBlocks",
                                                   (double) fe.blocks);
         }
+        while (items.size() > maxItemsSize) {
+               FailItem fi = (FailItem) items.shift();
+        }
     }
 
     /**
@@ -134,16 +145,9 @@
         FailureEntry fe = (FailureEntry) failedKeys.get(k);
         long time = System.currentTimeMillis();
 
-        if (fe != null && fe.hopsToLive >= hopsToLive &&
-            fe.time > (time - maxMillis)) {
+        if (fe == null) return -1;
 
-            fe.blocks++;
-            Core.diagnostics.occurrenceContinuous("timeBetweenFailedRequests",
-                                                 (double)(time - fe.lastHit));
-            fe.lastHit = time;
-            return fe.time;
-        } else
-            return -1;
+        return fe.shouldFail(hopsToLive, time);
     }
 
     /**
@@ -169,18 +173,19 @@
      * Purges the queue.
      */
     public synchronized void checkpoint() {
-        lastCp = System.currentTimeMillis();
-        long thresh = lastCp - maxMillis;
-        while (queue.size() > 0) {
-            FailureEntry fe = (FailureEntry) queue.top();
-            if (fe.time > thresh) {
-                break;
-            }
-            queue.pop();
-            failedKeys.remove(fe.key);
-            Core.diagnostics.occurrenceContinuous("failureTableBlocks",
-                                                  (double) fe.blocks);
-        }
+       // Will need old stuff later, don't bother
+//        lastCp = System.currentTimeMillis();
+//        long thresh = lastCp - maxMillis;
+//        while (queue.size() > 0) {
+//            FailureEntry fe = (FailureEntry) queue.top();
+//            if (fe.time > thresh) {
+//                break;
+//            }
+//            queue.pop();
+//            failedKeys.remove(fe.key);
+//            Core.diagnostics.occurrenceContinuous("failureTableBlocks",
+//                                                  (double) fe.blocks);
+//        }
     }
 
     public String getCheckpointName() {
@@ -201,51 +206,161 @@
                    + "<th>Age</th><th># of Blocks</th>" 
                    + "<th>lastHit</th></tr>");
 
-        Element[] elementArray = queue.elementArray();
-        QuickSorter.quickSort(new ArraySorter(elementArray));
-
+        FailureEntry fe = (FailureEntry)(entries.head());
         long time = System.currentTimeMillis();
-        for (int i = 0 ; i < elementArray.length ; i++) {
-            FailureEntry fe = (FailureEntry) elementArray[i];
-            boolean active = (time - fe.time) < maxMillis;
+        while(fe != null) {
+               fe.toHtml(pw, time);
+                       fe = (FailureEntry)fe.getNext();
+        }
+        pw.println("</table>");
+    }
+    
+    protected class FailItem extends Item {
+       FailureEntry fe;
+               public int hopsToLive;
+               private long time;
+               
+               public FailItem(FailureEntry fe, int hopsToLive, long time) {
+                       this.fe = fe;
+                       this.hopsToLive = hopsToLive;
+                       this.time = time;
+               }
+               
+               boolean matches(int htl, long now) {
+                       if(htl <= hopsToLive && time + maxMillis < now) {
+                               return true;
+                       } else return false;
+               }
+
+               /**
+                * @param pw
+                */
+               public void toHtml(PrintWriter pw, long time) {
+                       boolean active = (time - fe.lastFail) < maxMillis;
             pw.println("<tr><td><font color=\"" + (active ? "red" : "green") 
-                       + "\">" + fe.key + "</font></td><td>" + fe.hopsToLive 
-                       + "</td><td>" + (time - fe.time) / 1000 
+                                          + "\">" + fe.key + "</font></td><td>" + 
hopsToLive 
+                                          + "</td><td>" + (time - this.time) / 1000 
                        + "</td><td>" + fe.blocks 
                        + "</td><td>" + new Date(fe.lastHit) + "</td></tr>");
+
         }
-        pw.println("</table>");
     }
 
-
-    protected class FailureEntry extends Element {
-        public int hopsToLive;  //screw getters...
+    protected class FailureEntry extends Item {
         private Key key;
-        private long time;
 
         private int blocks;
         private long lastHit;
+        private long lastFail;
+        private int failures;
 
-        public FailureEntry(Key key, int hopsToLive, long time) {
-            this.hopsToLive = hopsToLive;
+        LinkedList myItems;
+        // java.util.LinkedList, NOT DoublyLinkedList, because we are already in 
items DLList
+        
+        public FailureEntry(Key key, long time) {
+               myItems = new LinkedList();
             this.key = key;
-            this.time = time;
-            this.lastHit = time;
             this.blocks = 0;
+            lastHit = time;
+        }
+        
+        /**
+                * @param pw
+                */
+               public void toHtml(PrintWriter pw, long time) {
+                       for(Iterator i = myItems.iterator();i.hasNext();) {
+                               FailItem fi = (FailItem)(i.next());
+                               fi.toHtml(pw, time);
+                       }
+               }
+
+               /**
+                * 
+                */
+               public void remove() {
+                       // TODO Auto-generated method stub
+                       for(Iterator i = myItems.iterator();i.hasNext();) {
+                               FailItem fi = (FailItem)(i.next());
+                               myItems.remove(fi);
+                               items.remove(fi);
+                       }
+                       entries.remove(this);
+               }
+               
+               /**
+         * Add a FailItem, or update an existing one
+                * @param hopsToLive the HTL of the request when it failed
+                * @param time the time when it failed (must not be
+                * lower than the previous time - intended to be the time when
+                * the enclosing synchronized method was entered).
+                */
+               public void failed(int hopsToLive, long time) {
+                       failures++;
+                       lastFail = time;
+                       boolean found = false;
+                       for(Iterator i = myItems.iterator();i.hasNext();) {
+                               FailItem fi = (FailItem)(i.next());
+                               if(fi.hopsToLive == hopsToLive) {
+                                       fi.time = time;
+                                       items.remove(fi);
+                                       items.push(fi); // MRU
+                                       found = true;
+                                       break;
+                               }
+                               if(fi.time + maxMillis < time) {
+                                       // Remove it
+                                       items.remove(fi);
+                                       i.remove();
+                               }
+                       }
+                       if(!found) {
+                               FailItem fi = new FailItem(this, hopsToLive, time);
+                               items.push(fi);
+                               myItems.addLast(fi);
+                       }
+               }
+               
+               /**
+                * Checks whether a query should fail.
+                * @return  The time at which the query that failed to find the key
+                *          occured, or < 0 if no such query is known.
+                */
+               public long shouldFail(int hopsToLive, long now) {
+                       for(Iterator i = myItems.iterator();i.hasNext();) {
+                               FailItem fi = (FailItem)(i.next());
+                               if(fi.time + maxMillis < now) {
+                                       items.remove(fi);
+                                       i.remove();
+                                       continue;
+                               }
+                               if(fi.hopsToLive >= hopsToLive) {
+                                       blocks++;
+                                       
Core.diagnostics.occurrenceContinuous("timeBetweenFailedRequests",
+                                                                                      
                                                          (double)(now - lastHit));
+                                       lastHit = now;
+                                       return fi.time;
+                               }
+                       }
+                       return -1;
+               }
+               /**
+                * @param item
+                */
+               public void add(FailItem item) {
+                       myItems.add(item);
         }
 
         public int compareTo(Object o) {
             //FailureEntry fe = (FailureEntry) o;
             //return (int) (fe.time - time);
             // older is "bigger"
-            long ot = ((FailureEntry) o).time;
-            return time == ot ? 0 : (time > ot ? -1 : 1);
+            long ot = ((FailureEntry) o).lastFail;
+            return lastFail == ot ? 0 : (lastFail > ot ? -1 : 1);
         }
 
         public String toString() {
-            return key.toString() + " " + hopsToLive + " " + new Date(time);
+            return key.toString();
         }
-
     }
 
 

Index: SmartFailureTable.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/SmartFailureTable.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -w -r1.4 -r1.5
--- SmartFailureTable.java      30 Oct 2003 01:34:02 -0000      1.4
+++ SmartFailureTable.java      1 Nov 2003 22:05:37 -0000       1.5
@@ -9,57 +9,61 @@
  *  on devl.  (yeah I know such description is lame --zab)
  */
 public class SmartFailureTable extends FailureTable {
-       final int treshold;
-       
-       /**
-        * reuse the constructor
-        * @param treshold - the number of hits before the key
-        * is marked irrelevant to pDNF calculation
-        */
-       public SmartFailureTable(int size, int treshold){
-               super(size,-1); //keys don't expire, do they?
-               this.treshold = treshold;
-       }
-       
-       public synchronized void checkpoint() {
-                lastCp = System.currentTimeMillis();
-               //override and do nothing, keys don't expire
-       }
-       
-       //contains a list of FailureEntries, doesn't extend it, aggregates it instead.
-       private class ExtendedFailureEntry {
-               Key key;
-               LinkedList history;
-               public ExtendedFailureEntry(Key key, int hopsToLive, long time) {
-                       this.key = key;
-                       history = new LinkedList();
-                       history.add(new FailureEntry(key, hopsToLive, time));
-               }
-               public FailureEntry getOldestEntry() {
-                       return (FailureEntry) history.getFirst();
-               }
-               
-               public FailureEntry getNewestEntry() {
-                       return (FailureEntry) history.getLast();
-               }
-               
-               public void update(int hopsToLive, long time) {
-                       history.addLast(new FailureEntry(key,hopsToLive,time));
-               }
-       }
-       
-       /**
-        * override...
-        */
-       public synchronized void failedToFind(Key k, int hopsToLive, long time) {
-               ExtendedFailureEntry efe = (ExtendedFailureEntry) failedKeys.get(k);
-               if (efe==null){
-                       efe = new ExtendedFailureEntry(k, hopsToLive, time);
-                       failedKeys.put(k,efe);
-               } else 
-               if (hopsToLive >= efe.getNewestEntry().hopsToLive)  //FIXME: > or >=???
-                       efe.update(hopsToLive,time);
-                       
-               //FINISHUP: decide if the heap is needed.
-       }
+       SmartFailureTable() {
+               super(-1,-1,-1);
+               throw new UnsupportedOperationException();
+       }
+//     final int treshold;
+//     
+//     /**
+//      * reuse the constructor
+//      * @param treshold - the number of hits before the key
+//      * is marked irrelevant to pDNF calculation
+//      */
+//     public SmartFailureTable(int size, int treshold){
+//             super(size,-1); //keys don't expire, do they?
+//             this.treshold = treshold;
+//     }
+//     
+//     public synchronized void checkpoint() {
+//              lastCp = System.currentTimeMillis();
+//             //override and do nothing, keys don't expire
+//     }
+//     
+//     //contains a list of FailureEntries, doesn't extend it, aggregates it instead.
+//     private class ExtendedFailureEntry {
+//             Key key;
+//             LinkedList history;
+//             public ExtendedFailureEntry(Key key, int hopsToLive, long time) {
+//                     this.key = key;
+//                     history = new LinkedList();
+//                     history.add(new FailureEntry(key, hopsToLive, time));
+//             }
+//             public FailureEntry getOldestEntry() {
+//                     return (FailureEntry) history.getFirst();
+//             }
+//             
+//             public FailureEntry getNewestEntry() {
+//                     return (FailureEntry) history.getLast();
+//             }
+//             
+//             public void update(int hopsToLive, long time) {
+//                     history.addLast(new FailureEntry(key,hopsToLive,time));
+//             }
+//     }
+//     
+//     /**
+//      * override...
+//      */
+//     public synchronized void failedToFind(Key k, int hopsToLive, long time) {
+//             ExtendedFailureEntry efe = (ExtendedFailureEntry) failedKeys.get(k);
+//             if (efe==null){
+//                     efe = new ExtendedFailureEntry(k, hopsToLive, time);
+//                     failedKeys.put(k,efe);
+//             } else 
+//             if (hopsToLive >= efe.getNewestEntry().hopsToLive)  //FIXME: > or >=???
+//                     efe.update(hopsToLive,time);
+//                     
+//             //FINISHUP: decide if the heap is needed.
+//     }
 }

Index: Main.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/Main.java,v
retrieving revision 1.289
retrieving revision 1.290
diff -u -w -r1.289 -r1.290
--- Main.java   31 Oct 2003 21:09:11 -0000      1.289
+++ Main.java   1 Nov 2003 22:05:37 -0000       1.290
@@ -816,6 +816,7 @@
 
             FailureTable ft = 
                 new FailureTable(params.getInt("failureTableSize"),
+                                               params.getInt("failureTableItems"),
                                  params.getLong("failureTableTime"));
 
             

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

Reply via email to