Fixed the header value for delta files so they are compatible with RDiff.
Fixed a bug where the delta file would be wrong in special cases. Added an optimization so SharpRSync now produces smaller delta files than librsync for some cases (and the same size for all others). Added comments to identify optimizations. git-svn-id: https://duplicati.googlecode.com/svn/trunk@49 59da171f-624f-0410-aa54-27559c288bec
This commit is contained in:
@@ -125,7 +125,7 @@ namespace Duplicati.CommandLine
|
||||
string relpath = s.Substring(f1.Length);
|
||||
string target = System.IO.Path.Combine(f2, relpath);
|
||||
if (!files2.Contains(target))
|
||||
Console.WriteLine("Missing folder: " + relpath);
|
||||
Console.WriteLine("Missing file: " + relpath);
|
||||
else
|
||||
{
|
||||
files2.Remove(target);
|
||||
|
||||
@@ -85,6 +85,7 @@ namespace Duplicati.Main
|
||||
long totalmax = options.ContainsKey("totalsize") ? Core.Sizeparser.ParseSize(options["totalsize"], "mb") : long.MaxValue;
|
||||
totalmax = Math.Max(volumesize, totalmax);
|
||||
|
||||
//TODO: Just pass the dir list to the zip, don't stress the disk
|
||||
using (new Logging.Timer("Creating folders for signature file"))
|
||||
dir.CreateFolders();
|
||||
|
||||
|
||||
@@ -174,6 +174,7 @@ namespace Duplicati.Main.RSync
|
||||
string s = m_unproccesed[next];
|
||||
m_unproccesed.RemoveAt(next);
|
||||
|
||||
//TODO: Add the delta to zip, don't use temp file
|
||||
if (ProccessDiff(s))
|
||||
totalSize = AddFileToCompression(s, c);
|
||||
|
||||
@@ -456,9 +457,19 @@ namespace Duplicati.Main.RSync
|
||||
//string source = System.IO.Path.Combine(sourcefolder, relpath)
|
||||
|
||||
string tempfile = System.IO.Path.GetTempFileName();
|
||||
SharpRSync.Interface.PatchFile(target, s, tempfile);
|
||||
System.IO.File.Delete(target);
|
||||
System.IO.File.Move(tempfile, target);
|
||||
try
|
||||
{
|
||||
SharpRSync.Interface.PatchFile(target, s, tempfile);
|
||||
System.IO.File.Delete(target);
|
||||
System.IO.File.Move(tempfile, target);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log.WriteMessage("Failed to restore file " + relpath, Duplicati.Logging.LogMessageType.Error, ex);
|
||||
System.IO.File.Delete(target);
|
||||
System.IO.File.Delete(tempfile);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ namespace Duplicati.SharpRSync
|
||||
long unmatched = 0;
|
||||
long matched = 0;
|
||||
long matched_offset = 0;
|
||||
long next_match_key = 0;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -168,6 +169,17 @@ namespace Duplicati.SharpRSync
|
||||
tmp = md4buffer;
|
||||
}
|
||||
|
||||
//If there are two identical blocks, we try the next first as that produces the smallest delta file
|
||||
//NOTE: RDiff does not seem to have this optimization
|
||||
if (matched > 0 && strong[0].Key != next_match_key)
|
||||
foreach (KeyValuePair<int, byte[]> k in strong)
|
||||
if (k.Key == next_match_key)
|
||||
{
|
||||
strong.Remove(k);
|
||||
strong.Insert(0, k);
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<int, byte[]> k in strong)
|
||||
{
|
||||
if (!md4.CanReuseTransform)
|
||||
@@ -192,8 +204,18 @@ namespace Duplicati.SharpRSync
|
||||
buffer.DropTail(unmatched);
|
||||
unmatched = 0;
|
||||
}
|
||||
|
||||
if (matched == 0)
|
||||
matched_offset = k.Key * m_checksum.BlockLength;
|
||||
else if (k.Key != next_match_key)
|
||||
{
|
||||
WriteCopy(matched_offset, matched, output);
|
||||
matched = 0;
|
||||
matched_offset = k.Key * m_checksum.BlockLength;
|
||||
}
|
||||
|
||||
next_match_key = k.Key + 1;
|
||||
|
||||
|
||||
matched += buffer.Count;
|
||||
foundMatch = true;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Duplicati.SharpRSync
|
||||
/// <summary>
|
||||
/// The magic header value in an RDiff delta file
|
||||
/// </summary>
|
||||
public static readonly byte[] DELTA_MAGIC = { (byte)'r', (byte)'s', 0x1, (byte)'6' };
|
||||
public static readonly byte[] DELTA_MAGIC = { (byte)'r', (byte)'s', 0x2, (byte)'6' };
|
||||
|
||||
/// <summary>
|
||||
/// Denotes the end of a delta stream.
|
||||
|
||||
Reference in New Issue
Block a user