PageRenderTime 143ms CodeModel.GetById 100ms app.highlight 8ms RepoModel.GetById 32ms app.codeStats 1ms

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