diff --git a/DiscImageChef.DiscImages/DiscImageChef.cs b/DiscImageChef.DiscImages/DiscImageChef.cs
index c5f9983b5..628b363e4 100644
--- a/DiscImageChef.DiscImages/DiscImageChef.cs
+++ b/DiscImageChef.DiscImages/DiscImageChef.cs
@@ -140,7 +140,7 @@ namespace DiscImageChef.DiscImages
MemoryStream decompressedStream;
bool deduplicate;
/// On-memory deduplication table indexed by checksum.
- Dictionary deduplicationTable;
+ Dictionary deduplicationTable;
/// writer.
FlakeWriter flakeWriter;
/// settings.
@@ -165,6 +165,7 @@ namespace DiscImageChef.DiscImages
Md5Context md5Provider;
/// Cache of media tags.
Dictionary mediaTags;
+ bool nocompress;
/// If DDT is on-disk, this is the image stream offset at which it starts.
long outMemoryDdtPosition;
bool rewinded;
@@ -190,7 +191,7 @@ namespace DiscImageChef.DiscImages
/// In-memory deduplication table
ulong[] userDataDdt;
bool writingLong;
- bool nocompress;
+ ulong writtenSectors;
public DiscImageChef()
{
@@ -2554,7 +2555,7 @@ namespace DiscImageChef.DiscImages
imageStream.Seek(0, SeekOrigin.End);
mediaTags = new Dictionary();
checksumProvider = SHA256.Create();
- deduplicationTable = new Dictionary();
+ deduplicationTable = new Dictionary();
trackIsrcs = new Dictionary();
trackFlags = new Dictionary();
@@ -2643,15 +2644,24 @@ namespace DiscImageChef.DiscImages
if(sectorAddress == 0) alreadyWrittenZero = true;
byte[] hash = null;
+ writtenSectors++;
// Compute hash only if asked to deduplicate, or the sector is empty (those will always be deduplicated)
if(deduplicate || ArrayHelpers.ArrayIsNullOrEmpty(data)) hash = checksumProvider.ComputeHash(data);
+ string hashString = null;
- if(hash != null && deduplicationTable.TryGetValue(hash, out ulong pointer))
+ if(hash != null)
{
- SetDdtEntry(sectorAddress, pointer);
- ErrorMessage = "";
- return true;
+ StringBuilder hashSb = new StringBuilder();
+ foreach(byte h in hash) hashSb.Append(h.ToString("x2"));
+ hashString = hashSb.ToString();
+
+ if(deduplicationTable.TryGetValue(hashString, out ulong pointer))
+ {
+ SetDdtEntry(sectorAddress, pointer);
+ ErrorMessage = "";
+ return true;
+ }
}
Track trk = new Track();
@@ -2758,8 +2768,8 @@ namespace DiscImageChef.DiscImages
sectorSize = (uint)data.Length
};
- if(imageInfo.XmlMediaType == XmlMediaType.OpticalDisc && trk.TrackType == TrackType.Audio && !nocompress)
- currentBlockHeader.compression = CompressionType.Flac;
+ if(imageInfo.XmlMediaType == XmlMediaType.OpticalDisc && trk.TrackType == TrackType.Audio && !nocompress
+ ) currentBlockHeader.compression = CompressionType.Flac;
blockStream = new MemoryStream();
decompressedStream = new MemoryStream();
@@ -2771,7 +2781,7 @@ namespace DiscImageChef.DiscImages
}
ulong ddtEntry = (ulong)((imageStream.Position << shift) + currentBlockOffset);
- if(hash != null) deduplicationTable.Add(hash, ddtEntry);
+ if(hash != null) deduplicationTable.Add(hashString, ddtEntry);
if(currentBlockHeader.compression == CompressionType.Flac)
{
AudioBuffer audioBuffer = new AudioBuffer(AudioPCMConfig.RedBook, data, SAMPLES_PER_SECTOR);
@@ -2780,8 +2790,7 @@ namespace DiscImageChef.DiscImages
else
{
decompressedStream.Write(data, 0, data.Length);
- if(currentBlockHeader.compression == CompressionType.Lzma)
- lzmaBlockStream.Write(data, 0, data.Length);
+ if(currentBlockHeader.compression == CompressionType.Lzma) lzmaBlockStream.Write(data, 0, data.Length);
}
SetDdtEntry(sectorAddress, ddtEntry);
@@ -3168,6 +3177,11 @@ namespace DiscImageChef.DiscImages
imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length);
}
+ if(deduplicate)
+ DicConsole.DebugWriteLine("DiscImageChef format plugin",
+ "Of {0} sectors written, {1} are unique ({2:P})", writtenSectors,
+ deduplicationTable.Count, (double)deduplicationTable.Count / writtenSectors);
+
IndexEntry idxEntry;
// Write media tag blocks