Skip to content

Commit

Permalink
Merge pull request #485 from adamhathcock/issue-256
Browse files Browse the repository at this point in the history
Create and using PauseEntryRebuilding for adding large numbers of ent…
  • Loading branch information
adamhathcock committed Jan 9, 2021
2 parents 5879999 + 669e40d commit 6e42e00
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
26 changes: 26 additions & 0 deletions src/SharpCompress/Archives/AbstractWritableArchive.cs
Expand Up @@ -12,11 +12,28 @@ public abstract class AbstractWritableArchive<TEntry, TVolume> : AbstractArchive
where TEntry : IArchiveEntry
where TVolume : IVolume
{
private class RebuildPauseDisposable: IDisposable
{
private readonly AbstractWritableArchive<TEntry, TVolume> archive;

public RebuildPauseDisposable(AbstractWritableArchive<TEntry, TVolume> archive)
{
this.archive = archive;
archive.pauseRebuilding = true;
}

public void Dispose()
{
archive.pauseRebuilding = false;
archive.RebuildModifiedCollection();
}
}
private readonly List<TEntry> newEntries = new List<TEntry>();
private readonly List<TEntry> removedEntries = new List<TEntry>();

private readonly List<TEntry> modifiedEntries = new List<TEntry>();
private bool hasModifications;
private bool pauseRebuilding;

internal AbstractWritableArchive(ArchiveType type)
: base(type)
Expand Down Expand Up @@ -45,8 +62,17 @@ public override ICollection<TEntry> Entries
}
}

public IDisposable PauseEntryRebuilding()
{
return new RebuildPauseDisposable(this);
}

private void RebuildModifiedCollection()
{
if (pauseRebuilding)
{
return;
}
hasModifications = true;
newEntries.RemoveAll(v => removedEntries.Contains(v));
modifiedEntries.Clear();
Expand Down
6 changes: 6 additions & 0 deletions src/SharpCompress/Archives/IWritableArchive.cs
Expand Up @@ -11,5 +11,11 @@ public interface IWritableArchive : IArchive
IArchiveEntry AddEntry(string key, Stream source, bool closeStream, long size = 0, DateTime? modified = null);

void SaveTo(Stream stream, WriterOptions options);

/// <summary>
/// Use this to pause entry rebuilding when adding large collections of entries. Dispose when complete. A using statement is recommended.
/// </summary>
/// <returns>IDisposeable to resume entry rebuilding</returns>
IDisposable PauseEntryRebuilding();
}
}
11 changes: 7 additions & 4 deletions src/SharpCompress/Archives/IWritableArchiveExtensions.cs
Expand Up @@ -35,11 +35,14 @@ public static void SaveTo(this IWritableArchive writableArchive, FileInfo fileIn
this IWritableArchive writableArchive,
string filePath, string searchPattern = "*.*", SearchOption searchOption = SearchOption.AllDirectories)
{
foreach (var path in Directory.EnumerateFiles(filePath, searchPattern, searchOption))
using (writableArchive.PauseEntryRebuilding())
{
var fileInfo = new FileInfo(path);
writableArchive.AddEntry(path.Substring(filePath.Length), fileInfo.OpenRead(), true, fileInfo.Length,
fileInfo.LastWriteTime);
foreach (var path in Directory.EnumerateFiles(filePath, searchPattern, searchOption))
{
var fileInfo = new FileInfo(path);
writableArchive.AddEntry(path.Substring(filePath.Length), fileInfo.OpenRead(), true, fileInfo.Length,
fileInfo.LastWriteTime);
}
}
}
public static IArchiveEntry AddEntry(this IWritableArchive writableArchive, string key, FileInfo fileInfo)
Expand Down

0 comments on commit 6e42e00

Please sign in to comment.