PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Raven.Database/Server/RavenFS/Infrastructure/Historian.cs

https://github.com/nwendel/ravendb
C# | 109 lines | 92 code | 15 blank | 2 comment | 3 complexity | 1644dc12e8a1c3d20d7d1959862961b5 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, CC-BY-SA-3.0
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using System.Collections.Specialized;
  5. using System.Globalization;
  6. using System.IO;
  7. using System.Text;
  8. using Newtonsoft.Json;
  9. using Raven.Database.Server.RavenFS.Extensions;
  10. using Raven.Database.Server.RavenFS.Storage;
  11. using Raven.Database.Server.RavenFS.Storage.Esent;
  12. using Raven.Database.Server.RavenFS.Synchronization;
  13. using Raven.Json.Linq;
  14. using Raven.Abstractions.Extensions;
  15. using Raven.Abstractions.FileSystem;
  16. using Raven.Abstractions.Data;
  17. namespace Raven.Database.Server.RavenFS.Infrastructure
  18. {
  19. public class Historian
  20. {
  21. private readonly ITransactionalStorage storage;
  22. private readonly SynchronizationHiLo synchronizationHiLo;
  23. private readonly UuidGenerator uuidGenerator;
  24. public Historian(ITransactionalStorage storage, SynchronizationHiLo synchronizationHiLo, UuidGenerator uuidGenerator)
  25. {
  26. this.storage = storage;
  27. this.uuidGenerator = uuidGenerator;
  28. this.synchronizationHiLo = synchronizationHiLo;
  29. }
  30. public void Update(string fileName, RavenJObject sourceMetadata)
  31. {
  32. var fileMetadata = GetMetadata(fileName);
  33. var serverId = fileMetadata.Value<string>(SynchronizationConstants.RavenSynchronizationSource);
  34. var history = new List<HistoryItem>();
  35. // if there is RavenReplicationVersion metadata it means that file is not new and we have to add a new item to the history
  36. if (!String.IsNullOrEmpty(serverId))
  37. {
  38. var currentVersion = fileMetadata.Value<long>(SynchronizationConstants.RavenSynchronizationVersion);
  39. history = DeserializeHistory(fileMetadata);
  40. history.Add(new HistoryItem { ServerId = serverId, Version = currentVersion });
  41. }
  42. if (history.Count > SynchronizationConstants.ChangeHistoryLength)
  43. history.RemoveAt(0);
  44. sourceMetadata[SynchronizationConstants.RavenSynchronizationHistory] = SerializeHistory(history);
  45. sourceMetadata[SynchronizationConstants.RavenSynchronizationVersion] = synchronizationHiLo.NextId();
  46. sourceMetadata[SynchronizationConstants.RavenSynchronizationSource] = new RavenJValue(storage.Id);
  47. }
  48. public void UpdateLastModified(RavenJObject metadata)
  49. {
  50. // internally keep last modified date with millisecond precision
  51. metadata[Constants.LastModified] = DateTimeOffset.UtcNow;
  52. metadata[Constants.MetadataEtagField] = new RavenJValue(uuidGenerator.CreateSequentialUuid());
  53. }
  54. private RavenJObject GetMetadata(string fileName)
  55. {
  56. try
  57. {
  58. FileAndPagesInformation fileAndPages = null;
  59. storage.Batch(accessor => fileAndPages = accessor.GetFile(fileName, 0, 0));
  60. return fileAndPages.Metadata;
  61. }
  62. catch (FileNotFoundException)
  63. {
  64. return new RavenJObject();
  65. }
  66. }
  67. public static List<HistoryItem> DeserializeHistory(RavenJObject metadata)
  68. {
  69. var history = new List<HistoryItem>();
  70. if (metadata.ContainsKey(SynchronizationConstants.RavenSynchronizationHistory))
  71. {
  72. var array = (RavenJArray) metadata[SynchronizationConstants.RavenSynchronizationHistory];
  73. var items = array.Values<RavenJObject>().Select(x => JsonExtensions.JsonDeserialization<HistoryItem>(x));
  74. return new List<HistoryItem>(items);
  75. }
  76. return history;
  77. }
  78. public static RavenJArray SerializeHistory(List<HistoryItem> history)
  79. {
  80. return JsonExtensions.ToJArray(history);
  81. }
  82. public static bool IsDirectChildOfCurrent(RavenJObject destinationMetadata, RavenJObject sourceMetadata)
  83. {
  84. long destVersion = destinationMetadata.Value<long>(SynchronizationConstants.RavenSynchronizationVersion);
  85. var destServerId = destinationMetadata.Value<string>(SynchronizationConstants.RavenSynchronizationSource);
  86. var version = new HistoryItem { ServerId = destServerId, Version = destVersion };
  87. var history = DeserializeHistory(sourceMetadata);
  88. long sourceVersion = sourceMetadata.Value<long>(SynchronizationConstants.RavenSynchronizationVersion);
  89. var sourceServerId = sourceMetadata.Value<string>(SynchronizationConstants.RavenSynchronizationSource);
  90. history.Add(new HistoryItem { ServerId = sourceServerId, Version = sourceVersion });
  91. return history.Contains(version);
  92. }
  93. }
  94. }