Revision dccd340f
b/trunk/Pithos.Core.Test/LocalFileComparerTest.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using System.Linq; |
|
4 |
using System.Text; |
|
5 |
using NUnit.Framework; |
|
6 |
using Pithos.Interfaces; |
|
7 |
using Pithos.Network; |
|
8 |
|
|
9 |
namespace Pithos.Core.Test |
|
10 |
{ |
|
11 |
[TestFixture] |
|
12 |
class LocalFileComparerTest |
|
13 |
{ |
|
14 |
[Test] |
|
15 |
public void objects_with_same_name_and_hash_should_match() |
|
16 |
{ |
|
17 |
var comparer = new LocalFileComparer(); |
|
18 |
var account = new AccountInfo(); |
|
19 |
var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"}); |
|
20 |
var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" }); |
|
21 |
Assert.That(comparer.Equals(x, y), Is.True); |
|
22 |
} |
|
23 |
|
|
24 |
[Test] |
|
25 |
public void objects_with_different_name_same_hash_should_not_match() |
|
26 |
{ |
|
27 |
var comparer = new LocalFileComparer(); |
|
28 |
var account = new AccountInfo(); |
|
29 |
var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"}); |
|
30 |
var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a" }); |
|
31 |
Assert.That(comparer.Equals(x, y), Is.True); |
|
32 |
} |
|
33 |
[Test] |
|
34 |
public void directories_with_different_name_should_not_match() |
|
35 |
{ |
|
36 |
var comparer = new LocalFileComparer(); |
|
37 |
var account = new AccountInfo(); |
|
38 |
var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a",Content_Type = "application/directory"}); |
|
39 |
var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a", Content_Type = "application/directory" }); |
|
40 |
Assert.That(comparer.Equals(x, y), Is.False); |
|
41 |
} |
|
42 |
|
|
43 |
} |
|
44 |
} |
b/trunk/Pithos.Core.Test/Pithos.Core.Test.csproj | ||
---|---|---|
207 | 207 |
<Compile Include="ExtensionTests.cs" /> |
208 | 208 |
<Compile Include="FileSystemWatcherAdapterTest.cs" /> |
209 | 209 |
<Compile Include="IdleBatchTest.cs" /> |
210 |
<Compile Include="LocalFileComparerTest.cs" /> |
|
210 | 211 |
<Compile Include="NetworkAgentTest.cs" /> |
211 | 212 |
<Compile Include="PithosWorkflowTest.cs" /> |
212 | 213 |
<Compile Include="Properties\AssemblyInfo.cs" /> |
b/trunk/Pithos.Core/Agents/FileSystemWatcherAdapter.cs | ||
---|---|---|
94 | 94 |
throw new ArgumentException("e"); |
95 | 95 |
if (string.IsNullOrWhiteSpace(e.FullPath)) |
96 | 96 |
throw new ArgumentException("e"); |
97 |
Contract.Ensures(!String.IsNullOrWhiteSpace(_cachedDeletedFullPath)); |
|
98 | 97 |
Contract.EndContractBlock(); |
99 | 98 |
|
100 | 99 |
TaskEx.Run(() => InnerOnDeleted(sender, e)); |
... | ... | |
134 | 133 |
{ |
135 | 134 |
if (sender == null) |
136 | 135 |
throw new ArgumentNullException("sender"); |
137 |
Contract.Ensures(_cachedDeletedFullPath == null); |
|
138 | 136 |
Contract.EndContractBlock(); |
139 | 137 |
|
140 | 138 |
TaskEx.Run(() => InnerRename(sender, e)); |
... | ... | |
196 | 194 |
throw new ArgumentNullException("sender"); |
197 | 195 |
if (!(e.ChangeType == WatcherChangeTypes.Created || e.ChangeType == WatcherChangeTypes.Changed)) |
198 | 196 |
throw new ArgumentException("e"); |
199 |
Contract.Ensures(_cachedDeletedFullPath == null); |
|
200 | 197 |
Contract.EndContractBlock(); |
201 | 198 |
TaskEx.Run(() => InnerChangeOrCreated(sender, e)); |
202 | 199 |
|
b/trunk/Pithos.Core/Agents/PollAgent.cs | ||
---|---|---|
189 | 189 |
Contract.EndContractBlock(); |
190 | 190 |
|
191 | 191 |
|
192 |
using (log4net.ThreadContext.Stacks["Retrieve Remote"].Push(accountInfo.UserName))
|
|
192 |
using (ThreadContext.Stacks["Retrieve Remote"].Push(accountInfo.UserName)) |
|
193 | 193 |
{ |
194 | 194 |
|
195 | 195 |
await NetworkAgent.GetDeleteAwaiter(); |
... | ... | |
228 | 228 |
listObjects.Add(listShared); |
229 | 229 |
var listTasks = await Task.Factory.WhenAll(listObjects.ToArray()); |
230 | 230 |
|
231 |
using (log4net.ThreadContext.Stacks["SCHEDULE"].Push("Process Results"))
|
|
231 |
using (ThreadContext.Stacks["SCHEDULE"].Push("Process Results")) |
|
232 | 232 |
{ |
233 | 233 |
var dict = listTasks.ToDictionary(t => t.AsyncState); |
234 | 234 |
|
... | ... | |
285 | 285 |
|
286 | 286 |
//And remove those that are already being processed by the agent |
287 | 287 |
var distinctActions = allActions |
288 |
.Except(NetworkAgent.GetEnumerable(), new PithosMonitor.LocalFileComparer())
|
|
288 |
.Except(NetworkAgent.GetEnumerable(), new LocalFileComparer()) |
|
289 | 289 |
.ToList(); |
290 | 290 |
|
291 | 291 |
//Queue all the actions |
... | ... | |
540 | 540 |
//over the remote files |
541 | 541 |
foreach (var objectInfo in creates) |
542 | 542 |
{ |
543 |
if (Log.IsDebugEnabled) |
|
544 |
Log.DebugFormat("[NEW INFO] {0}",objectInfo.Uri); |
|
545 |
|
|
543 | 546 |
var relativePath = objectInfo.RelativeUrlToFilePath(accountInfo.UserName); |
544 | 547 |
//If the object already exists, we probably have a conflict |
545 | 548 |
if (fileAgent.Exists(relativePath)) |
546 | 549 |
{ |
550 |
Log.DebugFormat("[SKIP EXISTING] {0}", objectInfo.Uri); |
|
547 | 551 |
//If a directory object already exists, we don't need to perform any other action |
548 | 552 |
var localFile = fileAgent.GetFileSystemInfo(relativePath); |
549 | 553 |
StatusKeeper.SetFileState(localFile.FullName, FileStatus.Conflict, FileOverlayStatus.Conflict); |
... | ... | |
608 | 612 |
{ |
609 | 613 |
AccountInfo account; |
610 | 614 |
_accounts.TryRemove(accountInfo.UserName,out account); |
615 |
SnapshotDifferencer differencer; |
|
616 |
_differencer.Differencers.TryRemove(accountInfo.UserName, out differencer); |
|
611 | 617 |
} |
612 | 618 |
} |
613 | 619 |
} |
b/trunk/Pithos.Core/LocalFileComparer.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using Pithos.Core.Agents; |
|
4 |
|
|
5 |
namespace Pithos.Core |
|
6 |
{ |
|
7 |
public class LocalFileComparer:EqualityComparer<CloudAction> |
|
8 |
{ |
|
9 |
public override bool Equals(CloudAction x, CloudAction y) |
|
10 |
{ |
|
11 |
if (x.Action != y.Action) |
|
12 |
return false; |
|
13 |
if (x.LocalFile != null && y.LocalFile != null && !x.LocalFile.FullName.Equals(y.LocalFile.FullName)) |
|
14 |
return false; |
|
15 |
if (x.CloudFile != null && y.CloudFile != null ) |
|
16 |
{ |
|
17 |
if (x.CloudFile.Hash == null & y.CloudFile.Hash != null) |
|
18 |
return false; |
|
19 |
if (x.CloudFile.Hash != null & y.CloudFile.Hash == null) |
|
20 |
return false; |
|
21 |
if (x.CloudFile.Hash == null & y.CloudFile.Hash == null) |
|
22 |
return (x.CloudFile.Name == y.CloudFile.Name); |
|
23 |
|
|
24 |
if (!x.CloudFile.Hash.Equals(y.CloudFile.Hash)) |
|
25 |
return false; |
|
26 |
//All directories have the same hash. Compare them using their names instead |
|
27 |
if (x.CloudFile.Content_Type == y.CloudFile.Content_Type && x.CloudFile.Content_Type == "application/directory") |
|
28 |
{ |
|
29 |
return (x.CloudFile.Name == y.CloudFile.Name); |
|
30 |
} |
|
31 |
} |
|
32 |
if (x.CloudFile == null ^ y.CloudFile == null || |
|
33 |
x.LocalFile == null ^ y.LocalFile == null) |
|
34 |
return false; |
|
35 |
return true; |
|
36 |
} |
|
37 |
|
|
38 |
public override int GetHashCode(CloudAction obj) |
|
39 |
{ |
|
40 |
if (obj == null) |
|
41 |
return 0; |
|
42 |
var hash1 = (obj.LocalFile == null) ? Int32.MaxValue : obj.LocalFile.FullName.GetHashCode(); |
|
43 |
var hash2 = Int32.MaxValue; |
|
44 |
if (obj.CloudFile != null) |
|
45 |
{ |
|
46 |
//All directories have the same hash code. Use their name's hash code instead |
|
47 |
hash2 = obj.CloudFile.Content_Type == "application/directory" |
|
48 |
? obj.CloudFile.Name.GetHashCode() |
|
49 |
: (obj.CloudFile.Hash ?? obj.CloudFile.Name ?? "").GetHashCode(); |
|
50 |
} |
|
51 |
var hash3 = obj.Action.GetHashCode(); |
|
52 |
return hash1 ^ hash2 & hash3; |
|
53 |
} |
|
54 |
} |
|
55 |
} |
b/trunk/Pithos.Core/Pithos.Core.csproj | ||
---|---|---|
403 | 403 |
<Compile Include="IStatusNotification.cs" /> |
404 | 404 |
<Compile Include="IStatusService.cs" /> |
405 | 405 |
<Compile Include="JobQueue.cs" /> |
406 |
<Compile Include="LocalFileComparer.cs" /> |
|
406 | 407 |
<Compile Include="NetworkGate.cs" /> |
407 | 408 |
<Compile Include="Agents\StatusAgent.cs" /> |
408 | 409 |
<Compile Include="IPithosWorkflow.cs" /> |
b/trunk/Pithos.Core/PithosMonitor.cs | ||
---|---|---|
317 | 317 |
} |
318 | 318 |
}*/ |
319 | 319 |
|
320 |
internal class LocalFileComparer:EqualityComparer<CloudAction> |
|
321 |
{ |
|
322 |
public override bool Equals(CloudAction x, CloudAction y) |
|
323 |
{ |
|
324 |
if (x.Action != y.Action) |
|
325 |
return false; |
|
326 |
if (x.LocalFile != null && y.LocalFile != null && !x.LocalFile.FullName.Equals(y.LocalFile.FullName)) |
|
327 |
return false; |
|
328 |
if (x.CloudFile != null && y.CloudFile != null ) |
|
329 |
{ |
|
330 |
if (x.CloudFile.Hash == null & y.CloudFile.Hash != null) |
|
331 |
return false; |
|
332 |
if (x.CloudFile.Hash != null & y.CloudFile.Hash == null) |
|
333 |
return false; |
|
334 |
if (x.CloudFile.Hash == null & y.CloudFile.Hash == null) |
|
335 |
return (x.CloudFile.Name == y.CloudFile.Name); |
|
336 |
if (!x.CloudFile.Hash.Equals(y.CloudFile.Hash)) |
|
337 |
return false; |
|
338 |
} |
|
339 |
if (x.CloudFile == null ^ y.CloudFile == null || |
|
340 |
x.LocalFile == null ^ y.LocalFile == null) |
|
341 |
return false; |
|
342 |
return true; |
|
343 |
} |
|
344 |
|
|
345 |
public override int GetHashCode(CloudAction obj) |
|
346 |
{ |
|
347 |
if (obj == null) |
|
348 |
return 0; |
|
349 |
var hash1 = (obj.LocalFile == null) ? int.MaxValue : obj.LocalFile.FullName.GetHashCode(); |
|
350 |
var hash2 = (obj.CloudFile == null) ? int.MaxValue : (obj.CloudFile.Hash ?? obj.CloudFile.Name??"").GetHashCode(); |
|
351 |
var hash3 = obj.Action.GetHashCode(); |
|
352 |
return hash1 ^ hash2 & hash3; |
|
353 |
} |
|
354 |
} |
|
355 |
|
|
356 | 320 |
|
357 | 321 |
private void StartNetworkAgent() |
358 | 322 |
{ |
Also available in: Unified diff