Using MD5 to quickly check for local modifications before calculating the expensive...
authorpkanavos <pkanavos@gmail.com>
Fri, 1 Jun 2012 20:45:02 +0000 (23:45 +0300)
committerpkanavos <pkanavos@gmail.com>
Fri, 1 Jun 2012 20:45:02 +0000 (23:45 +0300)
Fixed bug that didn't upload the contents of new unselected root folders

16 files changed:
trunk/Pithos.Core.Test/LocalFileComparerTest.cs
trunk/Pithos.Core.Test/MockStatusKeeper.cs
trunk/Pithos.Core.Test/SnapshotDifferencerTest.cs
trunk/Pithos.Core/Agents/Downloader.cs
trunk/Pithos.Core/Agents/FileAgent.cs
trunk/Pithos.Core/Agents/NetworkAgent.cs
trunk/Pithos.Core/Agents/PollAgent.cs
trunk/Pithos.Core/Agents/SelectiveUris.cs
trunk/Pithos.Core/Agents/SnapshotDifferencer.cs
trunk/Pithos.Core/Agents/StatusAgent.cs
trunk/Pithos.Core/Agents/Uploader.cs
trunk/Pithos.Core/LocalFileComparer.cs
trunk/Pithos.Interfaces/ObjectInfo.cs
trunk/Pithos.Network.Test/ChecksumTest.cs
trunk/Pithos.Network.Test/NetworkOpsTest.cs
trunk/Pithos.Network/AccountInfo.cs

index 9126f8c..85c5850 100644 (file)
@@ -16,8 +16,8 @@ namespace Pithos.Core.Test
         {
             var comparer = new LocalFileComparer();
             var account = new AccountInfo();
-            var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"},null);
-            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" }, null);
+            var x = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", X_Object_Hash = "a" }, null);
+            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", X_Object_Hash = "a" }, null);
             Assert.That(comparer.Equals(x, y), Is.True);
         }
 
@@ -26,8 +26,8 @@ namespace Pithos.Core.Test
         {
             var comparer = new LocalFileComparer();
             var account = new AccountInfo();
-            var x = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" }, null);
-            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a" }, null);
+            var x = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", X_Object_Hash = "a" }, null);
+            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", X_Object_Hash = "a" }, null);
             Assert.That(comparer.Equals(x, y), Is.True);
         }
         [Test]
@@ -35,8 +35,8 @@ namespace Pithos.Core.Test
         {
             var comparer = new LocalFileComparer();
             var account = new AccountInfo();
-            var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a",Content_Type = "application/directory"},null);
-            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a", Content_Type = "application/directory" }, null);
+            var x = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", X_Object_Hash = "a", Content_Type = "application/directory" }, null);
+            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", X_Object_Hash = "a", Content_Type = "application/directory" }, null);
             Assert.That(comparer.Equals(x, y), Is.False);
         }
 
index 1baeac7..f45c14b 100644 (file)
@@ -82,7 +82,7 @@ namespace Pithos.Core.Test
 
             _statusCache[path] = FileStatus.Unchanged;
             _overlayCache[path] = FileOverlayStatus.Normal;
-            _checksums[path] = objectInfo.Hash;
+            _checksums[path] = objectInfo.X_Object_Hash;
 
 
         }
index bda6183..a0a6505 100644 (file)
@@ -29,34 +29,34 @@ namespace Pithos.Core.Test
         public void Setup()\r
         {\r
             _previous = new []{\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,Hash="aa4",Version=1,UUID="5"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="6"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="7"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="8"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="9"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="10"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="11"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="12"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="13"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="5"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="6"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="7"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="8"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="9"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="10"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="11"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="12"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="13"},\r
                             };\r
             _current = new []{\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=1234,Hash="aa45",Version=1,UUID="4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name5",Bytes=123,Hash="aa5",Version=1,UUID="14"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,Hash="aa4",Version=1,UUID="5"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="6"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="7"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="9"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="10"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=1234,Hash="aa45",Version=1,UUID="11"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name5",Bytes=123,Hash="aa5",Version=1,UUID="15"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="12"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="13"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=1234,X_Object_Hash="aa45",Version=1,UUID="4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name5",Bytes=123,X_Object_Hash="aa5",Version=1,UUID="14"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="5"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="6"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="7"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="9"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="10"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=1234,X_Object_Hash="aa45",Version=1,UUID="11"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name5",Bytes=123,X_Object_Hash="aa5",Version=1,UUID="15"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="12"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="13"},\r
                            };\r
             \r
         }\r
@@ -80,8 +80,8 @@ namespace Pithos.Core.Test
             var differencer=d1.Post(_previous).Post(_current);\r
             var deleted=new[]\r
                             {\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="8"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="8"},\r
                             };\r
             Assert.That(differencer.Deleted.ToList(),Is.EquivalentTo(deleted)\r
                 .Using((IEqualityComparer) new ObjectInfoComparer()));\r
@@ -93,8 +93,8 @@ namespace Pithos.Core.Test
             var differencer=d1.Post(_previous).Post(_current);\r
             var created = new[]\r
                               {\r
-                                  new ObjectInfo { Account = "acc1", Container = "Cont1", Name = "Name5", Bytes = 123, Hash = "aa5", Version = 1,UUID="14" },\r
-                                  new ObjectInfo { Account = "acc1", Container = "Cont2", Name = "Name5", Bytes = 123, Hash = "aa5", Version = 1,UUID="15" },\r
+                                  new ObjectInfo { Account = "acc1", Container = "Cont1", Name = "Name5", Bytes = 123, X_Object_Hash = "aa5", Version = 1,UUID="14" },\r
+                                  new ObjectInfo { Account = "acc1", Container = "Cont2", Name = "Name5", Bytes = 123, X_Object_Hash = "aa5", Version = 1,UUID="15" },\r
                               };\r
             Assert.That(differencer.Created.ToList(), Is.EquivalentTo(created)\r
                 .Using((IEqualityComparer)new ObjectInfoComparer()));\r
@@ -105,8 +105,8 @@ namespace Pithos.Core.Test
             var d1 = new SnapshotDifferencer();            \r
             var differencer=d1.Post(_previous).Post(_current);\r
             var changed = new[] { \r
-                new ObjectInfo { Account = "acc1", Container = "Cont1", Name = "Name4", Bytes = 1234, Hash = "aa45", PreviousHash="aa4", Version = 1,UUID="4" },\r
-                new ObjectInfo { Account = "acc1", Container = "Cont2", Name = "Name4", Bytes = 1234, Hash = "aa45", PreviousHash="aa4", Version = 1,UUID="11" },\r
+                new ObjectInfo { Account = "acc1", Container = "Cont1", Name = "Name4", Bytes = 1234, X_Object_Hash = "aa45", PreviousHash="aa4", Version = 1,UUID="4" },\r
+                new ObjectInfo { Account = "acc1", Container = "Cont2", Name = "Name4", Bytes = 1234, X_Object_Hash = "aa45", PreviousHash="aa4", Version = 1,UUID="11" },\r
             };\r
 \r
             Comparison<ObjectInfo> comparer = (x, y) =>\r
@@ -114,7 +114,7 @@ namespace Pithos.Core.Test
                                                       if (x.Account == y.Account\r
                                                           && x.Container == y.Container\r
                                                           && x.Name == y.Name\r
-                                                          && x.Hash == y.Hash\r
+                                                          && x.X_Object_Hash == y.X_Object_Hash\r
                                                           && x.PreviousHash == y.PreviousHash)\r
                                                           return 0;\r
                                                       return 1;\r
@@ -128,24 +128,24 @@ namespace Pithos.Core.Test
         {\r
             var d1 = new SnapshotDifferencer();\r
             var current = new[]{\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3a",Bytes=123,Hash="aa3",Version=1,UUID="3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,Hash="aa4",Version=1,UUID="5"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="6"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="7"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="8"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="9"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="10"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="11"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="12"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="13"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3a",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="5"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="6"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="7"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="8"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="9"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="10"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="11"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="12"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="13"},\r
                             };\r
 \r
             var differencer=d1.Post(_previous).Post(current);\r
             var moved = new[] { \r
-                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3a",Bytes=123,Hash="aa3",PreviousHash="aa3",Version=1,UUID="3"}\r
+                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3a",Bytes=123,X_Object_Hash="aa3",PreviousHash="aa3",Version=1,UUID="3"}\r
             };\r
 \r
             Comparison<ObjectInfo> comparer = (x, y) =>\r
@@ -153,7 +153,7 @@ namespace Pithos.Core.Test
                                                       if (x.Account == y.Account\r
                                                           && x.Container == y.Container\r
                                                           && x.Name == y.Name\r
-                                                          && x.Hash == y.Hash\r
+                                                          && x.X_Object_Hash == y.X_Object_Hash\r
                                                           && x.PreviousHash == y.PreviousHash)\r
                                                           return 0;\r
                                                       return 1;\r
@@ -171,38 +171,38 @@ namespace Pithos.Core.Test
         {\r
             var d1 = new SnapshotDifferencer();\r
             var current = new[]{\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3a",Bytes=123,Hash="aa35",Version=1,UUID="3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,Hash="aa4",Version=1,UUID="5"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="6"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="7"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="8"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="9"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="10"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="11"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="12"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="13"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3a",Bytes=123,X_Object_Hash="aa35",Version=1,UUID="3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="5"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="6"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="7"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="8"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="9"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="10"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="11"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="12"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="13"},\r
                             };\r
             var unchanged = new[]{\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="1",PreviousHash="aa1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="2",PreviousHash="aa2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="4",PreviousHash="aa4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,Hash="aa4",Version=1,UUID="5",PreviousHash="aa4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="6",PreviousHash="aa1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="7",PreviousHash="aa2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="8",PreviousHash="aa1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="9",PreviousHash="aa2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="10",PreviousHash="aa3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="11",PreviousHash="aa4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="12",PreviousHash="aa1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="13",PreviousHash="aa2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="1",PreviousHash="aa1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="2",PreviousHash="aa2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="4",PreviousHash="aa4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="5",PreviousHash="aa4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="6",PreviousHash="aa1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="7",PreviousHash="aa2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="8",PreviousHash="aa1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="9",PreviousHash="aa2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="10",PreviousHash="aa3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="11",PreviousHash="aa4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="12",PreviousHash="aa1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="13",PreviousHash="aa2"},\r
                             };\r
 \r
             var differencer = d1.Post(_previous).Post(current);\r
             var moved = new[] { \r
-                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3a",Bytes=123,Hash="aa35",PreviousHash="aa3",Version=1,UUID="3"}\r
+                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3a",Bytes=123,X_Object_Hash="aa35",PreviousHash="aa3",Version=1,UUID="3"}\r
             };\r
 \r
             Comparison<ObjectInfo> comparer = (x, y) =>\r
@@ -210,7 +210,7 @@ namespace Pithos.Core.Test
                 if (x.Account == y.Account\r
                     && x.Container == y.Container\r
                     && x.Name == y.Name\r
-                    && x.Hash == y.Hash\r
+                    && x.X_Object_Hash == y.X_Object_Hash\r
                     && x.PreviousHash == y.PreviousHash)\r
                     return 0;\r
                 return 1;\r
@@ -227,24 +227,24 @@ namespace Pithos.Core.Test
         {\r
             var d1 = new SnapshotDifferencer();\r
             var current = new[]{\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name3",Bytes=123,Hash="aa3",Version=1,UUID="3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,Hash="aa4",Version=1,UUID="5"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="6"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="7"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="8"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="9"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="10"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="11"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="12"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="13"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="5"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="6"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="7"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="8"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="9"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="10"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="11"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="12"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="13"},\r
                             };\r
 \r
             var differencer=d1.Post(_previous).Post(current);\r
             var moved = new[] { \r
-                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name3",Bytes=123,Hash="aa3",PreviousHash="aa3",Version=1},\r
+                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name3",Bytes=123,X_Object_Hash="aa3",PreviousHash="aa3",Version=1},\r
             };\r
 \r
             Comparison<ObjectInfo> comparer = (x, y) =>\r
@@ -252,7 +252,7 @@ namespace Pithos.Core.Test
                                                       if (x.Account == y.Account\r
                                                           && x.Container == y.Container\r
                                                           && x.Name == y.Name\r
-                                                          && x.Hash == y.Hash\r
+                                                          && x.X_Object_Hash == y.X_Object_Hash\r
                                                           && x.PreviousHash == y.PreviousHash)\r
                                                           return 0;\r
                                                       return 1;\r
@@ -272,15 +272,15 @@ namespace Pithos.Core.Test
             var differencer=d1.Post(_previous).Post(_current);\r
             var unchanged = new[]\r
                                 {\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="6"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="7"},  \r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,Hash="aa4",Version=1,UUID="5"},  \r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="9"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="10"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="12"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="13"},                                    \r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="6"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="7"},  \r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="5"},  \r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="9"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="10"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="12"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="13"},                                    \r
                                 };            \r
             Assert.That(differencer.Unchanged.ToList(), Is.EquivalentTo(unchanged)\r
                 .Using((IEqualityComparer)new ObjectInfoComparer()));\r
@@ -346,21 +346,21 @@ namespace Pithos.Core.Test
                                 };\r
             var deleted = new[]\r
                             {\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="4"},\r
                             };\r
             var unchanged = new[]{\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,Hash="aa4",Version=1,UUID="5",PreviousHash="aa4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="6",PreviousHash="aa1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="7",PreviousHash="aa2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="8",PreviousHash="aa1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="9",PreviousHash="aa2"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,Hash="aa3",Version=1,UUID="10",PreviousHash="aa3"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,Hash="aa4",Version=1,UUID="11",PreviousHash="aa4"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,Hash="aa1",Version=1,UUID="12",PreviousHash="aa1"},\r
-                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,Hash="aa2",Version=1,UUID="13",PreviousHash="aa2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont1",Name="Folder1/Name1",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="5",PreviousHash="aa4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="6",PreviousHash="aa1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont1",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="7",PreviousHash="aa2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="8",PreviousHash="aa1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="9",PreviousHash="aa2"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name3",Bytes=123,X_Object_Hash="aa3",Version=1,UUID="10",PreviousHash="aa3"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc1",Container="Cont2",Name="Name4",Bytes=123,X_Object_Hash="aa4",Version=1,UUID="11",PreviousHash="aa4"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name1",Bytes=123,X_Object_Hash="aa1",Version=1,UUID="12",PreviousHash="aa1"},\r
+                                new ObjectInfo{StorageUri=_testUri,Account="acc2",Container="Cont2",Name="Name2",Bytes=123,X_Object_Hash="aa2",Version=1,UUID="13",PreviousHash="aa2"},\r
                             };\r
             var differencer = d1.Post(_previous)\r
                 .Post(noModItems);\r
index 5b76a74..e87c455 100644 (file)
@@ -321,7 +321,7 @@ namespace Pithos.Core.Agents
             if (localState.ShortHash != shortHash)\r
                 return true;\r
             //If the top hashes differ, we have a change\r
-            return (localState.Checksum != cloudFile.Hash);\r
+            return (localState.Checksum != cloudFile.X_Object_Hash);\r
         }\r
 \r
         private static FileAgent GetFileAgent(AccountInfo accountInfo)\r
index 1468761..5b9fb0c 100644 (file)
@@ -331,15 +331,17 @@ namespace Pithos.Core.Agents
         {
             var rootDir = new DirectoryInfo(RootPath);
             //Ensure folders appear first, to allow folder processing as soon as possilbe
-            var monitoredFiles = (from file in rootDir.EnumerateDirectories(searchPattern, SearchOption.AllDirectories)
-                                 where !Ignore(file.FullName)
-                                 orderby file.FullName ascending 
-                                 select file)
+            var folders = (from file in rootDir.EnumerateDirectories(searchPattern, SearchOption.AllDirectories)
+                                     where !Ignore(file.FullName)
+                                     orderby file.FullName ascending
+                                     select file).ToList();
+            var files = (from file in rootDir.EnumerateFiles(searchPattern, SearchOption.AllDirectories)
+                                  where !Ignore(file.FullName)
+                                  orderby file.Length ascending
+                                  select file as FileSystemInfo).ToList();
+            var monitoredFiles = folders
                                  //Process small files first, leaving expensive large files for last
-                                 .Concat(from file in rootDir.EnumerateFiles(searchPattern, SearchOption.AllDirectories)
-                                         where !Ignore(file.FullName)
-                                         orderby file.Length ascending 
-                                         select file as FileSystemInfo);
+                                 .Concat(files);
             return monitoredFiles;
         }                
 
@@ -376,7 +378,8 @@ namespace Pithos.Core.Agents
                     return false;
             //Ignore if selective synchronization is defined, 
             //And the target file is not below any of the selective paths
-            return !Selectives.IsSelected(AccountInfo, filePath);
+            var ignore = !Selectives.IsSelected(AccountInfo, filePath);
+            return ignore;
         }
 
         public bool IsUnselectedRootFolder(string filePath)
index ece050a..f511614 100644 (file)
@@ -424,7 +424,7 @@ namespace Pithos.Core.Agents
                 var cloudFile = action.CloudFile;
                 var downloadPath = action.LocalFile.GetProperCapitalization();
 
-                var cloudHash = cloudFile.Hash.ToLower();
+                var cloudHash = cloudFile.X_Object_Hash.ToLower();
                 var previousCloudHash = cloudFile.PreviousHash == null?null: cloudFile.PreviousHash.ToLower();
                 var localHash = action.TreeHash.Value.TopHash.ToHashString();// LocalHash.Value.ToLower();
                 //var topHash = action.TopHash.Value.ToLower();
index d125987..ec33aac 100644 (file)
@@ -47,6 +47,7 @@ using System.Diagnostics.Contracts;
 using System.IO;\r
 using System.Linq.Expressions;\r
 using System.Reflection;\r
+using System.Security.Cryptography;\r
 using System.Threading;\r
 using System.Threading.Tasks;\r
 using Castle.ActiveRecord;\r
@@ -65,6 +66,8 @@ namespace Pithos.Core.Agents
     {\r
         public string FilePath { get; private set; }\r
 \r
+        public string MD5 { get; set; }\r
+\r
         public string L\r
         {\r
             get { return FileState==null?null:FileState.Checksum; }\r
@@ -74,7 +77,7 @@ namespace Pithos.Core.Agents
 \r
         public string S\r
         {\r
-            get { return ObjectInfo== null ? null : ObjectInfo.Hash; }\r
+            get { return ObjectInfo == null ? null : ObjectInfo.X_Object_Hash; }\r
         }\r
 \r
         private FileSystemInfo _fileInfo;\r
@@ -393,8 +396,12 @@ namespace Pithos.Core.Agents
                         foreach (var tuple in tuples)\r
                         {\r
                             await _unPauseEvent.WaitAsync();\r
-                            \r
+\r
+                            //Set the Merkle Hash\r
+                            SetMerkleHash(accountInfo, tuple);\r
+\r
                             SyncSingleItem(accountInfo, tuple, agent, token);\r
+\r
                         }\r
 \r
 \r
@@ -421,6 +428,24 @@ namespace Pithos.Core.Agents
             }\r
         }\r
 \r
+        private static void SetMerkleHash(AccountInfo accountInfo, StateTuple tuple)\r
+        {\r
+            //The Merkle hash for directories is that of an empty buffer\r
+            if (tuple.FileInfo is DirectoryInfo)\r
+                tuple.C = MERKLE_EMPTY;\r
+            else if (tuple.FileState != null && tuple.MD5 == tuple.FileState.ShortHash)\r
+            {\r
+                //If there is a state whose MD5 matches, load the merkle hash fromthe file state\r
+                //insteaf of calculating it\r
+                tuple.C = tuple.FileState.Checksum;                              \r
+            }\r
+            else\r
+            {\r
+                tuple.C=Signature.CalculateTreeHash(tuple.FileInfo, accountInfo.BlockSize, accountInfo.BlockHash)\r
+                                   .TopHash.ToHashString();\r
+            }\r
+        }\r
+\r
         private static List<Tuple<FileSystemInfo, string>> LoadLocalFileTuples(AccountInfo accountInfo)\r
         {\r
             using (ThreadContext.Stacks["Account Files Hashing"].Push(accountInfo.UserName))\r
@@ -429,6 +454,7 @@ namespace Pithos.Core.Agents
                 var localInfos = AgentLocator<FileAgent>.Get(accountInfo.AccountPath).EnumerateFileSystemInfos();\r
                 //Use the queue to retry locked file hashing\r
                 var fileQueue = new Queue<FileSystemInfo>(localInfos);\r
+                var hasher = MD5.Create();\r
 \r
                 var results = new List<Tuple<FileSystemInfo, string>>();\r
 \r
@@ -437,14 +463,24 @@ namespace Pithos.Core.Agents
                     var file = fileQueue.Dequeue();\r
                     using (ThreadContext.Stacks["File"].Push(file.FullName))\r
                     {\r
+                        /*\r
+                                                Signature.CalculateTreeHash(file, accountInfo.BlockSize,\r
+                                                                                                 accountInfo.BlockHash).\r
+                                                                         TopHash.ToHashString()\r
+                        */\r
                         try\r
                         {\r
-                            var hash = (file is DirectoryInfo)\r
-                                           ? "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"\r
-                                           : Signature.CalculateTreeHash(file, accountInfo.BlockSize,\r
-                                                                         accountInfo.BlockHash)\r
-                                                 .\r
-                                                 TopHash.ToHashString();\r
+                            //Replace MD5 here, do the calc while syncing individual files\r
+                            string hash ;\r
+                            if (file is DirectoryInfo)\r
+                                hash = MERKLE_EMPTY;\r
+                            else\r
+                            {\r
+                                using (var stream = (file as FileInfo).OpenRead())\r
+                                {\r
+                                    hash = hasher.ComputeHash(stream).ToHashString();\r
+                                }\r
+                            }                            \r
                             results.Add(Tuple.Create(file, hash));\r
                         }\r
                         catch (IOException exc)\r
@@ -504,8 +540,8 @@ namespace Pithos.Core.Agents
                                                                             tuple.ObjectInfo,\r
                                                                             localFilePath, token).Wait(token);\r
                             //updateRecord( L = S )\r
-                            StatusKeeper.UpdateFileChecksum(localFilePath, tuple.FileState==null?"":tuple.FileState.ShortHash,\r
-                                                            tuple.ObjectInfo.Hash);\r
+                            StatusKeeper.UpdateFileChecksum(localFilePath, tuple.ObjectInfo.ETag,\r
+                                                            tuple.ObjectInfo.X_Object_Hash);\r
 \r
                             StatusKeeper.SetFileState(localFilePath, FileStatus.Unchanged,\r
                                                       FileOverlayStatus.Normal, "");\r
@@ -559,8 +595,8 @@ namespace Pithos.Core.Agents
                         {\r
                             // (Identical Changes) Result: L = S\r
                             //doNothing()\r
-                            StatusKeeper.UpdateFileChecksum(localFilePath, tuple.FileState == null ? "" : tuple.FileState.ShortHash,\r
-                                                            tuple.ObjectInfo.Hash);\r
+                            StatusKeeper.UpdateFileChecksum(localFilePath, tuple.ObjectInfo.ETag,\r
+                                                            tuple.ObjectInfo.X_Object_Hash);\r
                             StatusKeeper.SetFileState(localFilePath, FileStatus.Unchanged,\r
                                                       FileOverlayStatus.Normal, "");\r
                         }\r
@@ -615,8 +651,9 @@ namespace Pithos.Core.Agents
             foreach (var file in files)\r
             {\r
                 var fsInfo = file.Item1;\r
-                var fileHash = file.Item2;\r
-                dct[fsInfo.FullName] = new StateTuple {FileInfo = fsInfo, C = fileHash};\r
+                var fileHash = fsInfo is DirectoryInfo? MERKLE_EMPTY:file.Item2;\r
+\r
+                dct[fsInfo.FullName] = new StateTuple {FileInfo = fsInfo, MD5 = fileHash};\r
             }\r
             foreach (var state in states)\r
             {\r
@@ -690,6 +727,7 @@ namespace Pithos.Core.Agents
         //readonly AccountsDifferencer _differencer = new AccountsDifferencer();\r
         private Dictionary<Uri, List<Uri>> _selectiveUris = new Dictionary<Uri, List<Uri>>();\r
         private bool _pause;\r
+        private static string MERKLE_EMPTY = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";\r
 \r
         /// <summary>\r
         /// Deletes local files that are not found in the list of cloud files\r
@@ -874,7 +912,7 @@ namespace Pithos.Core.Agents
                                                      previousFile, objectInfo, state, accountInfo.BlockSize,\r
                                                      accountInfo.BlockHash,"Poll Moves");\r
                         //For modified files, we need to download the changes as well\r
-                        if (objectInfo.Hash!=objectInfo.PreviousHash)\r
+                        if (objectInfo.X_Object_Hash != objectInfo.PreviousHash)\r
                             yield return new CloudDownloadAction(accountInfo,objectInfo, "Poll Moves");\r
                     }\r
                 }\r
index 8276051..3d527a7 100644 (file)
@@ -65,6 +65,22 @@ namespace Pithos.Core.Agents
             SelectivePaths[account.AccountKey] = UrisToFilePaths(account,uris);\r
         }\r
 \r
+        public void AddUri(AccountInfo account,Uri uri)\r
+        {\r
+            var accountPath = account.AccountPath;\r
+            var storageUrl = account.StorageUri.ToString();\r
+            var isShared=!uri.ToString().StartsWith(storageUrl);\r
+            var relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath();\r
+            \r
+            var fullPath=isShared\r
+                ?Path.Combine(accountPath, FolderConstants.OthersFolder, relativePath)\r
+                :Path.Combine(accountPath, relativePath.After(account.UserName + '\\'));\r
+            \r
+            SelectiveUris[account.AccountKey].Add(uri);\r
+            SelectivePaths[account.AccountKey].Add(fullPath);\r
+            \r
+        }\r
+\r
         public bool IsSelected(AccountInfo account,ObjectInfo info)\r
         {\r
             //Shared folders should NOT be synced if selective syncing is disabled\r
@@ -97,9 +113,9 @@ namespace Pithos.Core.Agents
                 return !isShared;\r
 \r
             List<string> paths;\r
-            return !SelectivePaths.TryGetValue(account.AccountKey, out paths)\r
-                || paths.Count == 0\r
-                || paths.Any(fullPath.IsAtOrDirectlyBelow);\r
+            var hasSelectives = SelectivePaths.TryGetValue(account.AccountKey, out paths);\r
+            var isSelected = !hasSelectives || paths.Count == 0 || paths.Any(fullPath.IsAtOrDirectlyBelow);\r
+            return isSelected;\r
         }\r
 \r
         /// <summary>\r
@@ -123,7 +139,7 @@ namespace Pithos.Core.Agents
                           where !uri.ToString().StartsWith(storageUrl)\r
                           let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath()\r
                           //Trim the account name\r
-                          select Path.Combine(accountPath, "others-shared", relativePath)).ToList();\r
+                          select Path.Combine(accountPath, FolderConstants.OthersFolder, relativePath)).ToList();\r
             return own.Union(others).ToList();\r
         }\r
 \r
index c340529..af8e311 100644 (file)
@@ -184,7 +184,7 @@ namespace Pithos.Core.Agents
             {\r
                 return Common.Where(info => \r
                     //The hash is different\r
-                    info.PreviousHash != info.Hash \r
+                    info.PreviousHash != info.X_Object_Hash \r
                     //And the Uri is unchanged or there is no previous version\r
                     && (info.Previous == null ||  info.Uri == info.Previous.Uri));\r
             }\r
@@ -195,7 +195,7 @@ namespace Pithos.Core.Agents
         /// </summary>\r
         public IEnumerable<ObjectInfo> Unchanged\r
         {\r
-            get{ return Common.Where(i => i.PreviousHash == i.Hash);}\r
+            get { return Common.Where(i => i.PreviousHash == i.X_Object_Hash); }\r
         }\r
 \r
         /// <summary>\r
index 9074160..b95645d 100644 (file)
@@ -672,8 +672,8 @@ namespace Pithos.Core.Agents
                     }
 
                     command.Parameters.AddWithValue("path", path);
-                    command.Parameters.AddWithValue("checksum", objectInfo.Hash);
-                    command.Parameters.AddWithValue("shortHash", "");
+                    command.Parameters.AddWithValue("checksum", objectInfo.X_Object_Hash);
+                    command.Parameters.AddWithValue("shortHash", objectInfo.ETag);
                     command.Parameters.AddWithValue("version", objectInfo.Version);
                     command.Parameters.AddWithValue("versionTimeStamp", objectInfo.VersionTimestamp);
                     command.Parameters.AddWithValue("fileStatus", FileStatus.Unchanged);
index 37c55be..136bbbf 100644 (file)
@@ -134,7 +134,7 @@ namespace Pithos.Core.Agents
                             if (fileInfo is DirectoryInfo)\r
                             {\r
                                 //If the directory doesn't exist the Hash property will be empty\r
-                                if (String.IsNullOrWhiteSpace(cloudInfo.Hash))\r
+                                if (String.IsNullOrWhiteSpace(cloudInfo.X_Object_Hash))\r
                                     //Go on and create the directory\r
                                     await client.PutObject(account, cloudFile.Container, cloudFile.Name, fullFileName,\r
                                                          String.Empty, "application/directory");\r
@@ -142,16 +142,15 @@ namespace Pithos.Core.Agents
                                 if (action.IsCreation)\r
                                 {\r
                                     //Add the folder to the Selected URls\r
-                                    var selections = Selectives.SelectiveUris[accountInfo.AccountKey];\r
                                     var selectiveUri = new Uri(client.RootAddressUri, cloudFile.Uri);\r
-                                    selections.Add(selectiveUri);\r
+                                    Selectives.AddUri(accountInfo, selectiveUri);                                    \r
                                     Selectives.Save(accountInfo);\r
                                 }\r
                             }\r
                             else\r
                             {\r
 \r
-                                var cloudHash = cloudInfo.Hash.ToLower();\r
+                                var cloudHash = cloudInfo.X_Object_Hash.ToLower();\r
 \r
                                 string topHash;\r
                                 TreeHash treeHash;\r
index 2006f3f..9d295eb 100644 (file)
@@ -14,14 +14,14 @@ namespace Pithos.Core
                 return false;
             if (x.CloudFile != null && y.CloudFile != null )
             {
-                if (x.CloudFile.Hash == null & y.CloudFile.Hash != null)
+                if (x.CloudFile.X_Object_Hash == null & y.CloudFile.X_Object_Hash != null)
                     return false;
-                if (x.CloudFile.Hash != null & y.CloudFile.Hash == null)
+                if (x.CloudFile.X_Object_Hash != null & y.CloudFile.X_Object_Hash == null)
                     return false;
-                if (x.CloudFile.Hash == null & y.CloudFile.Hash == null)
+                if (x.CloudFile.X_Object_Hash == null & y.CloudFile.X_Object_Hash == null)
                     return (x.CloudFile.Name == y.CloudFile.Name);
-                    
-                if (!x.CloudFile.Hash.Equals(y.CloudFile.Hash))
+
+                if (!x.CloudFile.X_Object_Hash.Equals(y.CloudFile.X_Object_Hash))
                     return false;
                 //All directories have the same hash. Compare them using their names instead
                 if (x.CloudFile.Content_Type == y.CloudFile.Content_Type && x.CloudFile.IsDirectory)
@@ -45,8 +45,8 @@ namespace Pithos.Core
             {
                 //All directories have the same hash code. Use their name's hash code instead
                 hash2 = obj.CloudFile.IsDirectory 
-                            ? obj.CloudFile.Name.GetHashCode() 
-                            : (obj.CloudFile.Hash ?? obj.CloudFile.Name ?? "").GetHashCode();
+                            ? obj.CloudFile.Name.GetHashCode()
+                            : (obj.CloudFile.X_Object_Hash ?? obj.CloudFile.Name ?? "").GetHashCode();
             }
             var hash3 = obj.Action.GetHashCode();
             return hash1 ^ hash2 & hash3;
index 7301002..1fa79d8 100644 (file)
@@ -58,11 +58,16 @@ namespace Pithos.Interfaces
         private readonly List<string> _knownContainers= new List<string>{"trash"};
         public string Name { get; set; }
 
+        [JsonProperty("hash")]
         public string ETag { get; set; }
 
-        public string Hash { get; set; }
+        //public string Hash { get; set; }
 
+/*
         public string X_Object_Hash { get { return Hash; } set { Hash = value; } }
+*/
+
+        public string X_Object_Hash { get; set; }
 
         [JsonProperty("x_object_uuid")]
         public string UUID { get; set; }
@@ -234,7 +239,8 @@ namespace Pithos.Interfaces
         public static ObjectInfo Empty = new ObjectInfo
         {
             Name = String.Empty,
-            Hash = String.Empty,
+            ETag= String.Empty,
+            X_Object_Hash= String.Empty,
             Bytes = 0,
             Content_Type = String.Empty,
             Last_Modified = DateTime.MinValue,
@@ -373,7 +379,7 @@ namespace Pithos.Interfaces
         public ObjectInfo SetPrevious(ObjectInfo previous)
         {            
             Previous = previous;
-            PreviousHash = previous.Hash;
+            PreviousHash = previous.X_Object_Hash;
             return this;
         }
 
index 151690c..b466aab 100644 (file)
@@ -41,10 +41,10 @@ namespace Pithos.Network.Test
 
 
                     var meta = client.GetObjectInfo(null, "Shares", "DeveloperGuide.pdf");
-                    Assert.IsNotEmpty(meta.Hash);
-                    
+                    Assert.IsNotEmpty(meta.X_Object_Hash);
+
 
-                    Assert.AreEqual(hash,meta.Hash,String.Format("The hashes don't match, expected {0} but got {1}",hash,meta.Hash));
+                    Assert.AreEqual(hash, meta.X_Object_Hash, String.Format("The hashes don't match, expected {0} but got {1}", hash, meta.X_Object_Hash));
                 
 
             });
index b4bf22f..d4a1227 100644 (file)
@@ -189,7 +189,7 @@ namespace Pithos.Network.Test
 
                 
                 var meta=client.GetObjectInfo(null, "Shares", filePath);
-                Assert.IsNotEmpty(meta.Hash);
+                Assert.IsNotEmpty(meta.X_Object_Hash);
                 Assert.AreEqual(meta.Name,filePath);
 
             });
index 63195f4..4dde04f 100644 (file)
@@ -92,6 +92,7 @@ namespace Pithos.Network
         }
 
         public List<Group> Groups { get; set; }
+
     }
 
     public class Group