Author: toad
Date: 2006-05-12 20:45:50 +0000 (Fri, 12 May 2006)
New Revision: 8686

Modified:
   trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
   trunk/freenet/src/freenet/client/async/USKChecker.java
   trunk/freenet/src/freenet/client/async/USKCheckerCallback.java
   trunk/freenet/src/freenet/client/async/USKFetcher.java
   trunk/freenet/src/freenet/client/async/USKInserter.java
   trunk/freenet/src/freenet/keys/ClientCHKBlock.java
   trunk/freenet/src/freenet/keys/ClientKeyBlock.java
   trunk/freenet/src/freenet/keys/ClientSSKBlock.java
   trunk/freenet/src/freenet/node/Version.java
Log:
704:
Don't insert another USK edition if the same content already exists in the last 
known edition.
Also fixes the current behaviour of an extra ARK being inserted, with the same 
data, every time the node restarts.

Modified: trunk/freenet/src/freenet/client/async/SingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleFileFetcher.java       
2006-05-12 20:00:13 UTC (rev 8685)
+++ trunk/freenet/src/freenet/client/async/SingleFileFetcher.java       
2006-05-12 20:45:50 UTC (rev 8686)
@@ -108,7 +108,7 @@
                // Extract data
                Bucket data;
                try {
-                       data = block.decode(ctx.bucketFactory, 
(int)(Math.min(ctx.maxOutputLength, Integer.MAX_VALUE)));
+                       data = block.decode(ctx.bucketFactory, 
(int)(Math.min(ctx.maxOutputLength, Integer.MAX_VALUE)), false);
                } catch (KeyDecodeException e1) {
                        onFailure(new 
FetchException(FetchException.BLOCK_DECODE_ERROR, e1.getMessage()));
                        return;

Modified: trunk/freenet/src/freenet/client/async/USKChecker.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKChecker.java      2006-05-12 
20:00:13 UTC (rev 8685)
+++ trunk/freenet/src/freenet/client/async/USKChecker.java      2006-05-12 
20:45:50 UTC (rev 8686)
@@ -3,6 +3,8 @@
 import freenet.client.FetcherContext;
 import freenet.keys.ClientKey;
 import freenet.keys.ClientKeyBlock;
+import freenet.keys.ClientSSKBlock;
+import freenet.keys.SSKBlock;
 import freenet.node.LowLevelGetException;
 import freenet.support.Logger;

@@ -21,7 +23,7 @@
        }

        public void onSuccess(ClientKeyBlock block, boolean fromStore) {
-               cb.onSuccess();
+               cb.onSuccess((ClientSSKBlock)block);
        }

        public void onFailure(LowLevelGetException e) {

Modified: trunk/freenet/src/freenet/client/async/USKCheckerCallback.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKCheckerCallback.java      
2006-05-12 20:00:13 UTC (rev 8685)
+++ trunk/freenet/src/freenet/client/async/USKCheckerCallback.java      
2006-05-12 20:45:50 UTC (rev 8686)
@@ -1,5 +1,8 @@
 package freenet.client.async;

+import freenet.keys.ClientSSKBlock;
+import freenet.keys.SSKBlock;
+
 /**
  * Callback for a USKChecker
  */
@@ -8,8 +11,9 @@
        /** Data Not Found */
        public void onDNF();

-       /** Successfully found the latest version of the key */
-       public void onSuccess();
+       /** Successfully found the latest version of the key 
+        * @param block */
+       public void onSuccess(ClientSSKBlock block);

        /** Error committed by author */
        public void onFatalAuthorError();

Modified: trunk/freenet/src/freenet/client/async/USKFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKFetcher.java      2006-05-12 
20:00:13 UTC (rev 8685)
+++ trunk/freenet/src/freenet/client/async/USKFetcher.java      2006-05-12 
20:45:50 UTC (rev 8686)
@@ -1,14 +1,18 @@
 package freenet.client.async;

+import java.io.IOException;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Vector;

 import freenet.client.FetcherContext;
+import freenet.keys.ClientSSKBlock;
 import freenet.keys.FreenetURI;
+import freenet.keys.KeyDecodeException;
 import freenet.keys.USK;
 import freenet.node.RequestStarter;
+import freenet.support.Bucket;
 import freenet.support.Logger;

 /**
@@ -74,6 +78,11 @@
        private boolean cancelled;

        final ClientRequester parent;
+
+       // We keep the data from the last (highest number) request.
+       private Bucket lastRequestData;
+       private short lastCompressionCodec;
+       private boolean lastWasMetadata;

        public synchronized boolean addCallback(USKFetcherCallback cb) {
                if(completed) return false; 
@@ -101,16 +110,16 @@
                        dnf = true;
                        USKFetcher.this.onDNF(this);
                }
-               public void onSuccess() {
+               public void onSuccess(ClientSSKBlock block) {
                        checker = null;
                        succeeded = true;
-                       USKFetcher.this.onSuccess(this, false);
+                       USKFetcher.this.onSuccess(this, false, block);
                }

                public void onFatalAuthorError() {
                        checker = null;
                        // Counts as success except it doesn't update
-                       USKFetcher.this.onSuccess(this, true);
+                       USKFetcher.this.onSuccess(this, true, null);
                }

                public void onNetworkError() {
@@ -257,7 +266,7 @@
                }
        }

-       void onSuccess(USKAttempt att, boolean dontUpdate) {
+       void onSuccess(USKAttempt att, boolean dontUpdate, ClientSSKBlock 
block) {
                LinkedList l = null;
                synchronized(this) {
                        if(completed || cancelled) return;
@@ -265,7 +274,19 @@
                        long curLatest = att.number;
                        if(!dontUpdate)
                                uskManager.update(origUSK, curLatest);
-                       curLatest = Math.max(uskManager.lookup(origUSK), 
curLatest);
+                       long lastEd = uskManager.lookup(origUSK);
+                       if(curLatest >= lastEd) {
+                               try {
+                                       this.lastRequestData = 
block.decode(ctx.bucketFactory, 1025 /* it's an SSK */, true);
+                                       this.lastCompressionCodec = 
block.getCompressionCodec();
+                                       this.lastWasMetadata = 
block.isMetadata();
+                               } catch (KeyDecodeException e) {
+                                       lastRequestData = null;
+                               } catch (IOException e) {
+                                       lastRequestData = null;
+                               }
+                       }
+                       curLatest = Math.max(lastEd, curLatest);
                        Logger.minor(this, "Latest: "+curLatest);
                        long addTo = curLatest + minFailures;
                        long addFrom = Math.max(lastAddedEdition + 1, curLatest 
+ 1);
@@ -395,4 +416,25 @@
                subscribers.remove(cb);
        }

+       public boolean hasLastData() {
+               return this.lastRequestData != null;
+       }
+
+       public boolean lastContentWasMetadata() {
+               return this.lastWasMetadata;
+       }
+
+       public short lastCompressionCodec() {
+               return this.lastCompressionCodec;
+       }
+
+       public Bucket getLastData() {
+               return this.lastRequestData;
+       }
+
+       public void freeLastData() {
+               lastRequestData.free();
+               lastRequestData = null;
+       }
+
 }

Modified: trunk/freenet/src/freenet/client/async/USKInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKInserter.java     2006-05-12 
20:00:13 UTC (rev 8685)
+++ trunk/freenet/src/freenet/client/async/USKInserter.java     2006-05-12 
20:45:50 UTC (rev 8686)
@@ -1,6 +1,8 @@
 package freenet.client.async;

+import java.io.IOException;
 import java.net.MalformedURLException;
+import java.util.Arrays;

 import freenet.client.InserterContext;
 import freenet.client.InserterException;
@@ -10,6 +12,7 @@
 import freenet.keys.InsertableUSK;
 import freenet.keys.USK;
 import freenet.support.Bucket;
+import freenet.support.BucketTools;
 import freenet.support.Logger;

 /**
@@ -73,6 +76,26 @@
        public void onFoundEdition(long l, USK key) {
                edition = Math.max(l, edition);
                consecutiveCollisions = 0;
+               if(fetcher.lastContentWasMetadata() == isMetadata && 
fetcher.hasLastData()
+                               && fetcher.lastCompressionCodec() == 
compressionCodec) {
+                       try {
+                               byte[] myData = BucketTools.toByteArray(data);
+                               byte[] hisData = 
BucketTools.toByteArray(fetcher.getLastData());
+                               fetcher.freeLastData();
+                               if(Arrays.equals(myData, hisData)) {
+                                       // Success!
+                                       cb.onEncode(pubUSK.copy(edition), this);
+                                       cb.onSuccess(this);
+                                       synchronized(this) {
+                                               finished = true;
+                                               sbi = null;
+                                       }
+                                       return;
+                               }
+                       } catch (IOException e) {
+                               Logger.error(this, "Could not decode: "+e, e);
+                       }
+               }
                fetcher = null;
                scheduleInsert();
        }

Modified: trunk/freenet/src/freenet/keys/ClientCHKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientCHKBlock.java  2006-05-12 20:00:13 UTC 
(rev 8685)
+++ trunk/freenet/src/freenet/keys/ClientCHKBlock.java  2006-05-12 20:45:50 UTC 
(rev 8686)
@@ -28,7 +28,7 @@

     public static final long MAX_COMPRESSED_DATA_LENGTH = NodeCHK.BLOCK_SIZE - 
4;
        final ClientCHK key;
-    
+       
     public String toString() {
         return super.toString()+",key="+key;
     }
@@ -59,7 +59,7 @@
      */
        public byte[] memoryDecode() throws CHKDecodeException {
                try {
-                       ArrayBucket a = (ArrayBucket) decode(new 
ArrayBucketFactory(), 32*1024);
+                       ArrayBucket a = (ArrayBucket) decode(new 
ArrayBucketFactory(), 32*1024, false);
                        return BucketTools.toByteArray(a); // FIXME
                } catch (IOException e) {
                        throw new Error(e);
@@ -71,7 +71,7 @@
      * @return the original data
      * @throws IOException If there is a bucket error.
      */
-    public Bucket decode(BucketFactory bf, int maxLength) throws 
CHKDecodeException, IOException {
+    public Bucket decode(BucketFactory bf, int maxLength, boolean 
dontCompress) throws CHKDecodeException, IOException {
         // Overall hash already verified, so first job is to decrypt.
         if(key.cryptoAlgorithm != Key.ALGO_AES_PCFB_256_SHA256)
             throw new UnsupportedOperationException();
@@ -120,7 +120,7 @@
         byte[] output = new byte[size];
         // No particular reason to check the padding, is there?
         System.arraycopy(dbuf, 0, output, 0, size);
-        return Key.decompress(key.isCompressed(), output, bf, 
Math.min(maxLength, MAX_LENGTH_BEFORE_COMPRESSION), key.compressionAlgorithm, 
false);
+        return Key.decompress(dontCompress ? false : key.isCompressed(), 
output, bf, Math.min(maxLength, MAX_LENGTH_BEFORE_COMPRESSION), 
key.compressionAlgorithm, false);
     }

     /**

Modified: trunk/freenet/src/freenet/keys/ClientKeyBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientKeyBlock.java  2006-05-12 20:00:13 UTC 
(rev 8685)
+++ trunk/freenet/src/freenet/keys/ClientKeyBlock.java  2006-05-12 20:45:50 UTC 
(rev 8686)
@@ -11,7 +11,7 @@
         * @param factory The BucketFactory to use to create the Bucket to 
return the data in.
         * @param maxLength The maximum size of the returned data in bytes.
         */
-       Bucket decode(BucketFactory factory, int maxLength) throws 
KeyDecodeException, IOException;
+       Bucket decode(BucketFactory factory, int maxLength, boolean 
dontDecompress) throws KeyDecodeException, IOException;

        /**
         * Does the block contain metadata? If not, it contains real data.

Modified: trunk/freenet/src/freenet/keys/ClientSSKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientSSKBlock.java  2006-05-12 20:00:13 UTC 
(rev 8685)
+++ trunk/freenet/src/freenet/keys/ClientSSKBlock.java  2006-05-12 20:45:50 UTC 
(rev 8686)
@@ -7,6 +7,7 @@
 import freenet.crypt.ciphers.Rijndael;
 import freenet.support.Bucket;
 import freenet.support.BucketFactory;
+import freenet.support.BucketTools;

 public class ClientSSKBlock extends SSKBlock implements ClientKeyBlock {

@@ -20,6 +21,9 @@
        private boolean decoded;
        /** Client-key. This contains the decryption key etc. */
        private ClientSSK key;
+
+       /** Compression algorithm from last time tried to decompress. */
+       private short compressionAlgorithm = -1;

        public ClientSSKBlock(byte[] data, byte[] headers, ClientSSK key, 
boolean dontVerify) throws SSKVerifyException {
                super(data, headers, (NodeSSK) key.getNodeKey(), dontVerify);
@@ -33,7 +37,7 @@
        /**
         * Decode the data.
         */
-       public Bucket decode(BucketFactory factory, int maxLength) throws 
KeyDecodeException, IOException {
+       public Bucket decode(BucketFactory factory, int maxLength, boolean 
dontDecompress) throws KeyDecodeException, IOException {
                /* We know the signature is valid because it is checked in the 
constructor. */
                /* We also know e(h(docname)) is valid */
                byte[] decryptedHeaders = new byte[ENCRYPTED_HEADERS_LENGTH];
@@ -75,10 +79,14 @@
                        System.arraycopy(dataOutput, 0, realDataOutput, 0, 
dataLength);
                        dataOutput = realDataOutput;
                }
-        short compressionAlgorithm = 
(short)(((decryptedHeaders[DATA_DECRYPT_KEY_LENGTH+2] & 0xff) << 8) + 
(decryptedHeaders[DATA_DECRYPT_KEY_LENGTH+3] & 0xff));
+        compressionAlgorithm = 
(short)(((decryptedHeaders[DATA_DECRYPT_KEY_LENGTH+2] & 0xff) << 8) + 
(decryptedHeaders[DATA_DECRYPT_KEY_LENGTH+3] & 0xff));
+        decoded = true;
+        
+        if(dontDecompress) {
+               return BucketTools.makeImmutableBucket(factory, dataOutput);
+        }

         Bucket b = Key.decompress(compressionAlgorithm >= 0, dataOutput, 
factory, Math.min(MAX_DECOMPRESSED_DATA_LENGTH, maxLength), 
compressionAlgorithm, true);
-        decoded = true;
         return b;
        }

@@ -92,4 +100,8 @@
                return key;
        }

+       public short getCompressionCodec() {
+               return compressionAlgorithm;
+       }
+
 }

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-05-12 20:00:13 UTC (rev 
8685)
+++ trunk/freenet/src/freenet/node/Version.java 2006-05-12 20:45:50 UTC (rev 
8686)
@@ -18,7 +18,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 703;
+       private static final int buildNumber = 704;

        /** Oldest build of Fred we will talk to */
        private static final int lastGoodBuild = 591;


Reply via email to