On Sat, 13 Sep 2003, Mihai T. Lazarescu wrote:
>> > The 1-3Mb amount is arbitrary chosen in doing by hand, but gtkg
>> > can do automatically a much better job in backtracking in, say,
>> > 128kb increments, up to achieving a match. It would be nice
>> > to have such a feature, it very often saves several hundred
>> > Mb of downloads.
>>
>> I have a patch for this approach lying around somewhere. I could
>> dig it up and make it work with current CVS if people are
>> interested.
Ok, here is the patch. It shows I was really lazy when I wrote
this. Some things to note:
* I wasn't sure where the boundary was in the d download structure, so
I cleared one more byte to avoid off-by-one errors. May not be
needed.
* The 10.000 bytes number should be at least a define in the file and
perhaps even an option. It might also be useful to make it a power
of 2. From what I've seen while testing the patch it could be a bit
larger than 10.000 to be more effective. However, if it is too large
then one rogue file will have too much impact on downloading.
* The patch does not check for borderline cases (like the begin offset
being smaller than 0.
* This patch does not solve the case where we've downloaded a swarming
part which is not matching, because there is no 'continuity check'
at the end of a just-downloaded chunk (and because of this, this
patch did not work for me in the end).
* Having Tiger Tree Hash support is a much better solution than trying
to patch things up this way.
Hans
Index: downloads.c
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/downloads.c,v
retrieving revision 1.301
diff -u -r1.301 downloads.c
--- downloads.c 11 Sep 2003 19:32:54 -0000 1.301
+++ downloads.c 14 Sep 2003 07:27:42 -0000
@@ -3965,6 +3965,13 @@
download_bad_source(d);
download_stop(d, GTA_DL_ERROR, "Resuming data mismatch @ %lu",
d->skip - d->overlap_size);
+ printf("Resuming data mismatch on %s, clearing 10.000 bytes block from download\n", d->file_name);
+
+ off_t end = d->skip + 1;
+ off_t begin = end - 10000;
+ file_info_update(d, begin, end, DL_CHUNK_EMPTY);
+ printf("Cleared from %lu to %lu in %s\n", begin, end, d->file_name);
+
if (dbg > 3)
printf("%d overlapping bytes UNMATCHED at offset %d for \"%s\"\n",
d->overlap_size, d->skip - d->overlap_size, d->file_name);