Revision 6bcdd8e2 trunk/Pithos.Network/BlockHashAlgorithms.cs
b/trunk/Pithos.Network/BlockHashAlgorithms.cs | ||
---|---|---|
42 | 42 |
using System.Collections.Concurrent; |
43 | 43 |
using System.Diagnostics.Contracts; |
44 | 44 |
using System.IO; |
45 |
using System.Reflection; |
|
45 | 46 |
using System.Security.Cryptography; |
46 | 47 |
using System.Threading.Tasks; |
47 | 48 |
using System.Threading.Tasks.Dataflow; |
... | ... | |
58 | 59 |
/// </summary> |
59 | 60 |
public static class BlockHashAlgorithms |
60 | 61 |
{ |
62 |
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
|
63 |
|
|
61 | 64 |
public static Func<FileStream, int, string, ConcurrentDictionary<int, byte[]>, int, Task<ConcurrentDictionary<int, byte[]>>> CalculateBlockHash; |
62 | 65 |
|
63 | 66 |
public static Task<ConcurrentDictionary<int, byte[]>> CalculateBlockHashesRecursiveAsync(FileStream stream, int blockSize, string algorithm, ConcurrentDictionary<int, byte[]> hashes = null, int index = 0) |
... | ... | |
143 | 146 |
|
144 | 147 |
var hashes = new ConcurrentDictionary<int, byte[]>(); |
145 | 148 |
|
149 |
var path = stream.Name; |
|
150 |
var size = stream.Length; |
|
151 |
Log.DebugFormat("Hashing [{0}] size [{1}]",path,size); |
|
152 |
|
|
153 |
/* |
|
146 | 154 |
var options = new ExecutionDataflowBlockOptions {BoundedCapacity = parallelism,MaxDegreeOfParallelism=parallelism}; |
147 | 155 |
var hashBlock=new ActionBlock<Tuple<int,byte[]>>(input=> |
148 | 156 |
{ |
... | ... | |
158 | 166 |
hashes[idx] = hash; |
159 | 167 |
} |
160 | 168 |
},options); |
169 |
*/ |
|
161 | 170 |
|
162 | 171 |
var buffer = new byte[blockSize]; |
163 | 172 |
int read; |
164 | 173 |
int index = 0; |
165 |
while ((read = await stream.ReadAsync(buffer, 0, blockSize)) > 0)
|
|
174 |
using (var hasher = HashAlgorithm.Create(algorithm))
|
|
166 | 175 |
{ |
167 |
var block = new byte[read]; |
|
168 |
Buffer.BlockCopy(buffer,0,block,0,read); |
|
169 |
await hashBlock.SendAsync(Tuple.Create(index, block)); |
|
170 |
index += read; |
|
171 |
}; |
|
176 |
while ((read = await stream.ReadAsync(buffer, 0, blockSize)) > 0) |
|
177 |
{ |
|
178 |
// var block = new byte[read]; |
|
179 |
|
|
180 |
//This code was added for compatibility with the way Pithos calculates the last hash |
|
181 |
//We calculate the hash only up to the last non-null byte |
|
182 |
var lastByteIndex = Array.FindLastIndex(buffer, read - 1, aByte => aByte != 0); |
|
183 |
|
|
184 |
var hash = hasher.ComputeHash(buffer, 0, lastByteIndex + 1); |
|
185 |
Log.DebugFormat("Hashed [{0}] [{1}/{2}] [{3:p}]", path, index,size,(double)index/size); |
|
186 |
hashes[index] = hash; |
|
187 |
index += read; |
|
188 |
} |
|
189 |
|
|
190 |
/* |
|
191 |
Buffer.BlockCopy(buffer,0,block,0,read); |
|
192 |
await hashBlock.SendAsync(Tuple.Create(index, block)); |
|
193 |
*/ |
|
194 |
|
|
195 |
} |
|
196 |
|
|
172 | 197 |
|
198 |
/* |
|
173 | 199 |
hashBlock.Complete(); |
174 | 200 |
await hashBlock.Completion; |
201 |
*/ |
|
175 | 202 |
|
176 | 203 |
return hashes; |
177 | 204 |
} |
Also available in: Unified diff