Author: toad
Date: 2008-05-22 18:22:55 +0000 (Thu, 22 May 2008)
New Revision: 20042

Added:
   branches/db4o/freenet/src/freenet/client/async/CooldownQueue.java
   branches/db4o/freenet/src/freenet/client/async/PersistentCooldownQueue.java
Modified:
   branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
   branches/db4o/freenet/src/freenet/client/async/RequestCooldownQueue.java
Log:
Implement a much simpler CooldownQueue using db4o queries.
We will keep the old one for in-memory-only stuff.
Created a new CooldownQueue interface for both of them.

Modified: 
branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2008-05-22 17:19:52 UTC (rev 20041)
+++ branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2008-05-22 18:22:55 UTC (rev 20042)
@@ -90,7 +90,7 @@
        private final RequestStarter starter;
        private final Node node;
        public final String name;
-       private final RequestCooldownQueue cooldownQueue;
+       private final CooldownQueue cooldownQueue;

        public static final String PRIORITY_NONE = "NONE";
        public static final String PRIORITY_SOFT = "SOFT";

Added: branches/db4o/freenet/src/freenet/client/async/CooldownQueue.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/CooldownQueue.java           
                (rev 0)
+++ branches/db4o/freenet/src/freenet/client/async/CooldownQueue.java   
2008-05-22 18:22:55 UTC (rev 20042)
@@ -0,0 +1,27 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.client.async;
+
+import freenet.keys.Key;
+import freenet.node.SendableGet;
+
+public interface CooldownQueue {
+
+       /**
+        * Add a key to the end of the queue. Returns the time at which it will 
be valid again.
+        */
+       public abstract long add(Key key, SendableGet client);
+
+       /**
+        * Remove a key whose cooldown time has passed.
+        * @return Either a Key or null if no keys have passed their cooldown 
time.
+        */
+       public abstract Key removeKeyBefore(long now);
+
+       /**
+        * @return True if the key was found.
+        */
+       public abstract boolean removeKey(Key key, SendableGet client, long 
time);
+
+}
\ No newline at end of file

Added: 
branches/db4o/freenet/src/freenet/client/async/PersistentCooldownQueue.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/PersistentCooldownQueue.java 
                        (rev 0)
+++ branches/db4o/freenet/src/freenet/client/async/PersistentCooldownQueue.java 
2008-05-22 18:22:55 UTC (rev 20042)
@@ -0,0 +1,94 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.client.async;
+
+import com.db4o.ObjectContainer;
+import com.db4o.ObjectSet;
+import com.db4o.query.Predicate;
+
+import freenet.keys.Key;
+import freenet.node.SendableGet;
+
+/**
+ * Persistable implementation of CooldownQueue. Much simpler than 
RequestCooldownQueue,
+ * and would use much more memory if it wasn't for the database!
+ * 
+ * Creator must call setContainer() and setCooldownTime() before use, after 
pulling it 
+ * out of the database.
+ * @author toad
+ */
+public class PersistentCooldownQueue implements CooldownQueue {
+       
+       private ObjectContainer container;
+       
+       private long cooldownTime;
+
+       private static class Item {
+               final SendableGet client;
+               final Key key;
+               final long time;
+               final PersistentCooldownQueue parent;
+               
+               Item(SendableGet client, Key key, long time, 
PersistentCooldownQueue parent) {
+                       this.client = client;
+                       this.key = key;
+                       this.time = time;
+                       this.parent = parent;
+               }
+       }
+       
+       void setContainer(ObjectContainer container) {
+               this.container = container;
+       }
+       
+       void setCooldownTime(long time) {
+               cooldownTime = time;
+       }
+
+       public long add(Key key, SendableGet client) {
+               assert(cooldownTime != 0);
+               long removeTime = System.currentTimeMillis() + cooldownTime;
+               Item item = new Item(client, key, removeTime, this);
+               container.set(item);
+               return removeTime;
+       }
+
+       public boolean removeKey(final Key key, final SendableGet client, final 
long time) {
+               boolean found = false;
+               ObjectSet results = container.query(new Predicate() {
+                       public boolean match(Item item) {
+                               if(item.parent != PersistentCooldownQueue.this) 
return false;
+                               if(item.key != key) return false;
+                               if(item.client != client) return false;
+                               return true;
+                               // Ignore time
+                       }
+               });
+               while(results.hasNext()) {
+                       found = true;
+                       Item i = (Item) results.next();
+                       container.delete(i);
+               }
+               return found;
+       }
+
+       public Key removeKeyBefore(final long now) {
+               // Will be called repeatedly until no more keys are returned, 
so it doesn't
+               // matter very much if they're not in order.
+               ObjectSet results = container.query(new Predicate() {
+                       public boolean match(Item item) {
+                               if(item.parent != PersistentCooldownQueue.this) 
return false;
+                               if(item.time > now) return false;
+                               return true;
+                       }
+               });
+               if(results.hasNext()) {
+                       Item i = (Item) results.next();
+                       container.delete(i);
+                       return i.key;
+               } else
+                       return null;
+       }
+
+}

Modified: 
branches/db4o/freenet/src/freenet/client/async/RequestCooldownQueue.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/RequestCooldownQueue.java    
2008-05-22 17:19:52 UTC (rev 20041)
+++ branches/db4o/freenet/src/freenet/client/async/RequestCooldownQueue.java    
2008-05-22 18:22:55 UTC (rev 20042)
@@ -16,7 +16,7 @@
  * circular buffer, we expand it if necessary.
  * @author toad
  */
-public class RequestCooldownQueue {
+public class RequestCooldownQueue implements CooldownQueue {

        /** keys which have been put onto the cooldown queue */ 
        private Key[] keys;
@@ -47,10 +47,10 @@
                this.cooldownTime = cooldownTime;
        }

-       /**
-        * Add a key to the end of the queue. Returns the time at which it will 
be valid again.
+       /* (non-Javadoc)
+        * @see freenet.client.async.CooldownQueue#add(freenet.keys.Key, 
freenet.node.SendableGet)
         */
-       synchronized long add(Key key, SendableGet client) {
+       public synchronized long add(Key key, SendableGet client) {
                long removeTime = System.currentTimeMillis() + cooldownTime;
                if(removeTime < getLastTime()) {
                        removeTime = getLastTime();
@@ -110,11 +110,10 @@
                return;
        }

-       /**
-        * Remove a key whose cooldown time has passed.
-        * @return Either a Key or null if no keys have passed their cooldown 
time.
+       /* (non-Javadoc)
+        * @see freenet.client.async.CooldownQueue#removeKeyBefore(long)
         */
-       synchronized Key removeKeyBefore(long now) {
+       public synchronized Key removeKeyBefore(long now) {
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
                boolean foundIT = false;
                if(Logger.shouldLog(Logger.DEBUG, this)) {
@@ -219,10 +218,10 @@
                return foundIT;
        }

-       /**
-        * @return True if the key was found.
+       /* (non-Javadoc)
+        * @see freenet.client.async.CooldownQueue#removeKey(freenet.keys.Key, 
freenet.node.SendableGet, long)
         */
-       synchronized boolean removeKey(Key key, SendableGet client, long time) {
+       public synchronized boolean removeKey(Key key, SendableGet client, long 
time) {
                if(time <= 0) return false; // We won't find it.
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
                if(holes < 0) Logger.error(this, "holes = "+holes+" !!");


Reply via email to