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