Ejemplo n.º 1
0
        /// <summary>
        /// Loads previous versions stored from the specified file path.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <returns>FileVersionTracker.</returns>
        public static FileVersionTracker Load(string filePath)
        {
            // Try to compact it before using it
            FileVersionStorage.Compact(filePath);

            bool isFirstPass = true;

            while (true)
            {
                FileStream fileStream = null;

                // Try to open the file, if we get an exception, this might be due only because someone is locking the file to
                // save it while we are trying to open it
                const int RetryOpenFileStream = 20;
                var       random = new Random();
                for (int i = 0; i < RetryOpenFileStream; i++)
                {
                    try
                    {
                        fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                        break;
                    }
                    catch (Exception)
                    {
                        if ((i + 1) == RetryOpenFileStream)
                        {
                            throw;
                        }

                        Thread.Sleep(50 + random.Next(100));
                    }
                }

                var tracker = new FileVersionTracker(fileStream);
                try
                {
                    tracker.storage.LoadNewValues();
                    return(tracker);
                }
                catch (Exception)
                {
                    // If an exception occurred, we are going to try to recover from it by reseting it.
                    // reset file length to 0
                    fileStream.SetLength(0);
                    tracker.Dispose();
                    if (!isFirstPass)
                    {
                        throw;
                    }
                }
                isFirstPass = false;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Compacts the specified storage path.
        /// </summary>
        /// <param name="storagePath">The storage path.</param>
        /// <returns><c>true</c> if the storage path was successfully compacted, <c>false</c> otherwise.</returns>
        public static bool Compact(string storagePath)
        {
            FileStream fileStreamExclusive;

            try
            {
                fileStreamExclusive = new FileStream(storagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
            }
            catch (Exception)
            {
                return(false);
            }

            try
            {
                using (var localTracker = new FileVersionStorage(fileStreamExclusive)
                {
                    UseTransaction = true, AutoLoadNewValues = false
                })
                {
                    localTracker.LoadNewValues();
                    var latestVersion = new Dictionary <string, KeyValuePair <FileVersionKey, ObjectId> >(StringComparer.OrdinalIgnoreCase);
                    foreach (var keyValue in localTracker.GetValues())
                    {
                        var filePath = keyValue.Key.Path;
                        KeyValuePair <FileVersionKey, ObjectId> previousKeyValue;
                        if (!latestVersion.TryGetValue(filePath, out previousKeyValue) || keyValue.Key.LastModifiedDate > previousKeyValue.Key.LastModifiedDate)
                        {
                            latestVersion[filePath] = keyValue;
                        }
                    }
                    localTracker.Reset();
                    localTracker.AddValues(latestVersion.Values);
                    localTracker.Save();
                }
            }
            catch (Exception)
            {
                return(false);
            }
            return(true);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FileVersionTracker"/> class.
 /// </summary>
 /// <param name="stream">The stream.</param>
 public FileVersionTracker(Stream stream)
 {
     storage = new FileVersionStorage(stream);
     locks   = new Dictionary <FileVersionKey, object>();
 }