Author: toad
Date: 2008-06-21 23:56:14 +0000 (Sat, 21 Jun 2008)
New Revision: 20606

Modified:
   branches/db4o/freenet/src/freenet/client/FECCallback.java
   branches/db4o/freenet/src/freenet/client/FECCodec.java
   branches/db4o/freenet/src/freenet/client/FECQueue.java
   branches/db4o/freenet/src/freenet/client/async/SingleBlockInserter.java
   branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
   branches/db4o/freenet/src/freenet/client/async/SplitFileInserterSegment.java
Log:
db4o stores arrays as values!!
That means we cannot pass pointers to arrays around and expect them to stay the 
same!
Splitfile encoding was broken because of this: we need to copy the data back 
from the encoded buckets array.

Modified: branches/db4o/freenet/src/freenet/client/FECCallback.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/FECCallback.java   2008-06-21 
22:22:58 UTC (rev 20605)
+++ branches/db4o/freenet/src/freenet/client/FECCallback.java   2008-06-21 
23:56:14 UTC (rev 20606)
@@ -6,6 +6,7 @@
 import com.db4o.ObjectContainer;

 import freenet.client.async.ClientContext;
+import freenet.support.api.Bucket;

 /**
  * An interface wich has to be implemented by FECJob submitters
@@ -16,9 +17,16 @@
  */
 public interface FECCallback {

-       public void onEncodedSegment(ObjectContainer container, ClientContext 
context);
+       /**
+        * The implementor MUST copy the data manually from the arrays on the 
FECJob, because
+        * db4o persists arrays as inline values, so WE CANNOT UPDATE THE 
ARRAY!!
+        * @param container
+        * @param context
+        * @param job
+        */
+       public void onEncodedSegment(ObjectContainer container, ClientContext 
context, FECJob job, Bucket[] dataBuckets, Bucket[] checkBuckets, 
SplitfileBlock[] dataBlocks, SplitfileBlock[] checkBlocks);

-       public void onDecodedSegment(ObjectContainer container, ClientContext 
context);
+       public void onDecodedSegment(ObjectContainer container, ClientContext 
context, FECJob job, Bucket[] dataBuckets, Bucket[] checkBuckets, 
SplitfileBlock[] dataBlocks, SplitfileBlock[] checkBlocks);

        /** Something broke. */
        public void onFailed(Throwable t, ObjectContainer container, 
ClientContext context);

Modified: branches/db4o/freenet/src/freenet/client/FECCodec.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/FECCodec.java      2008-06-21 
22:22:58 UTC (rev 20605)
+++ branches/db4o/freenet/src/freenet/client/FECCodec.java      2008-06-21 
23:56:14 UTC (rev 20606)
@@ -248,16 +248,20 @@
                                readers[i] = new 
DataInputStream(buckets[i].getInputStream());
                        }

+                       int created = 0;
                        for(int i = 0; i < checkBlockStatus.length; i++) {
                                buckets[i + k] = checkBlockStatus[i];
                                if(buckets[i + k] == null) {
                                        buckets[i + k] = 
bf.makeBucket(blockLength);
                                        writers[i] = buckets[i + 
k].getOutputStream();
                                        toEncode[numberToEncode++] = i + k;
+                                       created++;
                                }
                                else
                                        writers[i] = null;
                        }
+                       if(logMINOR)
+                               Logger.minor(this, "Created "+created+" check 
buckets");

                        //                      Runtime.getRuntime().gc();
 //                     Runtime.getRuntime().runFinalization();

Modified: branches/db4o/freenet/src/freenet/client/FECQueue.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/FECQueue.java      2008-06-21 
22:22:58 UTC (rev 20605)
+++ branches/db4o/freenet/src/freenet/client/FECQueue.java      2008-06-21 
23:56:14 UTC (rev 20606)
@@ -87,6 +87,8 @@

        public void addToQueue(FECJob job, FECCodec codec, ObjectContainer 
container) {
                boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
+               if(logMINOR)
+                       Logger.minor(StandardOnionFECCodec.class, "Adding a new 
job to the queue: "+job+".");
                int maxThreads = getMaxRunningFECThreads();
                if(job.persistent) {
                        container.set(job);
@@ -129,8 +131,6 @@
                        }
                        notifyAll();
                }
-               if(logMINOR)
-                       Logger.minor(StandardOnionFECCodec.class, "Adding a new 
job to the queue.");
        }

        /**
@@ -171,21 +171,21 @@
                                        try {
                                                if(!job.persistent) {
                                                        if (job.isADecodingJob)
-                                                               
job.callback.onDecodedSegment(null, clientContext);
+                                                               
job.callback.onDecodedSegment(null, clientContext, job, job.dataBlocks, 
job.checkBlocks, job.dataBlockStatus, job.checkBlockStatus);
                                                        else
-                                                               
job.callback.onEncodedSegment(null, clientContext);
+                                                               
job.callback.onEncodedSegment(null, clientContext, job, job.dataBlocks, 
job.checkBlocks, job.dataBlockStatus, job.checkBlockStatus);
                                                } else {
                                                        
if(Logger.shouldLog(Logger.MINOR, this))
-                                                               
Logger.minor(this, "Scheduling callback...");
+                                                               
Logger.minor(this, "Scheduling callback for "+job+"...");
                                                        
databaseJobRunner.queue(new DBJob() {

                                                                public void 
run(ObjectContainer container, ClientContext context) {
                                                                        
if(Logger.shouldLog(Logger.MINOR, this))
                                                                                
Logger.minor(this, "Running callback for "+job);
                                                                        
if(job.isADecodingJob)
-                                                                               
job.callback.onDecodedSegment(container, clientContext);
+                                                                               
job.callback.onDecodedSegment(container, clientContext, job, job.dataBlocks, 
job.checkBlocks, job.dataBlockStatus, job.checkBlockStatus);
                                                                        else
-                                                                               
job.callback.onEncodedSegment(container, clientContext);
+                                                                               
job.callback.onEncodedSegment(container, clientContext, job, job.dataBlocks, 
job.checkBlocks, job.dataBlockStatus, job.checkBlockStatus);
                                                                        
container.delete(job);
                                                                }


Modified: 
branches/db4o/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/SingleBlockInserter.java     
2008-06-21 22:22:58 UTC (rev 20605)
+++ branches/db4o/freenet/src/freenet/client/async/SingleBlockInserter.java     
2008-06-21 23:56:14 UTC (rev 20606)
@@ -231,7 +231,11 @@

        public void schedule(ObjectContainer container, ClientContext context) 
throws InsertException {
                synchronized(this) {
-                       if(finished) return;
+                       if(finished) {
+                               if(logMINOR)
+                                       Logger.minor(this, "Finished already: 
"+this);
+                               return;
+                       }
                }
                if(getCHKOnly) {
                        ClientKeyBlock block = encode(container, context);

Modified: 
branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSegment.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSegment.java 
2008-06-21 22:22:58 UTC (rev 20605)
+++ branches/db4o/freenet/src/freenet/client/async/SplitFileFetcherSegment.java 
2008-06-21 23:56:14 UTC (rev 20606)
@@ -219,11 +219,13 @@
                }
        }

-       public void onDecodedSegment(ObjectContainer container, ClientContext 
context) {
+       public void onDecodedSegment(ObjectContainer container, ClientContext 
context, FECJob job, Bucket[] dataBuckets2, Bucket[] checkBuckets2, 
SplitfileBlock[] dataBlockStatus, SplitfileBlock[] checkBlockStatus) {
+               // Because we use SplitfileBlock, we DON'T have to copy here.
+               // See FECCallback comments for explanation.
                try {
                        if(isCollectingBinaryBlob()) {
                                for(int i=0;i<dataBuckets.length;i++) {
-                                       Bucket data = dataBuckets[i].getData();
+                                       Bucket data = 
dataBlockStatus[i].getData();
                                        try {
                                                maybeAddToBinaryBlob(data, i, 
false, container, context);
                                        } catch (FetchException e) {
@@ -271,7 +273,9 @@
                }
        }

-       public void onEncodedSegment(ObjectContainer container, ClientContext 
context) {
+       public void onEncodedSegment(ObjectContainer container, ClientContext 
context, FECJob job, Bucket[] dataBuckets2, Bucket[] checkBuckets2, 
SplitfileBlock[] dataBlockStatus, SplitfileBlock[] checkBlockStatus) {
+               // Because we use SplitfileBlock, we DON'T have to copy here.
+               // See FECCallback comments for explanation.
                synchronized(this) {
                        // Now insert *ALL* blocks on which we had at least one 
failure, and didn't eventually succeed
                        for(int i=0;i<dataBuckets.length;i++) {

Modified: 
branches/db4o/freenet/src/freenet/client/async/SplitFileInserterSegment.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/client/async/SplitFileInserterSegment.java    
    2008-06-21 22:22:58 UTC (rev 20605)
+++ 
branches/db4o/freenet/src/freenet/client/async/SplitFileInserterSegment.java    
    2008-06-21 23:56:14 UTC (rev 20606)
@@ -11,6 +11,7 @@
 import freenet.client.InsertContext;
 import freenet.client.InsertException;
 import freenet.client.Metadata;
+import freenet.client.SplitfileBlock;
 import freenet.keys.BaseClientKey;
 import freenet.keys.CHKBlock;
 import freenet.keys.ClientCHK;
@@ -446,7 +447,7 @@
                                } else
                                        parent.parent.completedBlock(true, 
container, context);
                        }
-                       onEncodedSegment(container, context);
+                       onEncodedSegment(container, context, null, dataBlocks, 
checkBlocks, null, null);
                }
                if (hasURIs) {
                        parent.segmentHasURIs(this, container, context);
@@ -466,13 +467,22 @@
                }
        }

-       public void onDecodedSegment(ObjectContainer container, ClientContext 
context) {} // irrevelant
+       public void onDecodedSegment(ObjectContainer container, ClientContext 
context, FECJob job, Bucket[] dataBuckets, Bucket[] checkBuckets, 
SplitfileBlock[] dataBlockStatus, SplitfileBlock[] checkBlockStatus) {} // 
irrevelant

-       public void onEncodedSegment(ObjectContainer container, ClientContext 
context) {
+       public void onEncodedSegment(ObjectContainer container, ClientContext 
context, FECJob job, Bucket[] dataBuckets, Bucket[] checkBuckets, 
SplitfileBlock[] dataBlockStatus, SplitfileBlock[] checkBlockStatus) {
+               logMINOR = Logger.shouldLog(Logger.MINOR, this);
                // Start the inserts
                try {
+                       if(logMINOR)
+                               Logger.minor(this, "Scheduling 
"+checkBlockInserters.length+" check blocks...");
                        for (int i = 0; i < checkBlockInserters.length; i++) {
-                               if(checkBlocks[i] == null) continue;
+                               // See comments on FECCallback: WE MUST COPY 
THE DATA BACK!!!
+                               checkBlocks[i] = checkBuckets[i];
+                               if(checkBlocks[i] == null) {
+                                       if(logMINOR)
+                                               Logger.minor(this, "Skipping 
check block "+i+" - is null");
+                                       continue;
+                               }
                                if(checkBlockInserters[i] != null) continue;
                                checkBlockInserters[i] = new 
SingleBlockInserter(parent.parent,
                                                checkBlocks[i], (short) -1, 
FreenetURI.EMPTY_CHK_URI,


Reply via email to