Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

Work in progress: 1810x increase in extraction speed for solid archives. Fixes issue #21 #22

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions SevenZip/ArchiveExtractCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ internal sealed class ArchiveExtractCallback : CallbackBase, IArchiveExtractCall
private OutStreamWrapper _fileStream;
private bool _directoryStructure;
private int _currentIndex;
private Func<uint, OutStreamWrapper> _getStream;
const int MEMORY_PRESSURE = 64 * 1024 * 1024; //64mb seems to be the maximum value

#region Constructors
Expand All @@ -49,9 +50,10 @@ internal sealed class ArchiveExtractCallback : CallbackBase, IArchiveExtractCall
/// <param name="extractor">The owner of the callback</param>
/// <param name="actualIndexes">The list of actual indexes (solid archives support)</param>
/// <param name="directoryStructure">The value indicating whether to preserve directory structure of extracted files.</param>
public ArchiveExtractCallback(IInArchive archive, string directory, int filesCount, bool directoryStructure,
public ArchiveExtractCallback(Func<uint, OutStreamWrapper> getStream, IInArchive archive, string directory, int filesCount, bool directoryStructure,
List<uint> actualIndexes, SevenZipExtractor extractor)
{
this._getStream = getStream;
Init(archive, directory, filesCount, directoryStructure, actualIndexes, extractor);
}

Expand All @@ -65,10 +67,11 @@ public ArchiveExtractCallback(IInArchive archive, string directory, int filesCou
/// <param name="extractor">The owner of the callback</param>
/// <param name="actualIndexes">The list of actual indexes (solid archives support)</param>
/// <param name="directoryStructure">The value indicating whether to preserve directory structure of extracted files.</param>
public ArchiveExtractCallback(IInArchive archive, string directory, int filesCount, bool directoryStructure,
public ArchiveExtractCallback(Func<uint, OutStreamWrapper> getStream, IInArchive archive, string directory, int filesCount, bool directoryStructure,
List<uint> actualIndexes, string password, SevenZipExtractor extractor)
: base(password)
{
this._getStream = getStream;
Init(archive, directory, filesCount, directoryStructure, actualIndexes, extractor);
}

Expand All @@ -80,9 +83,10 @@ public ArchiveExtractCallback(IInArchive archive, string directory, int filesCou
/// <param name="filesCount">The archive files count</param>
/// <param name="fileIndex">The file index for the stream</param>
/// <param name="extractor">The owner of the callback</param>
public ArchiveExtractCallback(IInArchive archive, Stream stream, int filesCount, uint fileIndex,
public ArchiveExtractCallback(Func<uint, OutStreamWrapper> getStream, IInArchive archive, Stream stream, int filesCount, uint fileIndex,
SevenZipExtractor extractor)
{
this._getStream = getStream;
Init(archive, stream, filesCount, fileIndex, extractor);
}

Expand All @@ -95,10 +99,11 @@ public ArchiveExtractCallback(IInArchive archive, Stream stream, int filesCount,
/// <param name="fileIndex">The file index for the stream</param>
/// <param name="password">Password for the archive</param>
/// <param name="extractor">The owner of the callback</param>
public ArchiveExtractCallback(IInArchive archive, Stream stream, int filesCount, uint fileIndex, string password,
public ArchiveExtractCallback(Func<uint, OutStreamWrapper> getStream, IInArchive archive, Stream stream, int filesCount, uint fileIndex, string password,
SevenZipExtractor extractor)
: base(password)
{
this._getStream = getStream;
Init(archive, stream, filesCount, fileIndex, extractor);
}

Expand Down Expand Up @@ -130,7 +135,7 @@ private void CommonInit(IInArchive archive, int filesCount, SevenZipExtractor ex
_fakeStream = new FakeOutStreamWrapper();
_fakeStream.BytesWritten += IntEventArgsHandler;
_extractor = extractor;
GC.AddMemoryPressure(MEMORY_PRESSURE);
//GC.AddMemoryPressure(MEMORY_PRESSURE);
}
#endregion

Expand Down Expand Up @@ -382,14 +387,21 @@ public int GetStream(uint index, out ISequentialOutStream outStream, AskMode ask
{
#region Extraction to a stream

if (index == _fileIndex)
if (_getStream == null)
{
outStream = _fileStream;
_fileIndex = null;
if (index == _fileIndex)
{
outStream = _fileStream;
_fileIndex = null;
}
else
{
outStream = _fakeStream;
}
}
else
{
outStream = _fakeStream;
outStream = _getStream(_fileIndex.Value);
}

#endregion
Expand Down Expand Up @@ -424,7 +436,9 @@ public int GetStream(uint index, out ISequentialOutStream outStream, AskMode ask
return 0;
}

public void PrepareOperation(AskMode askExtractMode) { }
public Func<AskMode, AskMode> PrepareChecker = null;

public void PrepareOperation(AskMode askExtractMode) { if (PrepareChecker != null) askExtractMode = PrepareChecker(askExtractMode); }

/// <summary>
/// Called when the archive was extracted
Expand Down Expand Up @@ -458,8 +472,8 @@ public void SetOperationResult(OperationResult operationResult)
}
catch (ObjectDisposedException) { }
_fileStream = null;
GC.Collect();
GC.WaitForPendingFinalizers();
//GC.Collect();
//GC.WaitForPendingFinalizers();
}
var iea = new FileInfoEventArgs(
_extractor.ArchiveFileData[_currentIndex], PercentDoneEventArgs.ProducePercentDone(_doneRate));
Expand Down Expand Up @@ -492,7 +506,7 @@ public int CryptoGetTextPassword(out string password)

public void Dispose()
{
GC.RemoveMemoryPressure(MEMORY_PRESSURE);
//GC.RemoveMemoryPressure(MEMORY_PRESSURE);

if (_fileStream != null)
{
Expand Down
2 changes: 1 addition & 1 deletion SevenZip/ArchiveOpenCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public void Dispose()
_wrappers = null;
}

GC.SuppressFinalize(this);
//GC.SuppressFinalize(this);
}

#endregion
Expand Down
8 changes: 4 additions & 4 deletions SevenZip/ArchiveUpdateCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public float DictionarySize
set
{
_memoryPressure = (int)(value * 1024 * 1024);
GC.AddMemoryPressure(_memoryPressure);
//GC.AddMemoryPressure(_memoryPressure);
}
}

Expand Down Expand Up @@ -707,7 +707,7 @@ public void SetOperationResult(OperationResult operationResult)
_wrappersToDispose.Add(_fileStream);
}
_fileStream = null;
GC.Collect();
//GC.Collect();
// Issue #6987
//GC.WaitForPendingFinalizers();
}
Expand All @@ -731,7 +731,7 @@ public int CryptoGetTextPassword2(ref int passwordIsDefined, out string password

public void Dispose()
{
GC.RemoveMemoryPressure(_memoryPressure);
//GC.RemoveMemoryPressure(_memoryPressure);

if (_fileStream != null)
{
Expand All @@ -754,7 +754,7 @@ public void Dispose()
}
}

GC.SuppressFinalize(this);
//GC.SuppressFinalize(this);
}

#endregion
Expand Down
2 changes: 1 addition & 1 deletion SevenZip/COM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ public override string ToString()
/// <summary>
/// Stores file extraction modes.
/// </summary>
internal enum AskMode
public enum AskMode
{
/// <summary>
/// Extraction mode
Expand Down
2 changes: 1 addition & 1 deletion SevenZip/Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ internal virtual void ReleaseContext()
{
Context = null;
NeedsToBeRecreated = true;
GC.SuppressFinalize(this);
//GC.SuppressFinalize(this);
}

private delegate void EventHandlerDelegate<T>(EventHandler<T> handler, T e) where T : EventArgs;
Expand Down
3 changes: 3 additions & 0 deletions SevenZip/SevenZip.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.configuration" />
Expand Down
Loading