using System.Diagnostics.Contracts;\r
using System.IO;\r
using System.Reflection;\r
+using System.Security.Cryptography;\r
using System.ServiceModel.Channels;\r
using System.Threading;\r
using System.Threading.Tasks;\r
using System.Threading.Tasks.Dataflow;\r
-using OpenSSL.Crypto;\r
+\r
\r
namespace Pithos.Network\r
{\r
return _bufferMgr;\r
}\r
\r
- public static async Task<ConcurrentDictionary<long, byte[]>> CalculateBlockHashesInPlacePFor(FileStream stream, int blockSize, string algorithm, int parallelism, Action<long, byte[], int> postAction,CancellationToken token, IProgress<double> progress)\r
+ //public static async Task<ConcurrentDictionary<long, byte[]>> CalculateBlockHashesInPlacePFor(FileStream stream, int blockSize, string algorithm, int parallelism, Action<long, byte[], int> postAction,CancellationToken token, IProgress<double> progress)\r
+ public static async Task<ConcurrentDictionary<long, byte[]>> CalculateBlockHashesInPlacePFor(FileStream stream, int blockSize, string algorithm, byte parallelism, CancellationToken token, IProgress<HashProgress> progress)\r
{\r
if (stream == null)\r
throw new ArgumentNullException("stream");\r
if (size == 0)\r
{\r
var buf = new byte[0];\r
- using (var hasher = new MessageDigestContext(MessageDigest.CreateByName(algorithm)))\r
- { \r
- hasher.Init();\r
- hashes[0] = hasher.Digest(buf);\r
+ using (var hasher = HashAlgorithm.Create(algorithm))\r
+ {\r
+ hashes[0] = hasher.ComputeHash(buf);\r
return hashes;\r
}\r
}\r
\r
+ var blocks = size<blockSize?1:size/blockSize;\r
\r
- var buffer = new byte[parallelism][];\r
- var hashers = new MessageDigestContext[parallelism];\r
- var bufferManager = GetBufferManager(blockSize, parallelism);\r
- for (var i = 0; i < parallelism; i++)\r
+ var actualHashers = parallelism > blocks ? (byte)blocks : parallelism;\r
+\r
+ var buffer = new byte[actualHashers][];\r
+ var hashers = new HashAlgorithm[actualHashers];\r
+ var bufferManager = GetBufferManager(blockSize, actualHashers);\r
+ for (var i = 0; i < actualHashers; i++)\r
{\r
buffer[i] = bufferManager.TakeBuffer(blockSize);// new byte[blockSize];\r
- hashers[i] = new MessageDigestContext(MessageDigest.CreateByName(algorithm));\r
- hashers[i].Init();\r
+ hashers[i] = HashAlgorithm.Create(algorithm); \r
}\r
try\r
{\r
- var indices = new long[parallelism];\r
- var bufferCount = new int[parallelism];\r
+ var indices = new long[actualHashers];\r
+ var bufferCount = new int[actualHashers];\r
\r
int read;\r
int bufIdx = 0;\r
long index = 0;\r
\r
- long block = 0;\r
+ //long block = 0;\r
\r
while ((read = await stream.ReadAsync(buffer[bufIdx], 0, blockSize).ConfigureAwait(false)) > 0)\r
{\r
index += read;\r
indices[bufIdx] = index;\r
bufferCount[bufIdx] = read;\r
- postAction(block++, buffer[bufIdx], read);\r
+ //postAction(block++, buffer[bufIdx], read);\r
\r
//If we have filled the last buffer or if we have read from the last block,\r
//we can calculate the clocks in parallel\r
- if (bufIdx == parallelism - 1 || read < blockSize)\r
+ if (bufIdx == actualHashers - 1 || read < blockSize)\r
{\r
- var options = new ParallelOptions {MaxDegreeOfParallelism = parallelism,CancellationToken=token};\r
+ var options = new ParallelOptions {MaxDegreeOfParallelism = actualHashers,CancellationToken=token};\r
\r
Parallel.For(0, bufIdx + 1, options,(idx,state) =>\r
{\r
\r
var hasher = hashers[idx];\r
\r
- byte[] hash;\r
+ byte[] hash=hasher.ComputeHash(buffer[idx],0,lastByteIndex+1);\r
+/*\r
if (buffer[idx].Length == lastByteIndex || lastByteIndex==-1)\r
hash = hasher.Digest(buffer[idx]);\r
else\r
Buffer.BlockCopy(buffer[idx],0,buf,0,lastByteIndex+1);\r
hash = hasher.Digest(buf);\r
}\r
+*/\r
\r
\r
\r
(double)filePosition / size);\r
*/\r
hashes[filePosition] = hash;\r
- progress.Report((long)hashes.Count*blockSize*1.0/stream.Length);\r
+ //Do not report for files smaller than 4MB\r
+ if (progress != null && stream.Length > 4*1024*1024)\r
+ progress.Report(new HashProgress((long)hashes.Count*blockSize,stream.Length));\r
});\r
}\r
- bufIdx = (bufIdx +1)%parallelism;\r
+ bufIdx = (bufIdx +1)%actualHashers;\r
}\r
}\r
finally\r
{\r
- for (var i = 0; i < parallelism; i++)\r
+ for (var i = 0; i < actualHashers; i++)\r
{\r
if (hashers[i] != null)\r
hashers[i].Dispose();\r