Skip to content

Commit

Permalink
Fix disposing issue for patch streams
Browse files Browse the repository at this point in the history
  • Loading branch information
neon-nyan committed Jul 23, 2023
1 parent e64d6dd commit 3bc996a
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 65 deletions.
2 changes: 1 addition & 1 deletion Hi3Helper.SharpHDiffPatch/HDiffPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ public HDiffPatch()
public void Initialize(string diff)
{
diffPath = diff;
diffStream = new FileStream(diff, FileMode.Open, FileAccess.Read);

using (diffStream = new FileStream(diff, FileMode.Open, FileAccess.Read))
using (BinaryReader sr = new BinaryReader(diffStream))
{
isPatchDir = Header.TryParseHeaderInfo(sr, diffPath, out TDirDiffInfo _tDirDiffInfo, out CompressedHDiffInfo _singleHDiffInfo, out HDiffHeaderInfo _headerInfo);
Expand Down
5 changes: 2 additions & 3 deletions Hi3Helper.SharpHDiffPatch/PatchCore/PatchCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@ internal class PatchCore
private static long newPosBack;
private static long coverCount;

internal static Stream GetBufferStreamFromOffset(CompressionMode compMode, Func<Stream> sourceStreamFunc,
internal static Stream GetBufferStreamFromOffset(CompressionMode compMode, Stream sourceStream,
long start, long length, long compLength, out long outLength, bool isBuffered)
{
Stream sourceStream = sourceStreamFunc();
sourceStream.Position = start;

GetDecompressStreamPlugin(compMode, sourceStream, out Stream returnStream, length, compLength, out outLength);
Expand All @@ -56,7 +55,7 @@ internal static Stream GetBufferStreamFromOffset(CompressionMode compMode, Func<
Console.Write($"Caching stream from offset: {start} with length: {(compLength > 0 ? compLength : length)}...");
MemoryStream stream = CreateAndCopyToMemoryStream(returnStream);
stream.Position = 0;
returnStream.Dispose();
returnStream?.Dispose();
Console.WriteLine($" Done! {stream.Length} bytes written");
return stream;
}
Expand Down
111 changes: 66 additions & 45 deletions Hi3Helper.SharpHDiffPatch/PatchDir/PatchDir.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,49 +47,51 @@ public void Patch(string input, string output, bool useBufferedPatch)
basePathOutput = output;
this.useBufferedPatch = useBufferedPatch;

FileStream patchStream = spawnPatchStream();
patchStream.Position = (long)hdiffHeaderInfo.headDataOffset + padding;
PatchCore.GetDecompressStreamPlugin(hdiffHeaderInfo.compMode, patchStream, out Stream decompHeadStream,
(long)hdiffHeaderInfo.headDataSize, (long)hdiffHeaderInfo.headDataCompressedSize - padding, out _);

using (BinaryReader patchReader = new BinaryReader(patchStream))
using (BinaryReader patchDecompReader = new BinaryReader(decompHeadStream))
using (patchDecompReader)
using (FileStream patchStream = spawnPatchStream())
{
TDirPatcher dirData = InitializeDirPatcher(patchDecompReader);
patchStream.Position = (long)hdiffHeaderInfo.headDataOffset + padding;
PatchCore.GetDecompressStreamPlugin(hdiffHeaderInfo.compMode, patchStream, out Stream decompHeadStream,
(long)hdiffHeaderInfo.headDataSize, (long)hdiffHeaderInfo.headDataCompressedSize - padding, out _);

HDiffPatch.currentSizePatched = 0;
HDiffPatch.totalSizePatched = GetSameFileSize(dirData) + GetNewPatchedFileSize(dirData);
using (BinaryReader patchReader = new BinaryReader(patchStream))
using (BinaryReader patchDecompReader = new BinaryReader(decompHeadStream))
using (patchDecompReader)
{
TDirPatcher dirData = InitializeDirPatcher(patchDecompReader);

FileStream[] mergedOldStream = GetRefOldStreams(dirData).ToArray();
NewFileCombinedStreamStruct[] mergedNewStream = GetRefNewStreams(dirData).ToArray();
HDiffPatch.currentSizePatched = 0;
HDiffPatch.totalSizePatched = GetSameFileSize(dirData) + GetNewPatchedFileSize(dirData);

patchStream.Position = (long)hdiffHeaderInfo.hdiffDataOffset;
_ = Header.TryParseHeaderInfo(patchReader, "", out _, out dirDiffInfo.hdiffinfo, out _);
padding = hdiffHeaderInfo.compMode == CompressionMode.zlib ? 1 : 0;
FileStream[] mergedOldStream = GetRefOldStreams(dirData).ToArray();
NewFileCombinedStreamStruct[] mergedNewStream = GetRefNewStreams(dirData).ToArray();

Stopwatch stopwatch = Stopwatch.StartNew();
using (Stream newStream = new CombinedStream(mergedNewStream))
using (Stream oldStream = new CombinedStream(mergedOldStream))
{
long oldFileSize = GetOldFileSize(dirData);
TryCheckMatchOldSize(oldStream, oldFileSize);
patchStream.Position = (long)hdiffHeaderInfo.hdiffDataOffset;
_ = Header.TryParseHeaderInfo(patchReader, "", out _, out dirDiffInfo.hdiffinfo, out _);
padding = hdiffHeaderInfo.compMode == CompressionMode.zlib ? 1 : 0;

long lastPos = patchStream.Position;
StartPatchRoutine(oldStream, newStream, dirDiffInfo.hdiffinfo.newDataSize, lastPos);
}
Stopwatch stopwatch = Stopwatch.StartNew();
using (Stream newStream = new CombinedStream(mergedNewStream))
using (Stream oldStream = new CombinedStream(mergedOldStream))
{
long oldFileSize = GetOldFileSize(dirData);
TryCheckMatchOldSize(oldStream, oldFileSize);

TimeSpan timeTaken = stopwatch.Elapsed;
Console.WriteLine($"Patch has been finished in {timeTaken.TotalSeconds} seconds ({timeTaken.TotalMilliseconds} ms)");
long lastPos = patchStream.Position;
StartPatchRoutine(oldStream, newStream, dirDiffInfo.hdiffinfo.newDataSize, lastPos);
}

TimeSpan timeTaken = stopwatch.Elapsed;
Console.WriteLine($"Patch has been finished in {timeTaken.TotalSeconds} seconds ({timeTaken.TotalMilliseconds} ms)");

stopwatch.Restart();
stopwatch.Restart();

Console.Write("Start copying similar data... ");
CopyOldSimilarToNewFiles(dirData);
Console.WriteLine("Done!");
Console.Write("Start copying similar data... ");
CopyOldSimilarToNewFiles(dirData);
Console.WriteLine("Done!");

timeTaken = stopwatch.Elapsed;
Console.WriteLine($"Copying similar data has been finished in {timeTaken.TotalSeconds} seconds ({timeTaken.TotalMilliseconds} ms)");
timeTaken = stopwatch.Elapsed;
Console.WriteLine($"Copying similar data has been finished in {timeTaken.TotalSeconds} seconds ({timeTaken.TotalMilliseconds} ms)");
}
}
}

Expand Down Expand Up @@ -136,23 +138,42 @@ private void StartPatchRoutine(Stream inputStream, Stream outputStream, ulong ne
{
bool isCompressed = dirDiffInfo.hdiffinfo.compMode != CompressionMode.nocomp;
Stream[] clips = new Stream[4];
Stream[] sourceClips = new Stream[4]
{
spawnPatchStream(),
spawnPatchStream(),
spawnPatchStream(),
spawnPatchStream()
};

clips[0] = PatchCore.GetBufferStreamFromOffset(dirDiffInfo.hdiffinfo.compMode, spawnPatchStream, offset,
(long)dirDiffInfo.hdiffinfo.headInfo.cover_buf_size, (long)dirDiffInfo.hdiffinfo.headInfo.compress_cover_buf_size, out long nextLength, this.useBufferedPatch);
try
{
clips[0] = PatchCore.GetBufferStreamFromOffset(dirDiffInfo.hdiffinfo.compMode, sourceClips[0], offset,
(long)dirDiffInfo.hdiffinfo.headInfo.cover_buf_size, (long)dirDiffInfo.hdiffinfo.headInfo.compress_cover_buf_size, out long nextLength, this.useBufferedPatch);

offset += nextLength;
clips[1] = PatchCore.GetBufferStreamFromOffset(dirDiffInfo.hdiffinfo.compMode, spawnPatchStream, offset,
(long)dirDiffInfo.hdiffinfo.headInfo.rle_ctrlBuf_size, (long)dirDiffInfo.hdiffinfo.headInfo.compress_rle_ctrlBuf_size, out nextLength, this.useBufferedPatch);
offset += nextLength;
clips[1] = PatchCore.GetBufferStreamFromOffset(dirDiffInfo.hdiffinfo.compMode, sourceClips[1], offset,
(long)dirDiffInfo.hdiffinfo.headInfo.rle_ctrlBuf_size, (long)dirDiffInfo.hdiffinfo.headInfo.compress_rle_ctrlBuf_size, out nextLength, this.useBufferedPatch);

offset += nextLength;
clips[2] = PatchCore.GetBufferStreamFromOffset(dirDiffInfo.hdiffinfo.compMode, spawnPatchStream, offset,
(long)dirDiffInfo.hdiffinfo.headInfo.rle_codeBuf_size, (long)dirDiffInfo.hdiffinfo.headInfo.compress_rle_codeBuf_size, out nextLength, this.useBufferedPatch);
offset += nextLength;
clips[2] = PatchCore.GetBufferStreamFromOffset(dirDiffInfo.hdiffinfo.compMode, sourceClips[2], offset,
(long)dirDiffInfo.hdiffinfo.headInfo.rle_codeBuf_size, (long)dirDiffInfo.hdiffinfo.headInfo.compress_rle_codeBuf_size, out nextLength, this.useBufferedPatch);

offset += nextLength;
clips[3] = PatchCore.GetBufferStreamFromOffset(dirDiffInfo.hdiffinfo.compMode, spawnPatchStream, offset,
(long)dirDiffInfo.hdiffinfo.headInfo.newDataDiff_size, (long)dirDiffInfo.hdiffinfo.headInfo.compress_newDataDiff_size, out _, false);
offset += nextLength;
clips[3] = PatchCore.GetBufferStreamFromOffset(dirDiffInfo.hdiffinfo.compMode, sourceClips[3], offset,
(long)dirDiffInfo.hdiffinfo.headInfo.newDataDiff_size, (long)dirDiffInfo.hdiffinfo.headInfo.compress_newDataDiff_size, out _, false);

PatchCore.UncoverBufferClipsStream(clips, inputStream, outputStream, dirDiffInfo.hdiffinfo, newDataSize);
PatchCore.UncoverBufferClipsStream(clips, inputStream, outputStream, dirDiffInfo.hdiffinfo, newDataSize);
}
catch
{
throw;
}
finally
{
foreach (Stream clip in clips) clip?.Dispose();
foreach (Stream clip in sourceClips) clip?.Dispose();
}
}

private void TryCheckMatchOldSize(Stream inputStream, long oldFileSize)
Expand Down
51 changes: 35 additions & 16 deletions Hi3Helper.SharpHDiffPatch/PatchSingle/PatchSingle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,30 +65,49 @@ private void StartPatchRoutine(Stream inputStream, Stream outputStream)

Stopwatch stopwatch = Stopwatch.StartNew();
Stream[] clips = new Stream[4];
Stream[] sourceClips = new Stream[4]
{
spawnPatchStream(),
spawnPatchStream(),
spawnPatchStream(),
spawnPatchStream()
};

int padding = hDiffInfo.compMode == CompressionMode.zlib ? 1 : 0;

long offset = (long)hDiffInfo.headInfo.headEndPos;
clips[0] = PatchCore.GetBufferStreamFromOffset(hDiffInfo.compMode, spawnPatchStream, offset + padding,
(long)hDiffInfo.headInfo.cover_buf_size, (long)hDiffInfo.headInfo.compress_cover_buf_size, out long nextLength, this.isUseBufferedPatch);
try
{
long offset = (long)hDiffInfo.headInfo.headEndPos;
clips[0] = PatchCore.GetBufferStreamFromOffset(hDiffInfo.compMode, sourceClips[0], offset + padding,
(long)hDiffInfo.headInfo.cover_buf_size, (long)hDiffInfo.headInfo.compress_cover_buf_size, out long nextLength, this.isUseBufferedPatch);

offset += nextLength;
clips[1] = PatchCore.GetBufferStreamFromOffset(hDiffInfo.compMode, spawnPatchStream, offset + padding,
(long)hDiffInfo.headInfo.rle_ctrlBuf_size, (long)hDiffInfo.headInfo.compress_rle_ctrlBuf_size, out nextLength, this.isUseBufferedPatch);
offset += nextLength;
clips[1] = PatchCore.GetBufferStreamFromOffset(hDiffInfo.compMode, sourceClips[1], offset + padding,
(long)hDiffInfo.headInfo.rle_ctrlBuf_size, (long)hDiffInfo.headInfo.compress_rle_ctrlBuf_size, out nextLength, this.isUseBufferedPatch);

offset += nextLength;
clips[2] = PatchCore.GetBufferStreamFromOffset(hDiffInfo.compMode, spawnPatchStream, offset + padding,
(long)hDiffInfo.headInfo.rle_codeBuf_size, (long)hDiffInfo.headInfo.compress_rle_codeBuf_size, out nextLength, this.isUseBufferedPatch);
offset += nextLength;
clips[2] = PatchCore.GetBufferStreamFromOffset(hDiffInfo.compMode, sourceClips[2], offset + padding,
(long)hDiffInfo.headInfo.rle_codeBuf_size, (long)hDiffInfo.headInfo.compress_rle_codeBuf_size, out nextLength, this.isUseBufferedPatch);

offset += nextLength;
clips[3] = PatchCore.GetBufferStreamFromOffset(hDiffInfo.compMode, spawnPatchStream, offset + padding,
(long)hDiffInfo.headInfo.newDataDiff_size, (long)hDiffInfo.headInfo.compress_newDataDiff_size - padding, out _, false);
offset += nextLength;
clips[3] = PatchCore.GetBufferStreamFromOffset(hDiffInfo.compMode, sourceClips[3], offset + padding,
(long)hDiffInfo.headInfo.newDataDiff_size, (long)hDiffInfo.headInfo.compress_newDataDiff_size - padding, out _, false);

PatchCore.UncoverBufferClipsStream(clips, inputStream, outputStream, hDiffInfo);
stopwatch.Stop();
PatchCore.UncoverBufferClipsStream(clips, inputStream, outputStream, hDiffInfo);

TimeSpan timeTaken = stopwatch.Elapsed;
Console.WriteLine($"Patch has been finished in {timeTaken.TotalSeconds} seconds ({timeTaken.TotalMilliseconds} ms)");
TimeSpan timeTaken = stopwatch.Elapsed;
Console.WriteLine($"Patch has been finished in {timeTaken.TotalSeconds} seconds ({timeTaken.TotalMilliseconds} ms)");
}
catch
{
throw;
}
finally
{
stopwatch.Stop();
foreach (Stream clip in clips) clip?.Dispose();
foreach (Stream clip in sourceClips) clip?.Dispose();
}
}
}
}

0 comments on commit 3bc996a

Please sign in to comment.