Author: toad
Date: 2005-10-27 17:49:43 +0000 (Thu, 27 Oct 2005)
New Revision: 7457

Added:
   trunk/freenet/src/freenet/client/ArchiveKey.java
   trunk/freenet/src/freenet/client/ArchiveStoreContext.java
   trunk/freenet/src/freenet/client/ArchiveStoreItem.java
   trunk/freenet/src/freenet/client/ErrorArchiveStoreItem.java
   trunk/freenet/src/freenet/client/RealArchiveStoreItem.java
   trunk/freenet/src/freenet/client/TempStoreElement.java
Removed:
   trunk/freenet/src/freenet/client/ArchiveElement.java
   trunk/freenet/src/freenet/client/ArchiveHandler.java
Modified:
   trunk/freenet/src/freenet/client/ArchiveContext.java
   trunk/freenet/src/freenet/client/ArchiveManager.java
   trunk/freenet/src/freenet/client/ArchiveRestartException.java
   trunk/freenet/src/freenet/client/FetchException.java
   trunk/freenet/src/freenet/client/MetadataParseException.java
Log:
Architecture changes re archives (relating to ArchiveHandler, now 
ArchiveStoreContext).
Break out some classes from ArchiveManager.

Modified: trunk/freenet/src/freenet/client/ArchiveContext.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveContext.java        2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/ArchiveContext.java        2005-10-27 
17:49:43 UTC (rev 7457)
@@ -2,7 +2,6 @@
 
 import java.util.HashSet;
 
-import freenet.keys.ClientKey;
 import freenet.keys.FreenetURI;
 
 /**
@@ -15,7 +14,11 @@
        HashSet soFar = new HashSet();
        int maxArchiveLevels;
        
-       public synchronized void doLoopDetection(ClientKey key) throws 
ArchiveFailureException {
+       /**
+        * Check for a loop.
+        * The URI provided is expected to be a reasonably unique identifier 
for the archive.
+        */
+       public synchronized void doLoopDetection(FreenetURI key) throws 
ArchiveFailureException {
                if(!soFar.add(key))
                        throw new ArchiveFailureException("Archive loop 
detected");
                if(soFar.size() > maxArchiveLevels)

Deleted: trunk/freenet/src/freenet/client/ArchiveElement.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveElement.java        2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/ArchiveElement.java        2005-10-27 
17:49:43 UTC (rev 7457)
@@ -1,50 +0,0 @@
-package freenet.client;
-
-import freenet.keys.ClientKey;
-import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-
-/**
- * An element in an archive. Does synchronization (on fetches, to avoid
- * having to do them twice), checks cache, does fetch, adds to cache.
- *
- * DO LOOP DETECTION!
- */
-public class ArchiveElement {
-
-       ArchiveElement(ArchiveManager manager, FreenetURI uri, String filename, 
short archiveType) {
-               this.manager = manager;
-               this.key = uri;
-               this.filename = filename;
-               this.archiveType = archiveType;
-       }
-       
-       final ArchiveManager manager;
-       final FreenetURI key;
-       final String filename;
-       final short archiveType;
-       
-       /**
-        * Fetch the element.
-        * If fetchContext is null, return null unless the data is cached.
-        * @throws ArchiveFailureException If there was a fatal error in the 
archive extraction. 
-        * @throws ArchiveRestartException If the archive changed, and 
therefore we need to
-        * restart the request.
-        * @throws FetchException If we could not fetch the key.
-        * @throws MetadataParseException If the key's metadata was invalid.
-        */
-       public Bucket get(FetcherContext fetchContext, ClientMetadata dm, int 
recursionLevel, ArchiveContext archiveContext) 
-       throws ArchiveFailureException, MetadataParseException, FetchException, 
ArchiveRestartException {
-               
-               synchronized(this) {
-                       // Synchronized during I/O to avoid doing it twice
-                       Bucket cached = manager.getCached(key, filename);
-                       if(cached != null) return cached;
-                       if(fetchContext == null) return null;
-                       Fetcher fetcher = new Fetcher(key, fetchContext, 
archiveContext);
-                       FetchResult result = fetcher.realRun(dm, 
recursionLevel, key);
-                       manager.extractToCache(key, archiveType, result.data, 
archiveContext);
-                       return manager.getCached(key, filename);
-               }
-       }
-}

Deleted: trunk/freenet/src/freenet/client/ArchiveHandler.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveHandler.java        2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/ArchiveHandler.java        2005-10-27 
17:49:43 UTC (rev 7457)
@@ -1,50 +0,0 @@
-package freenet.client;
-
-import freenet.keys.ClientKey;
-import freenet.keys.FreenetURI;
-import freenet.support.Bucket;
-
-/**
- * Handles a single archive for ZIP manifests.
- */
-class ArchiveHandler {
-
-       private ArchiveManager manager;
-       private FreenetURI key;
-       private short archiveType;
-       
-       public ArchiveHandler(ArchiveManager manager, FreenetURI key, short 
archiveType) {
-               this.manager = manager;
-               this.key = key;
-               this.archiveType = archiveType;
-       }
-
-       public void finalize() {
-               // Need to do anything here?
-       }
-
-       /**
-        * Get the metadata for this ZIP manifest, as a Bucket.
-        * @throws FetchException If the container could not be fetched.
-        * @throws MetadataParseException If there was an error parsing 
intermediary metadata.
-        */
-       public Bucket getMetadata(ArchiveContext archiveContext, FetcherContext 
fetchContext, ClientMetadata dm, int recursionLevel) throws 
ArchiveFailureException, ArchiveRestartException, MetadataParseException, 
FetchException {
-               return get(".metadata", archiveContext, fetchContext, dm, 
recursionLevel);
-       }
-
-       /**
-        * Get a file from this ZIP manifest, as a Bucket.
-        * If possible, read it from cache. If necessary, refetch the 
-        * container and extract it. If that fails, throw.
-        * @param inSplitZipManifest If true, indicates that the key points to 
a splitfile zip manifest,
-        * which means that we need to pass a flag to the fetcher to tell it to 
pretend it was a straight
-        * splitfile.
-        * @throws FetchException 
-        * @throws MetadataParseException 
-        */
-       public synchronized Bucket get(String internalName, ArchiveContext 
archiveContext, FetcherContext fetchContext, ClientMetadata dm, int 
recursionLevel) throws ArchiveFailureException, ArchiveRestartException, 
MetadataParseException, FetchException {
-               ArchiveElement element = 
-                       manager.makeElement(key, internalName, archiveType);
-               return element.get(fetchContext, dm, recursionLevel, 
archiveContext);
-       }
-}

Added: trunk/freenet/src/freenet/client/ArchiveKey.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveKey.java    2005-10-26 20:46:40 UTC 
(rev 7456)
+++ trunk/freenet/src/freenet/client/ArchiveKey.java    2005-10-27 17:49:43 UTC 
(rev 7457)
@@ -0,0 +1,25 @@
+package freenet.client;
+
+import freenet.keys.FreenetURI;
+
+public class ArchiveKey {
+
+       final FreenetURI key;
+       final String filename;
+       
+       public ArchiveKey(FreenetURI key2, String filename2) {
+               key = key2;
+               filename = filename2;
+       }
+
+       public boolean equals(Object o) {
+               if(this == o) return true;
+               if(!(o instanceof ArchiveKey)) return false;
+               ArchiveKey cmp = ((ArchiveKey)o);
+               return (cmp.key.equals(key) && cmp.filename.equals(filename));
+       }
+       
+       public int hashCode() {
+               return key.hashCode() ^ filename.hashCode();
+       }
+}
\ No newline at end of file

Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java        2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java        2005-10-27 
17:49:43 UTC (rev 7457)
@@ -4,6 +4,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -18,7 +20,6 @@
 import freenet.support.Logger;
 import freenet.support.PaddedEncryptedBucket;
 import freenet.support.io.FileBucket;
-import freenet.support.io.FileUtil;
 
 /**
  * Cache of recently decoded archives:
@@ -55,7 +56,7 @@
        public synchronized void putCached(FreenetURI key, ArchiveHandler zip) {
                archiveHandlers.push(key, zip);
                while(archiveHandlers.size() > maxArchiveHandlers)
-                       ((ArchiveHandler) archiveHandlers.popKey()).finalize();
+                       archiveHandlers.popKey(); // dump it
        }
 
        public ArchiveHandler getCached(FreenetURI key) {
@@ -71,25 +72,10 @@
        /** Maximum number of cached ArchiveElement's */
        final int maxCachedElements;
 
-       public ArchiveElement makeElement(FreenetURI uri, String internalName, 
short archiveType) {
-               MyKey key = new MyKey(uri, internalName);
-               synchronized(cachedElements) {
-                       ArchiveElement element;
-                       element = (ArchiveElement) cachedElements.get(key);
-                       if(element != null) {
-                               cachedElements.push(key, element);
-                               return element;
-                       }
-                       element = new ArchiveElement(this, uri, internalName, 
archiveType);
-                       cachedElements.push(key, element);
-                       return element;
-               }
-       }
-       
        // Data cache
        
        final long maxCachedData;
-       private long cachedData;
+       long cachedData;
        final File cacheDir;
        final LRUHashtable storedData;
 
@@ -104,13 +90,13 @@
        public synchronized ArchiveHandler makeHandler(FreenetURI key, short 
archiveType) {
                ArchiveHandler handler = getCached(key);
                if(handler != null) return handler;
-               handler = new ArchiveHandler(this, key, archiveType);
+               handler = new ArchiveStoreContext(this, key, archiveType);
                putCached(key, handler);
                return handler;
        }
 
        public synchronized Bucket getCached(FreenetURI key, String filename) {
-               MyKey k = new MyKey(key, filename);
+               ArchiveKey k = new ArchiveKey(key, filename);
                RealArchiveStoreItem ase = (RealArchiveStoreItem) 
storedData.get(k);
                // Promote to top of LRU
                storedData.push(k, ase);
@@ -118,106 +104,6 @@
                return ase.dataAsBucket();
        }
        
-       public class MyKey {
-               final FreenetURI key;
-               final String filename;
-               
-               public MyKey(FreenetURI key2, String filename2) {
-                       key = key2;
-                       filename = filename2;
-               }
-
-               public boolean equals(Object o) {
-                       if(this == o) return true;
-                       if(!(o instanceof MyKey)) return false;
-                       MyKey cmp = ((MyKey)o);
-                       return (cmp.key.equals(key) && 
cmp.filename.equals(filename));
-               }
-               
-               public int hashCode() {
-                       return key.hashCode() ^ filename.hashCode();
-               }
-       }
-
-       abstract class ArchiveStoreItem {
-               MyKey key;
-               
-               /** Expected to delete any stored data on disk, and decrement 
cachedData. */
-               public abstract void finalize();
-       }
-       
-       class RealArchiveStoreItem extends ArchiveStoreItem {
-               boolean finalized;
-               File myFilename;
-               PaddedEncryptedBucket bucket;
-               FileBucket underBucket;
-               
-               /**
-                * Create an ArchiveStoreElement from a TempStoreElement.
-                * @param key2 The key of the archive the file came from.
-                * @param realName The name of the file in that archive.
-                * @param temp The TempStoreElement currently storing the data.
-                */
-               RealArchiveStoreItem(FreenetURI key2, String realName, 
TempStoreElement temp) {
-                       this.key = new MyKey(key2, realName);
-                       this.finalized = false;
-                       this.bucket = temp.bucket;
-                       this.underBucket = temp.underBucket;
-                       underBucket.setReadOnly();
-                       cachedData += spaceUsed();
-               }
-
-               Bucket dataAsBucket() {
-                       return bucket;
-               }
-
-               long dataSize() {
-                       return bucket.size();
-               }
-               
-               long spaceUsed() {
-                       return FileUtil.estimateUsage(myFilename, 
underBucket.size());
-               }
-               
-               public synchronized void finalize() {
-                       if(finalized) return;
-                       long sz = spaceUsed();
-                       underBucket.finalize();
-                       finalized = true;
-                       cachedData -= sz;
-               }
-       }
-
-       class ErrorArchiveStoreItem extends ArchiveStoreItem {
-
-               String error;
-               
-               public ErrorArchiveStoreItem(FreenetURI key2, String name, 
String error) {
-                       key = new MyKey(key2, name);
-                       this.error = error;
-               }
-
-               public void finalize() {
-               }
-               
-       }
-       
-       class TempStoreElement {
-               TempStoreElement(File myFile, FileBucket fb, 
PaddedEncryptedBucket encryptedBucket) {
-                       this.myFilename = myFile;
-                       this.underBucket = fb;
-                       this.bucket = encryptedBucket;
-               }
-               
-               File myFilename;
-               PaddedEncryptedBucket bucket;
-               FileBucket underBucket;
-               
-               public void finalize() {
-                       underBucket.finalize();
-               }
-       }
-       
        /**
         * Extract data to cache.
         * @param key The key the data was fetched from.
@@ -226,7 +112,23 @@
         * @param archiveContext The context for the whole fetch process.
         * @throws ArchiveFailureException 
         */
-       public void extractToCache(FreenetURI key, short archiveType, Bucket 
data, ArchiveContext archiveContext) throws ArchiveFailureException {
+       public void extractToCache(FreenetURI key, short archiveType, Bucket 
data, ArchiveContext archiveContext, ArchiveStoreContext ctx) throws 
ArchiveFailureException {
+               ctx.removeAllCachedItems(); // flush cache anyway
+               long expectedSize = ctx.getLastSize();
+               long archiveSize = data.size();
+               /** Set if we need to throw a RestartedException rather than 
returning success,
+                * after we have unpacked everything.
+                */
+               boolean throwAtExit = false;
+               if(archiveSize != expectedSize) {
+                       throwAtExit = true;
+               }
+               byte[] expectedHash = ctx.getLastHash();
+               if(expectedHash != null) {
+                       byte[] realHash = BucketTools.hash(data);
+                       if(!Arrays.equals(realHash, expectedHash))
+                               throwAtExit = true;
+               }
                if(data.size() > maxArchiveSize)
                        throw new ArchiveFailureException("Archive too big");
                if(archiveType != Metadata.ARCHIVE_ZIP)
@@ -237,12 +139,18 @@
                        ZipInputStream zis = new ZipInputStream(is);
                        ZipEntry entry =  zis.getNextEntry();
                        byte[] buf = new byte[4096];
+                       HashSet names = new HashSet();
+                       boolean gotMetadata;
 outer:         while(entry != null) {
                                entry = zis.getNextEntry();
                                String name = entry.getName();
+                               if(names.contains(name)) {
+                                       Logger.error(this, "Duplicate key 
"+name+" in archive "+key);
+                                       continue;
+                               }
                                long size = entry.getSize();
                                if(size > maxArchivedFileSize) {
-                                       addErrorElement(key, name, "File too 
big: "+maxArchivedFileSize+" greater than current archived file size limit 
"+maxArchivedFileSize);
+                                       addErrorElement(ctx, key, name, "File 
too big: "+maxArchivedFileSize+" greater than current archived file size limit 
"+maxArchivedFileSize);
                                } else {
                                        // Read the element
                                        long realLen = 0;
@@ -254,37 +162,50 @@
                                                out.write(buf, 0, readBytes);
                                                readBytes += realLen;
                                                if(readBytes > 
maxArchivedFileSize) {
-                                                       addErrorElement(key, 
name, "File too big: "+maxArchivedFileSize+" greater than current archived file 
size limit "+maxArchivedFileSize);
+                                                       addErrorElement(ctx, 
key, name, "File too big: "+maxArchivedFileSize+" greater than current archived 
file size limit "+maxArchivedFileSize);
                                                        out.close();
                                                        temp.finalize();
                                                        continue outer;
                                                }
                                        }
                                        out.close();
-                                       addStoreElement(key, name, temp);
+                                       if(name.equals(".metadata"))
+                                               gotMetadata = true;
+                                       addStoreElement(ctx, key, name, temp);
+                                       names.add(name);
                                }
                        }
+                       // If no metadata, generate some
+                       if(!gotMetadata) {
+                               generateMetadata(ctx, key, names);
+                       }
+                       if(throwAtExit) throw new 
ArchiveRestartException("Archive changed on re-fetch");
                } catch (IOException e) {
                        throw new ArchiveFailureException("Error reading 
archive: "+e.getMessage(), e);
                } finally {
-                       if(is != null)
+                       if(is != null) {
                                try {
                                        is.close();
                                } catch (IOException e) {
                                        Logger.error(this, "Failed to close 
stream: "+e, e);
                                }
+                       }
                }
        }
 
-       private void addErrorElement(FreenetURI key, String name, String error) 
{
-               ErrorArchiveStoreItem element = new ErrorArchiveStoreItem(key, 
name, error);
+       private void addErrorElement(ArchiveStoreContext ctx, FreenetURI key, 
String name, String error) {
+               ErrorArchiveStoreItem element = new ErrorArchiveStoreItem(ctx, 
key, name, error);
                synchronized(storedData) {
                        storedData.push(element.key, element);
                }
        }
 
-       private void addStoreElement(FreenetURI key, String name, 
TempStoreElement temp) {
-               RealArchiveStoreItem element = new RealArchiveStoreItem(key, 
name, temp);
+       /**
+        * Add a store element.
+        * @return True if this was the metadata element.
+        */
+       private void addStoreElement(ArchiveStoreContext ctx, FreenetURI key, 
String name, TempStoreElement temp) {
+               RealArchiveStoreItem element = new RealArchiveStoreItem(this, 
ctx, key, name, temp);
                synchronized(storedData) {
                        storedData.push(element.key, element);
                        trimStoredData();

Modified: trunk/freenet/src/freenet/client/ArchiveRestartException.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveRestartException.java       
2005-10-26 20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/ArchiveRestartException.java       
2005-10-27 17:49:43 UTC (rev 7457)
@@ -7,8 +7,9 @@
  */
 public class ArchiveRestartException extends Exception {
 
+       private static final long serialVersionUID = -7670838856130773012L;
+
        public ArchiveRestartException(String msg) {
                super(msg);
        }
-
 }

Copied: trunk/freenet/src/freenet/client/ArchiveStoreContext.java (from rev 
7454, trunk/freenet/src/freenet/client/ArchiveHandler.java)
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveHandler.java        2005-10-26 
19:38:23 UTC (rev 7454)
+++ trunk/freenet/src/freenet/client/ArchiveStoreContext.java   2005-10-27 
17:49:43 UTC (rev 7457)
@@ -0,0 +1,66 @@
+package freenet.client;
+
+import freenet.keys.FreenetURI;
+import freenet.support.Bucket;
+
+/**
+ * Tracks all files currently in the cache from a given key.
+ * Keeps the last known hash of the key (if this changes in a fetch, we flush 
the cache, unpack,
+ * then throw an ArchiveRestartedException).
+ * Provides fetch methods for Fetcher, which try the cache and then fetch if 
necessary, 
+ * subject to the above.
+ */
+class ArchiveStoreContext implements ArchiveHandler {
+
+       private ArchiveManager manager;
+       private FreenetURI key;
+       private short archiveType;
+       
+       public ArchiveStoreContext(ArchiveManager manager, FreenetURI key, 
short archiveType) {
+               this.manager = manager;
+               this.key = key;
+               this.archiveType = archiveType;
+       }
+
+       public void finalize() {
+               // Need to do anything here?
+       }
+
+       /* (non-Javadoc)
+        * @see 
freenet.client.ArchiveHandler#getMetadata(freenet.client.ArchiveContext, 
freenet.client.FetcherContext, freenet.client.ClientMetadata, int)
+        */
+       public Bucket getMetadata(ArchiveContext archiveContext, FetcherContext 
fetchContext, ClientMetadata dm, int recursionLevel) throws 
ArchiveFailureException, ArchiveRestartException, MetadataParseException, 
FetchException {
+               return get(".metadata", archiveContext, fetchContext, dm, 
recursionLevel);
+       }
+
+       /* (non-Javadoc)
+        * @see freenet.client.ArchiveHandler#get(java.lang.String, 
freenet.client.ArchiveContext, freenet.client.FetcherContext, 
freenet.client.ClientMetadata, int)
+        */
+       public Bucket get(String internalName, ArchiveContext archiveContext, 
FetcherContext fetchContext, ClientMetadata dm, int recursionLevel) throws 
ArchiveFailureException, ArchiveRestartException, MetadataParseException, 
FetchException {
+
+               // Do loop detection on the archive that we are about to fetch.
+               archiveContext.doLoopDetection(key);
+               
+               Bucket data;
+
+               // Fetch from cache
+               if((data = manager.getCached(key, internalName)) != null) {
+                       return data;
+               }
+               
+               synchronized(this) {
+                       // Fetch from cache
+                       if((data = manager.getCached(key, internalName)) != 
null) {
+                               return data;
+                       }
+                       
+                       // Not in cache
+                       
+                       if(fetchContext == null) return null;
+                       Fetcher fetcher = new Fetcher(key, fetchContext, 
archiveContext);
+                       FetchResult result = fetcher.realRun(dm, 
recursionLevel, key);
+                       manager.extractToCache(key, archiveType, result.data, 
archiveContext);
+                       return manager.getCached(key, internalName);
+               }
+       }
+}

Added: trunk/freenet/src/freenet/client/ArchiveStoreItem.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveStoreItem.java      2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/ArchiveStoreItem.java      2005-10-27 
17:49:43 UTC (rev 7457)
@@ -0,0 +1,17 @@
+package freenet.client;
+
+/**
+ * Base class for items stored in the archive cache.
+ */
+abstract class ArchiveStoreItem {
+       final ArchiveKey key;
+       final ArchiveStoreContext context;
+       
+       ArchiveStoreItem(ArchiveKey key, ArchiveStoreContext context) {
+               this.key = key;
+               this.context = context;
+       }
+       
+       /** Expected to delete any stored data on disk, and decrement 
cachedData. */
+       public abstract void finalize();
+}

Added: trunk/freenet/src/freenet/client/ErrorArchiveStoreItem.java
===================================================================
--- trunk/freenet/src/freenet/client/ErrorArchiveStoreItem.java 2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/ErrorArchiveStoreItem.java 2005-10-27 
17:49:43 UTC (rev 7457)
@@ -0,0 +1,17 @@
+package freenet.client;
+
+import freenet.keys.FreenetURI;
+
+class ErrorArchiveStoreItem extends ArchiveStoreItem {
+
+       String error;
+       
+       public ErrorArchiveStoreItem(ArchiveStoreContext ctx, FreenetURI key2, 
String name, String error) {
+               super(new ArchiveKey(key2, name), ctx);
+               this.error = error;
+       }
+
+       public void finalize() {
+       }
+       
+}

Modified: trunk/freenet/src/freenet/client/FetchException.java
===================================================================
--- trunk/freenet/src/freenet/client/FetchException.java        2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/FetchException.java        2005-10-27 
17:49:43 UTC (rev 7457)
@@ -2,6 +2,8 @@
 
 public class FetchException extends Exception {
 
+       private static final long serialVersionUID = -1106716067841151962L;
+       
        final int mode;
        
        public FetchException(int m) {

Modified: trunk/freenet/src/freenet/client/MetadataParseException.java
===================================================================
--- trunk/freenet/src/freenet/client/MetadataParseException.java        
2005-10-26 20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/MetadataParseException.java        
2005-10-27 17:49:43 UTC (rev 7457)
@@ -5,6 +5,8 @@
 /** Thrown when Metadata parse fails. */
 public class MetadataParseException extends IOException {
 
+       private static final long serialVersionUID = 4910650977022715220L;
+
        public MetadataParseException(String string) {
                super(string);
        }

Added: trunk/freenet/src/freenet/client/RealArchiveStoreItem.java
===================================================================
--- trunk/freenet/src/freenet/client/RealArchiveStoreItem.java  2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/RealArchiveStoreItem.java  2005-10-27 
17:49:43 UTC (rev 7457)
@@ -0,0 +1,55 @@
+package freenet.client;
+
+import java.io.File;
+
+import freenet.keys.FreenetURI;
+import freenet.support.Bucket;
+import freenet.support.PaddedEncryptedBucket;
+import freenet.support.io.FileBucket;
+import freenet.support.io.FileUtil;
+
+class RealArchiveStoreItem extends ArchiveStoreItem {
+
+       private final ArchiveManager manager;
+       boolean finalized;
+       File myFilename;
+       PaddedEncryptedBucket bucket;
+       FileBucket underBucket;
+       
+       /**
+        * Create an ArchiveStoreElement from a TempStoreElement.
+        * @param key2 The key of the archive the file came from.
+        * @param realName The name of the file in that archive.
+        * @param temp The TempStoreElement currently storing the data.
+        * @param manager The parent ArchiveManager within which this item is 
stored.
+        */
+       RealArchiveStoreItem(ArchiveManager manager, ArchiveStoreContext ctx, 
FreenetURI key2, String realName, TempStoreElement temp) {
+               super(new ArchiveKey(key2, realName), ctx);
+               this.manager = manager;
+               this.finalized = false;
+               this.bucket = temp.bucket;
+               this.underBucket = temp.underBucket;
+               underBucket.setReadOnly();
+               this.manager.cachedData += spaceUsed();
+       }
+
+       Bucket dataAsBucket() {
+               return bucket;
+       }
+
+       long dataSize() {
+               return bucket.size();
+       }
+       
+       long spaceUsed() {
+               return FileUtil.estimateUsage(myFilename, underBucket.size());
+       }
+       
+       public synchronized void finalize() {
+               if(finalized) return;
+               long sz = spaceUsed();
+               underBucket.finalize();
+               finalized = true;
+               this.manager.cachedData -= sz;
+       }
+}
\ No newline at end of file

Added: trunk/freenet/src/freenet/client/TempStoreElement.java
===================================================================
--- trunk/freenet/src/freenet/client/TempStoreElement.java      2005-10-26 
20:46:40 UTC (rev 7456)
+++ trunk/freenet/src/freenet/client/TempStoreElement.java      2005-10-27 
17:49:43 UTC (rev 7457)
@@ -0,0 +1,25 @@
+/**
+ * 
+ */
+package freenet.client;
+
+import java.io.File;
+
+import freenet.support.PaddedEncryptedBucket;
+import freenet.support.io.FileBucket;
+
+class TempStoreElement {
+       TempStoreElement(File myFile, FileBucket fb, PaddedEncryptedBucket 
encryptedBucket) {
+               this.myFilename = myFile;
+               this.underBucket = fb;
+               this.bucket = encryptedBucket;
+       }
+       
+       File myFilename;
+       PaddedEncryptedBucket bucket;
+       FileBucket underBucket;
+       
+       public void finalize() {
+               underBucket.finalize();
+       }
+}
\ No newline at end of file

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to