Author: toad
Date: 2009-04-15 12:11:52 +0000 (Wed, 15 Apr 2009)
New Revision: 26841
Modified:
trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
trunk/freenet/src/freenet/keys/ClientSSKBlock.java
Log:
Fix another db4o regression: Detect SSK collision with existing data.
Modified: trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
2009-04-15 12:04:48 UTC (rev 26840)
+++ trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
2009-04-15 12:11:52 UTC (rev 26841)
@@ -5,6 +5,7 @@
import java.io.IOException;
import java.net.MalformedURLException;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -18,14 +19,17 @@
import freenet.keys.ClientCHKBlock;
import freenet.keys.ClientKey;
import freenet.keys.ClientKeyBlock;
+import freenet.keys.ClientSSK;
+import freenet.keys.ClientSSKBlock;
import freenet.keys.FreenetURI;
import freenet.keys.InsertableClientSSK;
+import freenet.keys.KeyDecodeException;
import freenet.keys.KeyEncodeException;
+import freenet.keys.KeyVerifyException;
import freenet.keys.SSKEncodeException;
import freenet.node.KeysFetchingLocally;
import freenet.node.LowLevelPutException;
import freenet.node.NodeClientCore;
-import freenet.node.NullSendableRequestItem;
import freenet.node.RequestClient;
import freenet.node.RequestScheduler;
import freenet.node.SendableInsert;
@@ -461,10 +465,11 @@
public boolean send(NodeClientCore core,
RequestScheduler sched, final ClientContext context, ChosenBlock req) {
// Ignore keyNum, key, since we're only sending
one block.
+ ClientKeyBlock b;
+ ClientKey key = null;
+ if(logMINOR) Logger.minor(this, "Starting
request: "+SingleBlockInserter.this);
+ BlockItem block = (BlockItem) req.token;
try {
- if(logMINOR) Logger.minor(this,
"Starting request: "+SingleBlockInserter.this);
- BlockItem block = (BlockItem) req.token;
- ClientKeyBlock b;
try {
b = innerEncode(context.random,
block.uri, block.copyBucket, block.isMetadata, block.compressionCodec,
block.sourceLength);
} catch (CHKEncodeException e) {
@@ -477,21 +482,20 @@
throw new
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" +
e.getMessage(), e);
} catch (IOException e) {
throw new
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" +
e.getMessage(), e);
- } finally {
- block.copyBucket.free();
}
if (b==null) {
Logger.error(this, "Asked to
send empty block on "+SingleBlockInserter.this, new Exception("error"));
return false;
}
- final ClientKey key = b.getClientKey();
+ key = b.getClientKey();
+ final ClientKey k = key;
if(block.persistent) {
context.jobRunner.queue(new DBJob() {
public void run(ObjectContainer
container, ClientContext context) {
if(!container.ext().isStored(SingleBlockInserter.this)) return;
container.activate(SingleBlockInserter.this, 1);
- onEncode(key,
container, context);
+ onEncode(k, container,
context);
container.deactivate(SingleBlockInserter.this, 1);
}
@@ -500,7 +504,7 @@
context.mainExecutor.execute(new Runnable() {
public void run() {
- onEncode(key,
null, context);
+ onEncode(k,
null, context);
}
}, "Got URI");
@@ -508,9 +512,30 @@
}
core.realPut(b, req.cacheLocalRequests);
} catch (LowLevelPutException e) {
+ if(e.code ==
LowLevelPutException.COLLISION) {
+ // Collision
+ try {
+ ClientSSKBlock collided
= (ClientSSKBlock) core.node.fetch((ClientSSK)key, true);
+ byte[] data =
collided.memoryDecode(true);
+ byte[] inserting =
BucketTools.toByteArray(block.copyBucket);
+
if(collided.isMetadata() == block.isMetadata && collided.getCompressionCodec()
== block.compressionCodec && Arrays.equals(data, inserting)) {
+ if(logMINOR)
Logger.minor(this, "Collided with identical data: "+SingleBlockInserter.this);
+
req.onInsertSuccess(context);
+ return true;
+ }
+ } catch (KeyVerifyException e1)
{
+ Logger.error(this,
"Caught "+e1+" when checking collision!", e1);
+ } catch (KeyDecodeException e1)
{
+ Logger.error(this,
"Caught "+e1+" when checking collision!", e1);
+ } catch (IOException e1) {
+ Logger.error(this,
"Caught "+e1+" when checking collision!", e1);
+ }
+ }
req.onFailure(e, context);
if(logMINOR) Logger.minor(this,
"Request failed: "+SingleBlockInserter.this+" for "+e);
return true;
+ } finally {
+ block.copyBucket.free();
}
if(logMINOR) Logger.minor(this, "Request
succeeded: "+SingleBlockInserter.this);
req.onInsertSuccess(context);
Modified: trunk/freenet/src/freenet/keys/ClientSSKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientSSKBlock.java 2009-04-15 12:04:48 UTC
(rev 26840)
+++ trunk/freenet/src/freenet/keys/ClientSSKBlock.java 2009-04-15 12:11:52 UTC
(rev 26841)
@@ -110,13 +110,17 @@
return compressionAlgorithm;
}
+ public byte[] memoryDecode() throws KeyDecodeException {
+ return memoryDecode(false);
+ }
+
/**
* Decode into RAM, if short.
* @throws KeyDecodeException
*/
- public byte[] memoryDecode() throws KeyDecodeException {
+ public byte[] memoryDecode(boolean dontDecompress) throws
KeyDecodeException {
try {
- ArrayBucket a = (ArrayBucket) decode(new
ArrayBucketFactory(), 32*1024, false);
+ ArrayBucket a = (ArrayBucket) decode(new
ArrayBucketFactory(), 32*1024, dontDecompress);
return BucketTools.toByteArray(a); // FIXME
} catch (IOException e) {
throw new Error(e);
_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs