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;