+ int read;\r
+ int bufIdx = 0;\r
+ long index = 0;\r
+ while ((read = await stream.ReadAsync(buffer[bufIdx], 0, blockSize)) > 0)\r
+ {\r
+ index += read;\r
+ indices[bufIdx] = index;\r
+ bufferCount[bufIdx] = read;\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
+ {\r
+ //var options = new ParallelOptions {MaxDegreeOfParallelism = parallelism};\r
+ Parallel.For(0, bufIdx + 1, idx =>\r
+ {\r
+ //This code was added for compatibility with the way Pithos calculates the last hash\r
+ //We calculate the hash only up to the last non-null byte\r
+ var lastByteIndex = Array.FindLastIndex(buffer[idx],\r
+ bufferCount[idx] - 1,\r
+ aByte => aByte != 0);\r
+\r
+ var hasher = hashers[idx];\r
+ var hash = hasher.ComputeHash(buffer[idx], 0, lastByteIndex + 1);\r
+ var filePosition = indices[idx];\r
+ /*\r
+ Trace.TraceInformation("Hashed [{0}] [{1}/{2}] [{3:p}]", path,\r
+ filePosition, size,\r
+ (double)filePosition / size);\r
+ */\r
+ hashes[filePosition] = hash;\r
+ });\r
+ }\r
+ bufIdx = (bufIdx + 1) % parallelism;\r
+ }\r
+ }\r
+ finally\r
+ {\r
+ for (var i = 0; i < parallelism; i++)\r
+ {\r
+ if (hashers[i] != null)\r
+ hashers[i].Dispose();\r
+ }\r
+\r
+ }\r