Revision 1cc1e8c5 trunk/Pithos.Core/Agents/PollAgent.cs
b/trunk/Pithos.Core/Agents/PollAgent.cs | ||
---|---|---|
47 | 47 |
using System.IO; |
48 | 48 |
using System.Linq.Expressions; |
49 | 49 |
using System.Reflection; |
50 |
using System.Security.Cryptography; |
|
50 | 51 |
using System.Threading; |
51 | 52 |
using System.Threading.Tasks; |
52 | 53 |
using Castle.ActiveRecord; |
... | ... | |
65 | 66 |
{ |
66 | 67 |
public string FilePath { get; private set; } |
67 | 68 |
|
69 |
public string MD5 { get; set; } |
|
70 |
|
|
68 | 71 |
public string L |
69 | 72 |
{ |
70 | 73 |
get { return FileState==null?null:FileState.Checksum; } |
... | ... | |
74 | 77 |
|
75 | 78 |
public string S |
76 | 79 |
{ |
77 |
get { return ObjectInfo== null ? null : ObjectInfo.Hash; }
|
|
80 |
get { return ObjectInfo == null ? null : ObjectInfo.X_Object_Hash; }
|
|
78 | 81 |
} |
79 | 82 |
|
80 | 83 |
private FileSystemInfo _fileInfo; |
... | ... | |
393 | 396 |
foreach (var tuple in tuples) |
394 | 397 |
{ |
395 | 398 |
await _unPauseEvent.WaitAsync(); |
396 |
|
|
399 |
|
|
400 |
//Set the Merkle Hash |
|
401 |
SetMerkleHash(accountInfo, tuple); |
|
402 |
|
|
397 | 403 |
SyncSingleItem(accountInfo, tuple, agent, token); |
404 |
|
|
398 | 405 |
} |
399 | 406 |
|
400 | 407 |
|
... | ... | |
421 | 428 |
} |
422 | 429 |
} |
423 | 430 |
|
431 |
private static void SetMerkleHash(AccountInfo accountInfo, StateTuple tuple) |
|
432 |
{ |
|
433 |
//The Merkle hash for directories is that of an empty buffer |
|
434 |
if (tuple.FileInfo is DirectoryInfo) |
|
435 |
tuple.C = MERKLE_EMPTY; |
|
436 |
else if (tuple.FileState != null && tuple.MD5 == tuple.FileState.ShortHash) |
|
437 |
{ |
|
438 |
//If there is a state whose MD5 matches, load the merkle hash fromthe file state |
|
439 |
//insteaf of calculating it |
|
440 |
tuple.C = tuple.FileState.Checksum; |
|
441 |
} |
|
442 |
else |
|
443 |
{ |
|
444 |
tuple.C=Signature.CalculateTreeHash(tuple.FileInfo, accountInfo.BlockSize, accountInfo.BlockHash) |
|
445 |
.TopHash.ToHashString(); |
|
446 |
} |
|
447 |
} |
|
448 |
|
|
424 | 449 |
private static List<Tuple<FileSystemInfo, string>> LoadLocalFileTuples(AccountInfo accountInfo) |
425 | 450 |
{ |
426 | 451 |
using (ThreadContext.Stacks["Account Files Hashing"].Push(accountInfo.UserName)) |
... | ... | |
429 | 454 |
var localInfos = AgentLocator<FileAgent>.Get(accountInfo.AccountPath).EnumerateFileSystemInfos(); |
430 | 455 |
//Use the queue to retry locked file hashing |
431 | 456 |
var fileQueue = new Queue<FileSystemInfo>(localInfos); |
457 |
var hasher = MD5.Create(); |
|
432 | 458 |
|
433 | 459 |
var results = new List<Tuple<FileSystemInfo, string>>(); |
434 | 460 |
|
... | ... | |
437 | 463 |
var file = fileQueue.Dequeue(); |
438 | 464 |
using (ThreadContext.Stacks["File"].Push(file.FullName)) |
439 | 465 |
{ |
466 |
/* |
|
467 |
Signature.CalculateTreeHash(file, accountInfo.BlockSize, |
|
468 |
accountInfo.BlockHash). |
|
469 |
TopHash.ToHashString() |
|
470 |
*/ |
|
440 | 471 |
try |
441 | 472 |
{ |
442 |
var hash = (file is DirectoryInfo) |
|
443 |
? "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" |
|
444 |
: Signature.CalculateTreeHash(file, accountInfo.BlockSize, |
|
445 |
accountInfo.BlockHash) |
|
446 |
. |
|
447 |
TopHash.ToHashString(); |
|
473 |
//Replace MD5 here, do the calc while syncing individual files |
|
474 |
string hash ; |
|
475 |
if (file is DirectoryInfo) |
|
476 |
hash = MERKLE_EMPTY; |
|
477 |
else |
|
478 |
{ |
|
479 |
using (var stream = (file as FileInfo).OpenRead()) |
|
480 |
{ |
|
481 |
hash = hasher.ComputeHash(stream).ToHashString(); |
|
482 |
} |
|
483 |
} |
|
448 | 484 |
results.Add(Tuple.Create(file, hash)); |
449 | 485 |
} |
450 | 486 |
catch (IOException exc) |
... | ... | |
504 | 540 |
tuple.ObjectInfo, |
505 | 541 |
localFilePath, token).Wait(token); |
506 | 542 |
//updateRecord( L = S ) |
507 |
StatusKeeper.UpdateFileChecksum(localFilePath, tuple.FileState==null?"":tuple.FileState.ShortHash,
|
|
508 |
tuple.ObjectInfo.Hash); |
|
543 |
StatusKeeper.UpdateFileChecksum(localFilePath, tuple.ObjectInfo.ETag,
|
|
544 |
tuple.ObjectInfo.X_Object_Hash);
|
|
509 | 545 |
|
510 | 546 |
StatusKeeper.SetFileState(localFilePath, FileStatus.Unchanged, |
511 | 547 |
FileOverlayStatus.Normal, ""); |
... | ... | |
559 | 595 |
{ |
560 | 596 |
// (Identical Changes) Result: L = S |
561 | 597 |
//doNothing() |
562 |
StatusKeeper.UpdateFileChecksum(localFilePath, tuple.FileState == null ? "" : tuple.FileState.ShortHash,
|
|
563 |
tuple.ObjectInfo.Hash); |
|
598 |
StatusKeeper.UpdateFileChecksum(localFilePath, tuple.ObjectInfo.ETag,
|
|
599 |
tuple.ObjectInfo.X_Object_Hash);
|
|
564 | 600 |
StatusKeeper.SetFileState(localFilePath, FileStatus.Unchanged, |
565 | 601 |
FileOverlayStatus.Normal, ""); |
566 | 602 |
} |
... | ... | |
615 | 651 |
foreach (var file in files) |
616 | 652 |
{ |
617 | 653 |
var fsInfo = file.Item1; |
618 |
var fileHash = file.Item2; |
|
619 |
dct[fsInfo.FullName] = new StateTuple {FileInfo = fsInfo, C = fileHash}; |
|
654 |
var fileHash = fsInfo is DirectoryInfo? MERKLE_EMPTY:file.Item2; |
|
655 |
|
|
656 |
dct[fsInfo.FullName] = new StateTuple {FileInfo = fsInfo, MD5 = fileHash}; |
|
620 | 657 |
} |
621 | 658 |
foreach (var state in states) |
622 | 659 |
{ |
... | ... | |
690 | 727 |
//readonly AccountsDifferencer _differencer = new AccountsDifferencer(); |
691 | 728 |
private Dictionary<Uri, List<Uri>> _selectiveUris = new Dictionary<Uri, List<Uri>>(); |
692 | 729 |
private bool _pause; |
730 |
private static string MERKLE_EMPTY = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; |
|
693 | 731 |
|
694 | 732 |
/// <summary> |
695 | 733 |
/// Deletes local files that are not found in the list of cloud files |
... | ... | |
874 | 912 |
previousFile, objectInfo, state, accountInfo.BlockSize, |
875 | 913 |
accountInfo.BlockHash,"Poll Moves"); |
876 | 914 |
//For modified files, we need to download the changes as well |
877 |
if (objectInfo.Hash!=objectInfo.PreviousHash)
|
|
915 |
if (objectInfo.X_Object_Hash != objectInfo.PreviousHash)
|
|
878 | 916 |
yield return new CloudDownloadAction(accountInfo,objectInfo, "Poll Moves"); |
879 | 917 |
} |
880 | 918 |
} |
Also available in: Unified diff