Author: toad
Date: 2008-06-13 19:21:11 +0000 (Fri, 13 Jun 2008)
New Revision: 20326

Added:
   branches/db4o/freenet/src/freenet/client/ArchiveHandlerImpl.java
Modified:
   branches/db4o/freenet/src/freenet/client/ArchiveManager.java
   branches/db4o/freenet/src/freenet/client/ArchiveStoreContext.java
   branches/db4o/freenet/src/freenet/client/async/SingleFileFetcher.java
Log:
Split ArchiveStoreContext and ArchiveHandlerImpl up. The latter is persistent 
and is a public interface, the former just contains the cached data for a 
single key.
Note that this also fixes a minor performance bug, because the force-refetch 
logic is now effectively on the client side, so one client asking for a refetch 
because of a binary blob doesn't cause the others to wait when they don't need 
to.

Added: branches/db4o/freenet/src/freenet/client/ArchiveHandlerImpl.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/ArchiveHandlerImpl.java            
                (rev 0)
+++ branches/db4o/freenet/src/freenet/client/ArchiveHandlerImpl.java    
2008-06-13 19:21:11 UTC (rev 20326)
@@ -0,0 +1,66 @@
+package freenet.client;
+
+import freenet.keys.FreenetURI;
+import freenet.support.Logger;
+import freenet.support.api.Bucket;
+
+public class ArchiveHandlerImpl implements ArchiveHandler {
+
+       private final FreenetURI key;
+       private final short archiveType;
+       private boolean forceRefetchArchive;
+       
+       ArchiveHandlerImpl(FreenetURI key, short archiveType, boolean 
forceRefetchArchive) {
+               this.key = key;
+               this.archiveType = archiveType;
+               this.forceRefetchArchive = forceRefetchArchive;
+       }
+       
+       public Bucket get(String internalName, ArchiveContext archiveContext,
+                       ClientMetadata dm, int recursionLevel,
+                       boolean dontEnterImplicitArchives, ArchiveManager 
manager)
+                       throws ArchiveFailureException, ArchiveRestartException,
+                       MetadataParseException, FetchException {
+               
+               // Do loop detection on the archive that we are about to fetch.
+               archiveContext.doLoopDetection(key);
+               
+               if(forceRefetchArchive) return null;
+               
+               Bucket data;
+               
+               // Fetch from cache
+               if(Logger.shouldLog(Logger.MINOR, this))
+                       Logger.minor(this, "Checking cache: "+key+ ' ' 
+internalName);
+               if((data = manager.getCached(key, internalName)) != null) {
+                       return data;
+               }       
+               
+               return null;
+       }
+
+       public Bucket getMetadata(ArchiveContext archiveContext, ClientMetadata 
dm,
+                       int recursionLevel, boolean dontEnterImplicitArchives,
+                       ArchiveManager manager) throws ArchiveFailureException,
+                       ArchiveRestartException, MetadataParseException, 
FetchException {
+               return get(".metadata", archiveContext, dm, recursionLevel, 
dontEnterImplicitArchives, manager);
+       }
+
+       public void extractToCache(Bucket bucket, ArchiveContext actx,
+                       String element, ArchiveExtractCallback callback,
+                       ArchiveManager manager) throws ArchiveFailureException,
+                       ArchiveRestartException {
+               forceRefetchArchive = false; // now we don't need to force 
refetch any more
+               ArchiveStoreContext ctx = manager.makeContext(key, archiveType, 
false);
+               manager.extractToCache(key, archiveType, bucket, actx, ctx, 
element, callback);
+       }
+
+       public short getArchiveType() {
+               return archiveType;
+       }
+
+       public FreenetURI getKey() {
+               return key;
+       }
+
+}

Modified: branches/db4o/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/ArchiveManager.java        
2008-06-13 18:42:01 UTC (rev 20325)
+++ branches/db4o/freenet/src/freenet/client/ArchiveManager.java        
2008-06-13 19:21:11 UTC (rev 20326)
@@ -90,7 +90,7 @@
        }

        /** Add an ArchiveHandler by key */
-       private synchronized void putCached(FreenetURI key, ArchiveHandler zip) 
{
+       private synchronized void putCached(FreenetURI key, ArchiveStoreContext 
zip) {
                if(logMINOR) Logger.minor(this, "Put cached AH for "+key+" : 
"+zip);
                archiveHandlers.push(key, zip);
                while(archiveHandlers.size() > maxArchiveHandlers)
@@ -98,9 +98,9 @@
        }

        /** Get an ArchiveHandler by key */
-       public ArchiveHandler getCached(FreenetURI key) {
+       ArchiveStoreContext getCached(FreenetURI key) {
                if(logMINOR) Logger.minor(this, "Get cached AH for "+key);
-               ArchiveHandler handler = (ArchiveHandler) 
archiveHandlers.get(key);
+               ArchiveStoreContext handler = (ArchiveStoreContext) 
archiveHandlers.get(key);
                if(handler == null) return null;
                archiveHandlers.push(key, handler);
                return handler;
@@ -115,17 +115,30 @@
         * @param archiveType The archive type, defined in Metadata.
         * @return An archive handler. 
         */
-       public synchronized ArchiveHandler makeHandler(FreenetURI key, short 
archiveType, boolean returnNullIfNotFound, boolean forceRefetchArchive) {
-               ArchiveHandler handler = null;
-               if(!forceRefetchArchive) handler = getCached(key);
+       synchronized ArchiveStoreContext makeContext(FreenetURI key, short 
archiveType, boolean returnNullIfNotFound) {
+               ArchiveStoreContext handler = null;
+               handler = getCached(key);
                if(handler != null) return handler;
                if(returnNullIfNotFound) return null;
-               handler = new ArchiveStoreContext(key, archiveType, 
forceRefetchArchive);
+               handler = new ArchiveStoreContext(key, archiveType);
                putCached(key, handler);
                return handler;
        }

        /**
+        * Create an archive handler. This does not need to know how to
+        * fetch the key, because the methods called later will ask.
+        * It will try to serve from cache, but if that fails, will
+        * re-fetch.
+        * @param key The key of the archive that we are extracting data from.
+        * @param archiveType The archive type, defined in Metadata.
+        * @return An archive handler. 
+        */
+       public ArchiveHandler makeHandler(FreenetURI key, short archiveType, 
boolean forceRefetch) {
+               return new ArchiveHandlerImpl(key, archiveType, forceRefetch);
+       }
+
+       /**
         * Get a cached, previously extracted, file from an archive.
         * @param key The key used to fetch the archive.
         * @param filename The name of the file within the archive.
@@ -183,7 +196,6 @@
                MutableBoolean gotElement = element != null ? new 
MutableBoolean() : null;

                if(logMINOR) Logger.minor(this, "Extracting "+key);
-               ctx.onExtract();
                ctx.removeAllCachedItems(this); // flush cache anyway
                long expectedSize = ctx.getLastSize();
                long archiveSize = data.size();

Modified: branches/db4o/freenet/src/freenet/client/ArchiveStoreContext.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/ArchiveStoreContext.java   
2008-06-13 18:42:01 UTC (rev 20325)
+++ branches/db4o/freenet/src/freenet/client/ArchiveStoreContext.java   
2008-06-13 19:21:11 UTC (rev 20326)
@@ -5,8 +5,6 @@

 import freenet.keys.FreenetURI;
 import freenet.support.DoublyLinkedListImpl;
-import freenet.support.Logger;
-import freenet.support.api.Bucket;

 /**
  * Tracks all files currently in the cache from a given key.
@@ -16,15 +14,11 @@
  * subject to the above.
  * 
  * Always take the lock on ArchiveStoreContext before the lock on 
ArchiveManager, NOT the other way around.
- * 
- * Not normally to be used directly by external packages, but public for
- * ArchiveManager.extractToCache. FIXME.
  */
-public class ArchiveStoreContext implements ArchiveHandler {
+public class ArchiveStoreContext {

        private FreenetURI key;
        private short archiveType;
-       private boolean forceRefetchArchive;
        /** Archive size */
        private long lastSize = -1;
        /** Archive hash */
@@ -35,47 +29,12 @@
         * the inner lock to avoid deadlocks. */
        private final DoublyLinkedListImpl myItems;

-       ArchiveStoreContext(FreenetURI key, short archiveType, boolean 
forceRefetchArchive) {
+       ArchiveStoreContext(FreenetURI key, short archiveType) {
                this.key = key;
                this.archiveType = archiveType;
                myItems = new DoublyLinkedListImpl();
-               this.forceRefetchArchive = forceRefetchArchive;
        }

-       /**
-        * Get the metadata for a given archive.
-        * @return A Bucket containing the metadata, in binary format, for the 
archive.
-        */
-       public Bucket getMetadata(ArchiveContext archiveContext, ClientMetadata 
dm, int recursionLevel, 
-                       boolean dontEnterImplicitArchives, ArchiveManager 
manager) throws ArchiveFailureException, ArchiveRestartException, 
MetadataParseException, FetchException {
-               return get(".metadata", archiveContext, dm, recursionLevel, 
dontEnterImplicitArchives, manager);
-       }
-
-       /**
-        * Fetch a file in an archive.
-        * @return A Bucket containing the data. This will not be freed until 
the 
-        * client is finished with it i.e. calls free() or it is finalized.
-        */
-       public Bucket get(String internalName, ArchiveContext archiveContext, 
ClientMetadata dm, int recursionLevel, 
-                       boolean dontEnterImplicitArchives, ArchiveManager 
manager) throws ArchiveFailureException, ArchiveRestartException, 
MetadataParseException, FetchException {
-
-               // Do loop detection on the archive that we are about to fetch.
-               archiveContext.doLoopDetection(key);
-               
-               if(forceRefetchArchive) return null;
-               
-               Bucket data;
-               
-               // Fetch from cache
-               if(Logger.shouldLog(Logger.MINOR, this))
-                       Logger.minor(this, "Checking cache: "+key+ ' ' 
+internalName);
-               if((data = manager.getCached(key, internalName)) != null) {
-                       return data;
-               }       
-               
-               return null;
-       }
-
        /** Returns the size of the archive last time we fetched it, or -1 */
        long getLastSize() {
                return lastSize;
@@ -136,12 +95,4 @@
                return key;
        }

-       public void extractToCache(Bucket bucket, ArchiveContext actx, String 
element, ArchiveExtractCallback callback, ArchiveManager manager) throws 
ArchiveFailureException, ArchiveRestartException {
-               manager.extractToCache(key, archiveType, bucket, actx, this, 
element, callback);
-       }
-
-       /** Called just before extracting this container to the cache */
-       void onExtract() {
-               forceRefetchArchive = false;
-       }
 }

Modified: branches/db4o/freenet/src/freenet/client/async/SingleFileFetcher.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/SingleFileFetcher.java       
2008-06-13 18:42:01 UTC (rev 20325)
+++ branches/db4o/freenet/src/freenet/client/async/SingleFileFetcher.java       
2008-06-13 19:21:11 UTC (rev 20326)
@@ -271,7 +271,7 @@
                                // It's more efficient to keep the existing ah 
if we can, and it is vital in
                                // the case of binary blobs.
                                if(ah == null || !ah.getKey().equals(thisKey))
-                                       ah = (ArchiveStoreContext) 
context.archiveManager.makeHandler(thisKey, metadata.getArchiveType(), false, 
+                                       ah = 
context.archiveManager.makeHandler(thisKey, metadata.getArchiveType(),
                                                        (parent instanceof 
ClientGetter ? ((ClientGetter)parent).collectingBinaryBlob() : false));
                                archiveMetadata = metadata;
                                // ah is set. This means we are currently 
handling an archive.


Reply via email to