Author: toad
Date: 2008-07-19 22:17:25 +0000 (Sat, 19 Jul 2008)
New Revision: 21276

Modified:
   branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
   
branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
Log:
Greatly speed up add() in schedule(), hopefully speeding up the 
pre-registration phase (when we add all the RegisterMe's).

Modified: 
branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSegment.java 
2008-07-19 22:04:07 UTC (rev 21275)
+++ branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSegment.java 
2008-07-19 22:17:25 UTC (rev 21276)
@@ -692,8 +692,7 @@
                        SplitFileFetcherSubSegment seg = getSubSegment(0, 
container, false);
                        if(persistent)
                                container.activate(seg, 1);
-                       for(int 
i=0;i<dataRetries.length+checkRetries.length;i++)
-                               seg.add(i, true, container, context, false);
+                       seg.addAll(dataRetries.length+checkRetries.length, 
true, container, context, false);

                        seg.schedule(container, context, true, regmeOnly);
                        if(persistent)

Modified: 
branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java  
    2008-07-19 22:04:07 UTC (rev 21275)
+++ 
branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSubSegment.java  
    2008-07-19 22:17:25 UTC (rev 21276)
@@ -426,6 +426,57 @@
                return false;
        }

+       public void addAll(int blocks, boolean dontSchedule, ObjectContainer 
container, ClientContext context, boolean dontComplainOnDupes) {
+               if(persistent) {
+//                     container.activate(segment, 1);
+                       container.activate(blockNums, 1);
+               }
+               boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
+               if(logMINOR) Logger.minor(this, "Adding "+blocks+" blocks to 
"+this+" dontSchedule="+dontSchedule);
+               boolean schedule = true;
+               synchronized(segment) {
+                       if(cancelled)
+                               throw new IllegalStateException("Adding blocks 
to already cancelled "+this);
+                       for(int i=0;i<blocks;i++) {
+                               Integer ii = new Integer(i);
+                               if(blockNums.contains(ii)) {
+                                       if(!dontComplainOnDupes)
+                                               Logger.error(this, "Block 
numbers already contain block "+i);
+                                       else if(logMINOR)
+                                               Logger.minor(this, "Block 
numbers already contain block "+i);
+                               } else {
+                                       blockNums.add(ii);
+                               }
+                               if(dontSchedule) schedule = false;
+                               /**
+                                * Race condition:
+                                * 
+                                * Starter thread sees there is only one block 
on us, so removes us.
+                                * Another thread adds a block. We don't 
schedule as we now have two blocks.
+                                * Starter thread removes us.
+                                * Other blocks may be added later, but we are 
never rescheduled.
+                                * 
+                                * Fixing this by only removing the 
SendableRequest after we've removed the 
+                                * block is nontrivial with the current code.
+                                * So what we do here is simply check whether 
we are registered, instead of 
+                                * checking whether blockNums.size() > 1 as we 
used to.
+                                */
+                               if(schedule && getParentGrabArray() != null) {
+                                       if(logMINOR) Logger.minor(this, 
"Already registered, not scheduling: "+blockNums.size()+" : "+blockNums);
+                                       schedule = false;
+                               }
+
+                       }
+               }
+               if(persistent)
+                       container.set(blockNums);
+               if(schedule) {
+                       // Only need to register once for all the blocks.
+                       context.getChkFetchScheduler().register(null, new 
SendableGet[] { this }, false, persistent, true, null, null);
+               }
+
+       }
+       
        public void add(int blockNo, boolean dontSchedule, ObjectContainer 
container, ClientContext context, boolean dontComplainOnDupes) {
                if(persistent) {
 //                     container.activate(segment, 1);


Reply via email to