Author: toad
Date: 2008-04-19 19:45:58 +0000 (Sat, 19 Apr 2008)
New Revision: 19447

Modified:
   trunk/freenet/src/freenet/support/TokenBucket.java
Log:
Simpler and hopefully more accurate low level bandwidth limiter.

Modified: trunk/freenet/src/freenet/support/TokenBucket.java
===================================================================
--- trunk/freenet/src/freenet/support/TokenBucket.java  2008-04-19 19:10:08 UTC 
(rev 19446)
+++ trunk/freenet/src/freenet/support/TokenBucket.java  2008-04-19 19:45:58 UTC 
(rev 19447)
@@ -11,7 +11,6 @@
        protected long max;
        protected long timeLastTick;
        protected long nanosPerTick;
-       protected long nextWake;

        /**
         * Create a token bucket.
@@ -28,7 +27,6 @@
                this.nanosPerTick = nanosPerTick;
                long now = System.currentTimeMillis();
                this.timeLastTick = now * (1000 * 1000);
-               nextWake = now;
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
        }

@@ -80,6 +78,7 @@
         * @param tokens The number of tokens to remove.
         */
        public synchronized void forceGrab(long tokens) {
+               if(logMINOR) Logger.minor(this, "forceGrab("+tokens+")");
                if(tokens <= 0) {
                        Logger.error(this, "forceGrab("+tokens+") - negative 
value!!", new Exception("error"));
                        return;
@@ -87,6 +86,7 @@
                addTokens();
                current -= tokens;
                if(current > max) current = max;
+               if(logMINOR) Logger.minor(this, "Removed tokens, balance now 
"+current);
        }

        /**
@@ -121,34 +121,23 @@
                addTokens();
                if(current > max) current = max;
                if(logMINOR) Logger.minor(this, "current="+current);
-               if(current > tokens) {
-                       current -= tokens;
+               
+               current -= tokens;
+               
+               if(current >= 0) {
                        if(logMINOR) Logger.minor(this, "Got tokens instantly, 
current="+current);
                        return;
+               } else {
+                       if(logMINOR) Logger.minor(this, "Blocking grab removed 
tokens, current="+current+" - will have to wait because negative...");
                }
-               long extra = 0;
-               if(current > 0) {
-                       tokens -= current;
-                       current = 0;
-               } else if(current < 0) {
-                       extra = -current;
-                       if(logMINOR) Logger.minor(this, "Neutralizing debt: 
"+extra);
-                       current = 0;
-               }
-               long minDelayNS = nanosPerTick * (tokens + extra);
+               
+               long minDelayNS = nanosPerTick * (-current);
                long minDelayMS = minDelayNS / (1000*1000) + (minDelayNS % 
(1000*1000) == 0 ? 0 : 1);
                long now = System.currentTimeMillis();
+               long wakeAt = now + minDelayMS;

-               // Schedule between the blockingGrab's.
+               if(logMINOR) Logger.minor(this, "Waking in "+minDelayMS+" 
millis");

-               if(nextWake < now) {
-                       if(logMINOR) Logger.minor(this, "Resetting nextWake to 
now");
-                       nextWake = now;
-               }
-               if(logMINOR) Logger.minor(this, "nextWake: "+(nextWake - 
now)+"ms");
-               long wakeAt = nextWake + minDelayMS;
-               nextWake = wakeAt;
-               if(logMINOR) Logger.minor(this, "nextWake now: "+(nextWake - 
now)+"ms");
                while(true) {
                        now = System.currentTimeMillis();
                        int delay = (int) Math.min(Integer.MAX_VALUE, wakeAt - 
now);
@@ -160,11 +149,7 @@
                                // Go around the loop again.
                        }
                }
-               // Remove the tokens, even if we have built up a debt due to 
forceGrab()s and
-               // will therefore go negative. We have paid off the initial 
debt, and we have
-               // paid off the tokens, any more debt is a problem for future 
blockingGrab's!
-               current -= tokens;
-               if(logMINOR) Logger.minor(this, "Blocking grab removed tokens: 
current="+current);
+               if(logMINOR) Logger.minor(this, "Blocking grab finished: 
current="+current);
        }

        public synchronized void recycle(long tokens) {


Reply via email to