Author: toad
Date: 2008-06-19 22:57:31 +0000 (Thu, 19 Jun 2008)
New Revision: 20503

Modified:
   branches/db4o/freenet/src/freenet/client/FailureCodeTracker.java
   branches/db4o/freenet/src/freenet/client/FetchWaiter.java
   branches/db4o/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
   branches/db4o/freenet/src/freenet/client/InsertContext.java
   branches/db4o/freenet/src/freenet/client/PutWaiter.java
   branches/db4o/freenet/src/freenet/client/async/ClientCallback.java
   branches/db4o/freenet/src/freenet/client/async/ClientPutter.java
   branches/db4o/freenet/src/freenet/client/async/ManifestElement.java
   branches/db4o/freenet/src/freenet/client/async/SimpleManifestPutter.java
   branches/db4o/freenet/src/freenet/client/events/ClientEventListener.java
   branches/db4o/freenet/src/freenet/client/events/ClientEventProducer.java
   branches/db4o/freenet/src/freenet/client/events/EventDumper.java
   branches/db4o/freenet/src/freenet/client/events/EventLogger.java
   branches/db4o/freenet/src/freenet/client/events/SimpleEventProducer.java
   branches/db4o/freenet/src/freenet/keys/FreenetURI.java
   branches/db4o/freenet/src/freenet/node/NodeARKInserter.java
   branches/db4o/freenet/src/freenet/node/TextModeClientInterface.java
   branches/db4o/freenet/src/freenet/node/fcp/AllDataMessage.java
   branches/db4o/freenet/src/freenet/node/fcp/ClientGet.java
   branches/db4o/freenet/src/freenet/node/fcp/ClientPut.java
   branches/db4o/freenet/src/freenet/node/fcp/ClientPutBase.java
   branches/db4o/freenet/src/freenet/node/fcp/ClientPutDir.java
   branches/db4o/freenet/src/freenet/node/fcp/ClientRequest.java
   branches/db4o/freenet/src/freenet/node/fcp/FCPClient.java
   branches/db4o/freenet/src/freenet/node/fcp/FCPConnectionHandler.java
   branches/db4o/freenet/src/freenet/node/fcp/GetFailedMessage.java
   branches/db4o/freenet/src/freenet/node/fcp/ProtocolErrorMessage.java
   branches/db4o/freenet/src/freenet/node/fcp/PutFailedMessage.java
   branches/db4o/freenet/src/freenet/node/updater/NodeUpdater.java
   branches/db4o/freenet/src/freenet/node/updater/RevocationChecker.java
   
branches/db4o/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java
   branches/db4o/freenet/src/freenet/support/SimpleReadOnlyArrayBucket.java
   branches/db4o/freenet/src/freenet/support/api/Bucket.java
   branches/db4o/freenet/src/freenet/support/io/ArrayBucket.java
   branches/db4o/freenet/src/freenet/support/io/BucketChainBucket.java
   branches/db4o/freenet/src/freenet/support/io/DelayedFreeBucket.java
   branches/db4o/freenet/src/freenet/support/io/FileBucket.java
   branches/db4o/freenet/src/freenet/support/io/MultiReaderBucket.java
   branches/db4o/freenet/src/freenet/support/io/NullBucket.java
   
branches/db4o/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
   branches/db4o/freenet/src/freenet/support/io/ReadOnlyFileSliceBucket.java
   branches/db4o/freenet/src/freenet/support/io/TempFileBucket.java
Log:
FCP: Client*: Store to database whenever there is a change.
Beginnings of deletion support: Client* in FCP, also Bucket's.
There is a callback in freenet.client.async.ClientRequester, but it doesn't do 
anything yet: currently the underlying structures will be leaked on removing a 
request.


Modified: branches/db4o/freenet/src/freenet/client/FailureCodeTracker.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/FailureCodeTracker.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/FailureCodeTracker.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -7,6 +7,8 @@
 import java.util.HashMap;
 import java.util.Iterator;

+import com.db4o.ObjectContainer;
+
 import freenet.support.SimpleFieldSet;

 /**
@@ -182,5 +184,21 @@
        public boolean isEmpty() {
                return map.isEmpty();
        }
+
+       public void removeFrom(ObjectContainer container) {
+               Item[] items;
+               Integer[] ints;
+               synchronized(this) {
+                       items = (Item[]) map.values().toArray(new 
Item[map.size()]);
+                       ints = (Integer[]) map.keySet().toArray(new 
Integer[map.size()]);
+                       map.clear();
+               }
+               for(int i=0;i<items.length;i++) {
+                       container.delete(items[i]);
+                       container.delete(ints[i]);
+               }
+               container.delete(map);
+               container.delete(this);
+       }

 }

Modified: branches/db4o/freenet/src/freenet/client/FetchWaiter.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/FetchWaiter.java   2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/FetchWaiter.java   2008-06-19 
22:57:31 UTC (rev 20503)
@@ -38,7 +38,7 @@
                throw new UnsupportedOperationException();
        }

-       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state) {
+       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state, 
ObjectContainer container) {
                throw new UnsupportedOperationException();
        }


Modified: 
branches/db4o/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2008-06-19 22:57:31 UTC (rev 20503)
@@ -87,7 +87,7 @@
                this.persistentFileTracker = node.persistentTempBucketFactory;
                random = r;
                this.globalEventProducer = new SimpleEventProducer();
-               globalEventProducer.addEventListener(new 
EventLogger(Logger.MINOR));
+               globalEventProducer.addEventListener(new 
EventLogger(Logger.MINOR, false));
                curMaxLength = Long.MAX_VALUE;
                curMaxTempLength = Long.MAX_VALUE;
                curMaxMetadataLength = 1024 * 1024;
@@ -219,7 +219,7 @@
                        // Impossible
                }

-               public void onGeneratedURI(FreenetURI uri, BaseClientPutter 
state) {
+               public void onGeneratedURI(FreenetURI uri, BaseClientPutter 
state, ObjectContainer container) {
                        // Impossible
                }


Modified: branches/db4o/freenet/src/freenet/client/InsertContext.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/InsertContext.java 2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/InsertContext.java 2008-06-19 
22:57:31 UTC (rev 20503)
@@ -3,6 +3,8 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.client;

+import com.db4o.ObjectContainer;
+
 import freenet.client.async.USKManager;
 import freenet.client.events.ClientEventProducer;
 import freenet.client.events.SimpleEventProducer;
@@ -75,4 +77,9 @@
                this.cacheLocalRequests = ctx.cacheLocalRequests;
        }

+       public void removeFrom(ObjectContainer container) {
+               eventProducer.removeFrom(container);
+               container.delete(this);
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/client/PutWaiter.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/PutWaiter.java     2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/PutWaiter.java     2008-06-19 
22:57:31 UTC (rev 20503)
@@ -35,7 +35,7 @@
                notifyAll();
        }

-       public synchronized void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state) {
+       public synchronized void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state, ObjectContainer container) {
                if(Logger.shouldLog(Logger.MINOR, this))
                        Logger.minor(this, "URI: "+uri);
                if(this.uri == null)

Modified: branches/db4o/freenet/src/freenet/client/async/ClientCallback.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ClientCallback.java  
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/async/ClientCallback.java  
2008-06-19 22:57:31 UTC (rev 20503)
@@ -25,7 +25,7 @@

        public void onFailure(InsertException e, BaseClientPutter state, 
ObjectContainer container);

-       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state);
+       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state, 
ObjectContainer container);

        /** Called when freenet.async thinks that the request should be 
serialized to
         * disk, if it is a persistent request. */

Modified: branches/db4o/freenet/src/freenet/client/async/ClientPutter.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ClientPutter.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/async/ClientPutter.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -204,7 +204,7 @@
                        if(targetFilename != null)
                                uri = uri.pushMetaString(targetFilename);
                }
-               client.onGeneratedURI(uri, this);
+               client.onGeneratedURI(uri, this, container);
        }

        public void cancel(ObjectContainer container, ClientContext context) {

Modified: branches/db4o/freenet/src/freenet/client/async/ManifestElement.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ManifestElement.java 
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/async/ManifestElement.java 
2008-06-19 22:57:31 UTC (rev 20503)
@@ -3,6 +3,8 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.client.async;

+import com.db4o.ObjectContainer;
+
 import freenet.keys.FreenetURI;
 import freenet.support.api.Bucket;

@@ -17,7 +19,7 @@
        final String fullName;

        /** Data to be inserted. Can be null, if the insert has completed. */
-       final Bucket data;
+       Bucket data;

        /** MIME type override. null => use default for filename */
        final String mimeOverride;
@@ -76,9 +78,12 @@
                return false;
        }

-       public void freeData() {
-               if(data != null)
+       public void freeData(ObjectContainer container) {
+               if(data != null) {
                        data.free();
+                       data.removeFrom(container);
+                       data = null;
+               }
        }

        public String getName() {

Modified: 
branches/db4o/freenet/src/freenet/client/async/SimpleManifestPutter.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/SimpleManifestPutter.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/async/SimpleManifestPutter.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -584,7 +584,7 @@
                if(state.getToken() == baseMetadata) {
                        this.finalURI = key.getURI();
                        if(logMINOR) Logger.minor(this, "Got metadata key: 
"+finalURI);
-                       cb.onGeneratedURI(finalURI, this);
+                       cb.onGeneratedURI(finalURI, this, container);
                } else {
                        // It's a sub-Metadata
                        Metadata m = (Metadata) state.getToken();

Modified: 
branches/db4o/freenet/src/freenet/client/events/ClientEventListener.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/events/ClientEventListener.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/events/ClientEventListener.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -25,4 +25,11 @@
      **/
     public void receive(ClientEvent ce, ObjectContainer maybeContainer, 
ClientContext context);

+    /**
+     * Called when the EventProducer gets removeFrom(ObjectContainer).
+     * If the listener is the main listener which probably called 
removeFrom(), it should do nothing.
+     * If it's a tag-along but request specific listener, it may need to 
remove itself.
+     */
+       public void onRemoveEventProducer(ObjectContainer container);
+
 }

Modified: 
branches/db4o/freenet/src/freenet/client/events/ClientEventProducer.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/events/ClientEventProducer.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/events/ClientEventProducer.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -35,6 +35,8 @@
      * @return     true if a Listener was removed, false otherwise.
      */
     boolean removeEventListener(ClientEventListener cel);
+
+       void removeFrom(ObjectContainer container);
 }



Modified: branches/db4o/freenet/src/freenet/client/events/EventDumper.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/events/EventDumper.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/events/EventDumper.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -12,13 +12,20 @@
 public class EventDumper implements ClientEventListener {

        final PrintWriter pw;
+       final boolean removeWithProducer;

-       public EventDumper(PrintWriter writer) {
+       public EventDumper(PrintWriter writer, boolean removeWithProducer) {
                this.pw = writer;
+               this.removeWithProducer = removeWithProducer;
        }

        public void receive(ClientEvent ce, ObjectContainer container, 
ClientContext context) {
                pw.println(ce.getDescription());
        }

+       public void onRemoveEventProducer(ObjectContainer container) {
+               if(removeWithProducer)
+                       container.delete(this);
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/client/events/EventLogger.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/events/EventLogger.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/events/EventLogger.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -16,9 +16,11 @@
 public class EventLogger implements ClientEventListener {

        final int logPrio;
+       final boolean removeWithProducer;

-       public EventLogger(int prio) {
+       public EventLogger(int prio, boolean removeWithProducer) {
                logPrio = prio;
+               this.removeWithProducer = removeWithProducer;
        }

     /**
@@ -30,4 +32,9 @@
     public void receive(ClientEvent ce, ObjectContainer container, 
ClientContext context) {
        Logger.logStatic(ce, ce.getDescription(), logPrio);
     }
+
+       public void onRemoveEventProducer(ObjectContainer container) {
+               if(removeWithProducer)
+                       container.delete(this);
+       }
 }

Modified: 
branches/db4o/freenet/src/freenet/client/events/SimpleEventProducer.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/events/SimpleEventProducer.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/client/events/SimpleEventProducer.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -81,4 +81,13 @@
        for (int i = 0 ; i < cela.length ; i++)
            addEventListener(cela[i]);
     }
+
+       public void removeFrom(ObjectContainer container) {
+               ClientEventListener[] list = (ClientEventListener[]) 
listeners.toArray(new ClientEventListener[listeners.size()]);
+               listeners.clear();
+               container.delete(listeners);
+               for(int i=0;i<list.length;i++)
+                       list[i].onRemoveEventProducer(container);
+               container.delete(this);
+       }
 }

Modified: branches/db4o/freenet/src/freenet/keys/FreenetURI.java
===================================================================
--- branches/db4o/freenet/src/freenet/keys/FreenetURI.java      2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/keys/FreenetURI.java      2008-06-19 
22:57:31 UTC (rev 20503)
@@ -16,6 +16,8 @@
 import java.util.StringTokenizer;
 import java.util.Vector;

+import com.db4o.ObjectContainer;
+
 import freenet.support.Base64;
 import freenet.support.Fields;
 import freenet.support.HexUtil;
@@ -831,4 +833,9 @@
        public URI toURI(String basePath) throws URISyntaxException {
                return new URI(basePath + toString(false, false));
        }
+
+       public void removeFrom(ObjectContainer container) {
+               // All members are inline (arrays, ints etc), treated as 
values, so we can happily just call delete(this).
+               container.delete(this);
+       }
 }

Modified: branches/db4o/freenet/src/freenet/node/NodeARKInserter.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeARKInserter.java 2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/NodeARKInserter.java 2008-06-19 
22:57:31 UTC (rev 20503)
@@ -224,7 +224,7 @@
                startInserter();
        }

-       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state) {
+       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state, 
ObjectContainer container) {
                if(logMINOR) Logger.minor(this, "Generated URI for " + 
darknetOpennetString + " ARK: "+uri);
                long l = uri.getSuggestedEdition();
                if(l < crypto.myARKNumber) {

Modified: branches/db4o/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/TextModeClientInterface.java 
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/TextModeClientInterface.java 
2008-06-19 22:57:31 UTC (rev 20503)
@@ -80,7 +80,7 @@
        this.downloadsDir = server.downloadsDir;
        this.in = in;
        this.out = out;
-        client.addGlobalHook(new EventDumper(new PrintWriter(out, true)));
+        client.addGlobalHook(new EventDumper(new PrintWriter(out, true), 
false));
        }

     public TextModeClientInterface(Node n, HighLevelSimpleClient c, File 
downloadDir, InputStream in, OutputStream out) {
@@ -92,7 +92,7 @@
        this.downloadsDir = downloadDir;
        this.in = in;
        this.out = out;
-        client.addGlobalHook(new EventDumper(new PrintWriter(out, true)));
+        client.addGlobalHook(new EventDumper(new PrintWriter(out, true), 
false));
     }

     public void run() {

Modified: branches/db4o/freenet/src/freenet/node/fcp/AllDataMessage.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/AllDataMessage.java      
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/AllDataMessage.java      
2008-06-19 22:57:31 UTC (rev 20503)
@@ -3,6 +3,8 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.node.fcp;

+import com.db4o.ObjectContainer;
+
 import freenet.node.Node;
 import freenet.support.SimpleFieldSet;
 import freenet.support.api.Bucket;
@@ -58,4 +60,8 @@
                return global;
        }

+       public void removeFrom(ObjectContainer container) {
+               container.delete(this);
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/ClientGet.java   2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/ClientGet.java   2008-06-19 
22:57:31 UTC (rev 20503)
@@ -19,6 +19,7 @@
 import freenet.client.async.ClientContext;
 import freenet.client.async.ClientGetter;
 import freenet.client.async.ClientRequester;
+import freenet.client.async.DBJob;
 import freenet.client.events.ClientEvent;
 import freenet.client.events.ClientEventListener;
 import freenet.client.events.SplitfileProgressEvent;
@@ -30,6 +31,7 @@
 import freenet.support.io.CannotCreateFromFieldSetException;
 import freenet.support.io.FileBucket;
 import freenet.support.io.FileUtil;
+import freenet.support.io.NativeThread;
 import freenet.support.io.NullBucket;
 import freenet.support.io.SerializableToFieldSetBucketUtil;

@@ -39,6 +41,8 @@
  */
 public class ClientGet extends ClientRequest implements ClientCallback, 
ClientEventListener {

+       /** Fetch context. Never passed in: always created new by the 
ClientGet. Therefore, we
+        * can safely delete it in requestWasRemoved(). */
        private final FetchContext fctx;
        private final ClientGetter getter;
        private final short returnType;
@@ -313,8 +317,6 @@
                        synchronized(this) {
                                started = true;
                        }
-                       if(persistenceType == PERSIST_FOREVER)
-                               container.set(this); // Update
                } catch (FetchException e) {
                        synchronized(this) {
                                started = true;
@@ -326,11 +328,13 @@
                        }
                        onFailure(new 
FetchException(FetchException.INTERNAL_ERROR, t), null, container);
                }
+               if(persistenceType == PERSIST_FOREVER)
+                       container.set(this); // Update
        }

-       public void onLostConnection() {
+       public void onLostConnection(ObjectContainer container) {
                if(persistenceType == PERSIST_CONNECTION)
-                       cancel();
+                       cancel(null);
                // Otherwise ignore
        }

@@ -401,9 +405,13 @@
                trySendDataFoundOrGetFailed(null);

                if(adm != null)
-                       trySendAllDataMessage(adm, null);
+                       trySendAllDataMessage(adm, null, container);
                if(!dontFree)
                        data.free();
+               if(persistenceType == PERSIST_FOREVER) {
+                       returnBucket.storeTo(container);
+                       container.set(this);
+               }
                finish(container);
                client.notifySuccess(this);
        }
@@ -432,17 +440,21 @@

        }

-       private void trySendAllDataMessage(AllDataMessage msg, 
FCPConnectionOutputHandler handler) {
+       private void trySendAllDataMessage(AllDataMessage msg, 
FCPConnectionOutputHandler handler, ObjectContainer container) {
                if(persistenceType != ClientRequest.PERSIST_CONNECTION) {
                        allDataPending = msg;
+                       if(persistenceType == ClientRequest.PERSIST_FOREVER)
+                               container.set(this);
                } else {
                        client.queueClientRequestMessage(msg, 0);
                }
        }

-       private void trySendProgress(SimpleProgressMessage msg, 
FCPConnectionOutputHandler handler) {
+       private void trySendProgress(SimpleProgressMessage msg, 
FCPConnectionOutputHandler handler, ObjectContainer container) {
                if(persistenceType != ClientRequest.PERSIST_CONNECTION) {
                        progressPending = msg;
+                       if(persistenceType == ClientRequest.PERSIST_FOREVER)
+                               container.set(this);
                }
                client.queueClientRequestMessage(msg, 
VERBOSITY_SPLITFILE_PROGRESS);
        }
@@ -486,6 +498,8 @@
                if(Logger.shouldLog(Logger.MINOR, this))
                        Logger.minor(this, "Caught "+e, e);
                trySendDataFoundOrGetFailed(null);
+               if(persistenceType == PERSIST_FOREVER)
+                       container.set(this);
                finish(container);
                client.notifyFailure(this);
        }
@@ -498,7 +512,7 @@
                // Ignore
        }

-       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state) {
+       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state, 
ObjectContainer container) {
                // Ignore
        }

@@ -517,19 +531,45 @@
                FCPMessage msg = new 
PersistentRequestRemovedMessage(getIdentifier(), global);
                client.queueClientRequestMessage(msg, 0);

-               freeData();
-               finish(container);
+               freeData(container);
+               
+               if(persistenceType == PERSIST_FOREVER) {
+                       container.delete(fctx);
+                       getter.removeFrom(container);
+                       if(targetFile != null)
+                               container.delete(targetFile);
+                       if(tempFile != null)
+                               container.delete(tempFile);
+                       if(getFailedMessage != null)
+                               getFailedMessage.removeFrom(container);
+                       if(postFetchProtocolErrorMessage != null)
+                               
postFetchProtocolErrorMessage.removeFrom(container);
+                       if(allDataPending != null)
+                               allDataPending.removeFrom(container);
+               }
+               super.requestWasRemoved(container);
        }

-       public void receive(ClientEvent ce) {
+       public void receive(ClientEvent ce, ObjectContainer container, 
ClientContext context) {
                // Don't need to lock, verbosity is final and finished is never 
unset.
                if(finished) return;
                if(!(((verbosity & VERBOSITY_SPLITFILE_PROGRESS) == 
VERBOSITY_SPLITFILE_PROGRESS) &&
                                (ce instanceof SplitfileProgressEvent)))
                        return;
-               SimpleProgressMessage progress =
+               final SimpleProgressMessage progress =
                        new SimpleProgressMessage(identifier, global, 
(SplitfileProgressEvent)ce);
-               trySendProgress(progress, null);
+               // container may be null...
+               if(persistenceType == PERSIST_FOREVER && container == null) {
+                       context.jobRunner.queue(new DBJob() {
+
+                               public void run(ObjectContainer container, 
ClientContext context) {
+                                       trySendProgress(progress, null, 
container);
+                               }
+                               
+                       }, NativeThread.HIGH_PRIORITY, false);
+               } else {
+                       trySendProgress(progress, null, container);
+               }
        }

        // This is distinct from the ClientGetMessage code, as later on it will 
be radically
@@ -587,9 +627,15 @@
                return getter;
        }

-       protected void freeData() {
-               if(returnBucket != null)
-                       returnBucket.free();
+       protected void freeData(ObjectContainer container) {
+               Bucket data;
+               synchronized(this) {
+                       data = returnBucket;
+                       returnBucket = null;
+               }
+               data.free();
+               if(persistenceType == PERSIST_FOREVER)
+                       data.removeFrom(container);
        }

        public boolean hasSucceeded() {
@@ -738,6 +784,8 @@
                                        if(redirect != null) this.uri = 
redirect;
                                        started = true;
                                }
+                               if(persistenceType == PERSIST_FOREVER)
+                                       container.set(this);
                        }
                        return true;
                } catch (FetchException e) {
@@ -749,4 +797,8 @@
        public synchronized boolean hasPermRedirect() {
                return getFailedMessage != null && getFailedMessage.redirectURI 
!= null;
        }
+
+       public void onRemoveEventProducer(ObjectContainer container) {
+               // Do nothing, we called the removeFrom().
+       }
 }

Modified: branches/db4o/freenet/src/freenet/node/fcp/ClientPut.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/ClientPut.java   2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/ClientPut.java   2008-06-19 
22:57:31 UTC (rev 20503)
@@ -46,7 +46,7 @@
        private final File origFilename;
        /** If uploadFrom==UPLOAD_FROM_REDIRECT, this is the target of the 
redirect */
        private final FreenetURI targetURI;
-       private final Bucket data;
+       private Bucket data;
        private final ClientMetadata clientMetadata;
        /** We store the size of inserted data before freeing it */
        private long finishedSize;
@@ -383,10 +383,16 @@
                }
        }

-       protected void freeData() {
-               if(data == null) return;
-               finishedSize=data.size();
-               data.free();
+       protected void freeData(ObjectContainer container) {
+               Bucket d;
+               synchronized(this) {
+                       d = data;
+                       data = null;
+                       finishedSize = d.size();
+               }
+               if(d == null) return;
+               d.free();
+               d.removeFrom(container);
        }

        public SimpleFieldSet getFieldSet() {
@@ -474,7 +480,7 @@

        public boolean restart(ObjectContainer container, ClientContext 
context) {
                if(!canRestart()) return false;
-               setVarsRestart();
+               setVarsRestart(container);
                try {
                        if(putter.restart(earlyEncode, container, context)) {
                                synchronized(this) {
@@ -482,6 +488,8 @@
                                        started = true;
                                }
                        }
+                       if(persistenceType == PERSIST_FOREVER)
+                               container.set(this);
                        return true;
                } catch (InsertException e) {
                        onFailure(e, null, container);
@@ -492,4 +500,8 @@
        public void onFailure(FetchException e, ClientGetter state, 
ObjectContainer container) {}

        public void onSuccess(FetchResult result, ClientGetter state, 
ObjectContainer container) {}
+
+       public void onRemoveEventProducer(ObjectContainer container) {
+               // Do nothing, we called the removeFrom().
+       }
 }

Modified: branches/db4o/freenet/src/freenet/node/fcp/ClientPutBase.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/ClientPutBase.java       
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/ClientPutBase.java       
2008-06-19 22:57:31 UTC (rev 20503)
@@ -7,6 +7,7 @@
 import freenet.client.*;
 import freenet.client.async.BaseClientPutter;
 import freenet.client.async.ClientCallback;
+import freenet.client.async.ClientContext;
 import freenet.client.events.ClientEvent;
 import freenet.client.events.ClientEventListener;
 import freenet.client.events.FinishedCompressionEvent;
@@ -25,6 +26,7 @@
  */
 public abstract class ClientPutBase extends ClientRequest implements 
ClientCallback, ClientEventListener {

+       /** Created new for each ClientPutBase, so we have to delete it in 
requestWasRemoved() */
        final InsertContext ctx;
        final boolean getCHKOnly;

@@ -46,7 +48,7 @@
        // Not that important, so not saved on persistence.
        // Probably saving it would conflict with later changes (full 
persistence at
        // ClientPutter level).
-       private FCPMessage progressMessage;
+       private transient FCPMessage progressMessage;

        /** Whether to force an early generation of the CHK */
        protected final boolean earlyEncode;
@@ -127,9 +129,9 @@
                }
        }

-       public void onLostConnection() {
+       public void onLostConnection(ObjectContainer container) {
                if(persistenceType == PERSIST_CONNECTION)
-                       cancel();
+                       cancel(container);
                // otherwise ignore
        }

@@ -140,7 +142,7 @@
                        succeeded = true;
                        finished = true;
                }
-               freeData();
+               freeData(container);
                finish(container);
                trySendFinalMessage(null);
                client.notifySuccess(this);
@@ -152,18 +154,20 @@
                        finished = true;
                        putFailedMessage = new PutFailedMessage(e, identifier, 
global);
                }
-               freeData();
+               freeData(container);
                finish(container);
                trySendFinalMessage(null);
                client.notifyFailure(this);
        }

-       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state) {
+       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state, 
ObjectContainer container) {
                synchronized(this) {
                        if((generatedURI != null) && !uri.equals(generatedURI))
                                Logger.error(this, "onGeneratedURI("+uri+ ',' 
+state+") but already set generatedURI to "+generatedURI);
                        generatedURI = uri;
                }
+               if(persistenceType == PERSIST_FOREVER)
+                       container.set(this);
                trySendGeneratedURIMessage(null);
        }

@@ -181,11 +185,18 @@
                FCPMessage msg = new 
PersistentRequestRemovedMessage(getIdentifier(), global);
                client.queueClientRequestMessage(msg, 0);

-               freeData();
-               finish(container);
+               freeData(container);
+               if(persistenceType == PERSIST_FOREVER) {
+                       ctx.removeFrom(container);
+                       if(putFailedMessage != null)
+                               putFailedMessage.removeFrom(container);
+                       if(generatedURI != null)
+                               generatedURI.removeFrom(container);
+                       publicURI.removeFrom(container);
+               }
        }

-       public void receive(ClientEvent ce) {
+       public void receive(ClientEvent ce, ObjectContainer container, 
ClientContext context) {
                if(finished) return;
                if(ce instanceof SplitfileProgressEvent) {
                        if((verbosity & VERBOSITY_SPLITFILE_PROGRESS) == 
VERBOSITY_SPLITFILE_PROGRESS) {
@@ -389,12 +400,14 @@
                return s;
        }

-       public void setVarsRestart() {
+       public void setVarsRestart(ObjectContainer container) {
                synchronized(this) {
                        finished = false;
                        this.putFailedMessage = null;
                        this.progressMessage = null;
                        started = false;
                }
+               if(persistenceType == PERSIST_FOREVER)
+                       container.set(this);
        }
 }

Modified: branches/db4o/freenet/src/freenet/node/fcp/ClientPutDir.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/ClientPutDir.java        
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/ClientPutDir.java        
2008-06-19 22:57:31 UTC (rev 20503)
@@ -238,25 +238,25 @@
                }
        }

-       public void onLostConnection() {
+       public void onLostConnection(ObjectContainer container) {
                if(persistenceType == PERSIST_CONNECTION)
-                       cancel();
+                       cancel(container);
                // otherwise ignore
        }

-       protected void freeData() {
-               freeData(manifestElements);
+       protected void freeData(ObjectContainer container) {
+               freeData(manifestElements, container);
        }

-       private void freeData(HashMap manifestElements) {
+       private void freeData(HashMap manifestElements, ObjectContainer 
container) {
                Iterator i = manifestElements.values().iterator();
                while(i.hasNext()) {
                        Object o = i.next();
                        if(o instanceof HashMap)
-                               freeData((HashMap)o);
+                               freeData((HashMap)o, container);
                        else {
                                ManifestElement e = (ManifestElement) o;
-                               e.freeData();
+                               e.freeData(container);
                        }
                }
        }
@@ -355,7 +355,7 @@

        public boolean restart(ObjectContainer container, ClientContext 
context) {
                if(!canRestart()) return false;
-               setVarsRestart();
+               setVarsRestart(container);
                        makePutter();
                start(container, context);
                return true;
@@ -364,4 +364,8 @@
        public void onFailure(FetchException e, ClientGetter state, 
ObjectContainer container) {}

        public void onSuccess(FetchResult result, ClientGetter state, 
ObjectContainer container) {}
+
+       public void onRemoveEventProducer(ObjectContainer container) {
+               // Do nothing, we called the removeFrom().
+       }
 }

Modified: branches/db4o/freenet/src/freenet/node/fcp/ClientRequest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/ClientRequest.java       
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/ClientRequest.java       
2008-06-19 22:57:31 UTC (rev 20503)
@@ -121,7 +121,7 @@
        }

        /** Lost connection */
-       public abstract void onLostConnection();
+       public abstract void onLostConnection(ObjectContainer container);

        /** Send any pending messages for a persistent request e.g. after 
reconnecting */
        public abstract void sendPendingMessages(FCPConnectionOutputHandler 
handler, boolean includePersistentRequest, boolean includeData, boolean 
onlyData);
@@ -206,11 +206,13 @@
                }
        }

-       public void cancel() {
+       public void cancel(ObjectContainer container) {
                ClientRequester cr = getClientRequest();
                // It might have been finished on startup.
                if(cr != null) cr.cancel();
-               freeData();
+               freeData(container);
+               if(persistenceType == PERSIST_FOREVER)
+                       container.set(this);
        }

        public boolean isPersistentForever() {
@@ -234,9 +236,9 @@
        protected abstract ClientRequester getClientRequest();

        /** Completed request dropped off the end without being acknowledged */
-       public void dropped() {
-               cancel();
-               freeData();
+       public void dropped(ObjectContainer container) {
+               cancel(container);
+               freeData(container);
        }

        /** Return the priority class */
@@ -245,7 +247,7 @@
        }

        /** Free cached data bucket(s) */
-       protected abstract void freeData(); 
+       protected abstract void freeData(ObjectContainer container); 

        /** Request completed. But we may have to stick around until we are 
acked. */
        protected void finish(ObjectContainer container) {
@@ -344,7 +346,10 @@
                        return; // quick return, nothing was changed
                }

-               container.commit();
+               if(persistenceType == PERSIST_FOREVER) {
+                       container.set(this);
+                       container.commit(); // commit before we send the message
+               }

                // this could become too complex with more parameters, but for 
now its ok
                final PersistentRequestModifiedMessage modifiedMsg;
@@ -360,11 +365,6 @@
                client.queueClientRequestMessage(modifiedMsg, 0);
        }

-       /**
-        * Called after a RemovePersistentRequest. Send a 
PersistentRequestRemoved to the clients.
-        */
-       public abstract void requestWasRemoved(ObjectContainer container);
-
        /** Utility method for storing details of a possibly encrypted bucket. 
*/
        protected void bucketToFS(SimpleFieldSet fs, String name, boolean 
includeSize, Bucket data) {
                SerializableToFieldSetBucket bucket = 
(SerializableToFieldSetBucket) data;
@@ -384,8 +384,13 @@
                }, NativeThread.HIGH_PRIORITY, false);
        }

-       public void delete(ObjectContainer container) {
+       /**
+        * Called after a RemovePersistentRequest. Send a 
PersistentRequestRemoved to the clients.
+        * If the request is in the database, delete it.
+        */
+       public void requestWasRemoved(ObjectContainer container) {
+               if(persistenceType != PERSIST_FOREVER) return;
+               if(uri != null) uri.removeFrom(container);
                container.delete(this);
-               // FIXME delete underlying structures
        }
 }

Modified: branches/db4o/freenet/src/freenet/node/fcp/FCPClient.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/FCPClient.java   2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/FCPClient.java   2008-06-19 
22:57:31 UTC (rev 20503)
@@ -188,7 +188,7 @@
         req.requestWasRemoved(container);
                if(kill) {
                        if(logMINOR) Logger.minor(this, "Killing request "+req);
-                       req.cancel();
+                       req.cancel(container);
                }
                if(completionCallback != null)
                        completionCallback.onRemove(req);
@@ -378,8 +378,8 @@
                Iterator i = toStart.iterator();
                while(i.hasNext()) {
                        ClientRequest req = (ClientRequest) i.next();
-                       req.cancel();
-                       req.delete(container);
+                       req.cancel(container);
+                       req.requestWasRemoved(container);
                }
        }


Modified: branches/db4o/freenet/src/freenet/node/fcp/FCPConnectionHandler.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/FCPConnectionHandler.java        
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/FCPConnectionHandler.java        
2008-06-19 22:57:31 UTC (rev 20503)
@@ -111,7 +111,7 @@
                        dupe = killedDupe;
                }
                for(int i=0;i<requests.length;i++)
-                       requests[i].onLostConnection();
+                       requests[i].onLostConnection(null);
                if(!dupe) {
                server.core.clientContext.jobRunner.queue(new DBJob() {

@@ -382,7 +382,7 @@
                if(failedMessage != null) {
                        outputHandler.queue(failedMessage);
                        if(cp != null)
-                               cp.cancel();
+                               cp.cancel(null);
                        return;
                } else {
                        if(Logger.shouldLog(Logger.MINOR, this))
@@ -564,7 +564,7 @@
                if(req != null) {
                        req.requestWasRemoved(null);
                        if(kill)
-                               req.cancel();
+                               req.cancel(null);
                }
                return req;
        }

Modified: branches/db4o/freenet/src/freenet/node/fcp/GetFailedMessage.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/GetFailedMessage.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/GetFailedMessage.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -5,6 +5,8 @@

 import java.net.MalformedURLException;

+import com.db4o.ObjectContainer;
+
 import freenet.client.FailureCodeTracker;
 import freenet.client.FetchException;
 import freenet.keys.FreenetURI;
@@ -134,4 +136,10 @@
                throw new 
MessageInvalidException(ProtocolErrorMessage.INVALID_MESSAGE, "GetFailed goes 
from server to client not the other way around", identifier, global);
        }

+       public void removeFrom(ObjectContainer container) {
+               redirectURI.removeFrom(container); // URI belongs to the parent 
which is also being removed.
+               tracker.removeFrom(container);
+               container.delete(this);
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/node/fcp/ProtocolErrorMessage.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/ProtocolErrorMessage.java        
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/ProtocolErrorMessage.java        
2008-06-19 22:57:31 UTC (rev 20503)
@@ -3,6 +3,8 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.node.fcp;

+import com.db4o.ObjectContainer;
+
 import freenet.node.Node;
 import freenet.support.Fields;
 import freenet.support.Logger;
@@ -171,4 +173,8 @@
                return "ProtocolError";
        }

+       public void removeFrom(ObjectContainer container) {
+               container.delete(this);
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/node/fcp/PutFailedMessage.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/PutFailedMessage.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/fcp/PutFailedMessage.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -5,6 +5,8 @@

 import java.net.MalformedURLException;

+import com.db4o.ObjectContainer;
+
 import freenet.client.FailureCodeTracker;
 import freenet.client.InsertException;
 import freenet.keys.FreenetURI;
@@ -108,4 +110,10 @@
                throw new 
MessageInvalidException(ProtocolErrorMessage.INVALID_MESSAGE, "PutFailed goes 
from server to client not the other way around", identifier, global);
        }

+       public void removeFrom(ObjectContainer container) {
+               tracker.removeFrom(container);
+               expectedURI.removeFrom(container);
+               container.delete(this);
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/node/updater/NodeUpdater.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/updater/NodeUpdater.java     
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/updater/NodeUpdater.java     
2008-06-19 22:57:31 UTC (rev 20503)
@@ -268,7 +268,7 @@
                // Impossible
        }

-       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state) {
+       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state, 
ObjectContainer container) {
                // Impossible
        }


Modified: branches/db4o/freenet/src/freenet/node/updater/RevocationChecker.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/updater/RevocationChecker.java       
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/node/updater/RevocationChecker.java       
2008-06-19 22:57:31 UTC (rev 20503)
@@ -225,7 +225,7 @@

        }

-       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state) {
+       public void onGeneratedURI(FreenetURI uri, BaseClientPutter state, 
ObjectContainer container) {
                // TODO Auto-generated method stub

        }

Modified: 
branches/db4o/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java  
    2008-06-19 20:57:54 UTC (rev 20502)
+++ 
branches/db4o/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java  
    2008-06-19 22:57:31 UTC (rev 20503)
@@ -755,7 +755,7 @@
                                // Irrelevant
                        }

-                       public void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state) {
+                       public void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state, ObjectContainer container) {
                                // Ignore, not possible
                        }

@@ -802,7 +802,7 @@
                        public void onFetchable(BaseClientPutter state) {
                                // Ignore
                        }
-                       public void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state) {
+                       public void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state, ObjectContainer container) {
                                // Ignore
                        }
                        public void onMajorProgress() {
@@ -1124,7 +1124,7 @@
                                // Irrelevant
                        }

-                       public void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state) {
+                       public void onGeneratedURI(FreenetURI uri, 
BaseClientPutter state, ObjectContainer container) {
                                // Ignore, not possible
                        }


Modified: 
branches/db4o/freenet/src/freenet/support/SimpleReadOnlyArrayBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/SimpleReadOnlyArrayBucket.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/SimpleReadOnlyArrayBucket.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -63,4 +63,8 @@
                container.set(this);
        }

+       public void removeFrom(ObjectContainer container) {
+               container.delete(this);
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/support/api/Bucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/api/Bucket.java   2008-06-19 
20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/api/Bucket.java   2008-06-19 
22:57:31 UTC (rev 20503)
@@ -58,4 +58,10 @@
         */
        public void storeTo(ObjectContainer container);

+       /**
+        * Remove the bucket and everything under it from the database.
+        * @param container The database.
+        */
+       public void removeFrom(ObjectContainer container);
+
 }

Modified: branches/db4o/freenet/src/freenet/support/io/ArrayBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/ArrayBucket.java       
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/io/ArrayBucket.java       
2008-06-19 22:57:31 UTC (rev 20503)
@@ -190,6 +190,11 @@
        }

        public void storeTo(ObjectContainer container) {
+               container.set(data);
                container.set(this);
        }
+
+       public void removeFrom(ObjectContainer container) {
+               container.delete(data);
+       }
 }

Modified: branches/db4o/freenet/src/freenet/support/io/BucketChainBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/BucketChainBucket.java 
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/io/BucketChainBucket.java 
2008-06-19 22:57:31 UTC (rev 20503)
@@ -262,8 +262,20 @@
        }

        public void storeTo(ObjectContainer container) {
-               // I'm not sure it's safe to serialize the BucketFactory ...
-               throw new UnsupportedOperationException();
+               container.set(buckets);
+               container.set(this);
        }

+       public void removeFrom(ObjectContainer container) {
+               Bucket[] list;
+               synchronized(this) {
+                       list = (Bucket[]) buckets.toArray(new 
Bucket[buckets.size()]);
+                       buckets.clear();
+               }
+               for(int i=0;i<list.length;i++)
+                       list[i].removeFrom(container);
+               container.delete(buckets);
+               container.delete(this);
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/support/io/DelayedFreeBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/DelayedFreeBucket.java 
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/io/DelayedFreeBucket.java 
2008-06-19 22:57:31 UTC (rev 20503)
@@ -94,4 +94,9 @@
                container.set(this);
        }

+       public void removeFrom(ObjectContainer container) {
+               bucket.removeFrom(container);
+               container.delete(this);
+       }
+
 }
\ No newline at end of file

Modified: branches/db4o/freenet/src/freenet/support/io/FileBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/FileBucket.java        
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/io/FileBucket.java        
2008-06-19 22:57:31 UTC (rev 20503)
@@ -45,7 +45,11 @@
        public FileBucket(File file, boolean readOnly, boolean createFileOnly, 
boolean deleteOnFinalize, boolean deleteOnExit, boolean deleteOnFree) {
                super(file);
                if(file == null) throw new NullPointerException();
+               File origFile = file;
                file = file.getAbsoluteFile();
+               // Copy it so we can safely delete it.
+               if(origFile == file)
+                       file = new File(file.getPath());
                this.readOnly = readOnly;
                this.createFileOnly = createFileOnly;
                this.file = file;
@@ -102,4 +106,9 @@
        public void storeTo(ObjectContainer container) {
                container.set(this);
        }
+
+       public void removeFrom(ObjectContainer container) {
+               container.delete(file);
+               container.delete(this);
+       }
 }

Modified: branches/db4o/freenet/src/freenet/support/io/MultiReaderBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/MultiReaderBucket.java 
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/io/MultiReaderBucket.java 
2008-06-19 22:57:31 UTC (rev 20503)
@@ -129,6 +129,16 @@
                public void storeTo(ObjectContainer container) {
                        container.set(this);
                }
+
+               public void removeFrom(ObjectContainer container) {
+                       container.delete(this);
+                       synchronized(MultiReaderBucket.this) {
+                               if(!closed) return;
+                       }
+                       bucket.removeFrom(container);
+                       container.delete(readers);
+                       container.delete(MultiReaderBucket.this);
+               }

        }


Modified: branches/db4o/freenet/src/freenet/support/io/NullBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/NullBucket.java        
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/io/NullBucket.java        
2008-06-19 22:57:31 UTC (rev 20503)
@@ -76,5 +76,9 @@
        public void storeTo(ObjectContainer container) {
                container.set(this);
        }
+
+       public void removeFrom(ObjectContainer container) {
+               container.delete(this);
+       }
 }


Modified: 
branches/db4o/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
  2008-06-19 20:57:54 UTC (rev 20502)
+++ 
branches/db4o/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
  2008-06-19 22:57:31 UTC (rev 20503)
@@ -44,6 +44,8 @@
         * @param minSize The minimum padded size of the file (after it has 
been closed).
         * @param strongPRNG a strong prng we will key from.
         * @param weakPRNG a week prng we will padd from.
+        * Serialization: Note that it is not our responsibility to free the 
random number generators,
+        * but we WILL free the underlying bucket.
         * @throws UnsupportedCipherException 
         */
        public PaddedEphemerallyEncryptedBucket(Bucket bucket, int minSize, 
RandomSource strongPRNG, Random weakPRNG) {
@@ -371,4 +373,10 @@
                container.set(this);
        }

+       public void removeFrom(ObjectContainer container) {
+               bucket.removeFrom(container);
+               // The random is passed in and not our responsibility.
+               container.delete(this);
+       }
+
 }

Modified: 
branches/db4o/freenet/src/freenet/support/io/ReadOnlyFileSliceBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/ReadOnlyFileSliceBucket.java   
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/io/ReadOnlyFileSliceBucket.java   
2008-06-19 22:57:31 UTC (rev 20503)
@@ -25,7 +25,7 @@
        private final long length;

        public ReadOnlyFileSliceBucket(File f, long startAt, long length) {
-               this.file = f;
+               this.file = new File(f.getPath()); // copy so we can delete it
                this.startAt = startAt;
                this.length = length;
        }
@@ -150,4 +150,9 @@
        public void storeTo(ObjectContainer container) {
                container.set(this);
        }
+
+       public void removeFrom(ObjectContainer container) {
+               container.delete(file);
+               container.delete(this);
+       }
 }

Modified: branches/db4o/freenet/src/freenet/support/io/TempFileBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/TempFileBucket.java    
2008-06-19 20:57:54 UTC (rev 20502)
+++ branches/db4o/freenet/src/freenet/support/io/TempFileBucket.java    
2008-06-19 22:57:31 UTC (rev 20503)
@@ -89,4 +89,9 @@
                container.set(generator);
                container.set(this);
        }
+
+       public void removeFrom(ObjectContainer container) {
+               // filenameGenerator is a global, we don't need to worry about 
it.
+               container.delete(this);
+       }
 }


Reply via email to