diff --git a/Assets/Editor/Tests/LocalMetaDataTest.cs b/Assets/Editor/Tests/LocalMetaDataTest.cs index 2518b636..33cb32b6 100644 --- a/Assets/Editor/Tests/LocalMetaDataTest.cs +++ b/Assets/Editor/Tests/LocalMetaDataTest.cs @@ -31,7 +31,7 @@ public void CreateMetaDataFile() var localMetaData = new LocalMetaData(_filePath, _deprecatedFilePath); - localMetaData.RegisterEntry("test", 1); + localMetaData.RegisterEntry("test", 1, 0, true); Assert.True(File.Exists(_filePath)); } @@ -41,8 +41,8 @@ public void SaveValidFileSinglePass() { var localMetaData = new LocalMetaData(_filePath, _deprecatedFilePath); - localMetaData.RegisterEntry("a", 1); - localMetaData.RegisterEntry("b", 2); + localMetaData.RegisterEntry("a", 1, 0 , true); + localMetaData.RegisterEntry("b", 2, 0 , true); var localMetaData2 = new LocalMetaData(_filePath, _deprecatedFilePath); diff --git a/Assets/PatchKit Patcher/Scripts/AppData/Local/ILocalMetaData.cs b/Assets/PatchKit Patcher/Scripts/AppData/Local/ILocalMetaData.cs index c641d941..4b402321 100644 --- a/Assets/PatchKit Patcher/Scripts/AppData/Local/ILocalMetaData.cs +++ b/Assets/PatchKit Patcher/Scripts/AppData/Local/ILocalMetaData.cs @@ -16,7 +16,9 @@ public interface ILocalMetaData /// /// Name of the entry. /// The version id. - void RegisterEntry(string entryName, int versionId); + /// Size of entry. + /// If set to true, it is last entry. + void RegisterEntry(string entryName, int versionId, long entrySize, bool isLastEntry); /// /// Unregisters the entry. diff --git a/Assets/PatchKit Patcher/Scripts/AppData/Local/LocalMetaData.cs b/Assets/PatchKit Patcher/Scripts/AppData/Local/LocalMetaData.cs index 185579f9..5a45594e 100644 --- a/Assets/PatchKit Patcher/Scripts/AppData/Local/LocalMetaData.cs +++ b/Assets/PatchKit Patcher/Scripts/AppData/Local/LocalMetaData.cs @@ -20,7 +20,9 @@ namespace PatchKit.Unity.Patcher.AppData.Local public class LocalMetaData : ILocalMetaData { private readonly ILogger _logger; + private long _unsavedEntriesSize = 0; private const string DeprecatedCachePatchKitKey = "patchkit-key"; + private const long UnsavedEntriesSizeLimit = 104857600; //100MiB /// /// Data structure stored in file. @@ -79,7 +81,7 @@ public string[] GetRegisteredEntries() return _data.FileVersionIds.Select(pair => pair.Key).ToArray(); } - public void RegisterEntry([NotNull] string entryName, int versionId) + public void RegisterEntry([NotNull] string entryName, int versionId, long entrySize, bool isLastEntry) { if (entryName == null) { @@ -103,7 +105,10 @@ public void RegisterEntry([NotNull] string entryName, int versionId) _data.FileVersionIds[entryName] = versionId; - SaveData(); + if (ShouldSaveEntry(entrySize, isLastEntry)) + { + SaveData(); + } _logger.LogDebug("Entry registered."); } @@ -114,6 +119,22 @@ public void RegisterEntry([NotNull] string entryName, int versionId) } } + private bool ShouldSaveEntry(long entrySize, bool isLastEntry) + { + if (isLastEntry) + { + return true; + } + + _unsavedEntriesSize += entrySize; + if (_unsavedEntriesSize > UnsavedEntriesSizeLimit) + { + _unsavedEntriesSize = 0; + return true; + } + return false; + } + public void UnregisterEntry([NotNull] string entryName) { if (entryName == null) @@ -183,10 +204,14 @@ public string GetProductKey() public void SetMainExecutableAndArgs(string mainExecutable, string mainExecutableArgs) { - _data.MainExecutable = mainExecutable; - _data.MainExecutableArgs = mainExecutableArgs; + if (_data.MainExecutable != mainExecutable || + _data.MainExecutableArgs != mainExecutableArgs) + { + _data.MainExecutable = mainExecutable; + _data.MainExecutableArgs = mainExecutableArgs; - SaveData(); + SaveData(); + } } public string GetMainExecutable() diff --git a/Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdaterRepairStrategy.cs b/Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdaterRepairStrategy.cs index 027ff6db..8b070d7e 100644 --- a/Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdaterRepairStrategy.cs +++ b/Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdaterRepairStrategy.cs @@ -84,10 +84,11 @@ ICheckVersionIntegrityCommand checkVersionIntegrityCommand var contentSummary = _context.App.RemoteMetaData.GetContentSummary(installedVersionId, cancellationToken); - foreach (var invalidVersionIdFile in filesIntegrity.Where(x => - x.Status == FileIntegrityStatus.InvalidVersion).ToArray()) + var filesIntegrityWithInvalidVersion = filesIntegrity.Where(x => + x.Status == FileIntegrityStatus.InvalidVersion).ToArray(); + for (int i = 0; i < filesIntegrityWithInvalidVersion.Length; i++) { - var fileName = invalidVersionIdFile.FileName; + var fileName = filesIntegrityWithInvalidVersion[i].FileName; var file = contentSummary.Files.First(x => x.Path == fileName); var localPath = _context.App.LocalDirectory.Path.PathCombine(file.Path); @@ -96,13 +97,15 @@ ICheckVersionIntegrityCommand checkVersionIntegrityCommand if (actualFileHash != file.Hash) { FileOperations.Delete(localPath, cancellationToken); - _context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId); - invalidVersionIdFile.Status = FileIntegrityStatus.MissingData; + _context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId, file.Size, + i == filesIntegrityWithInvalidVersion.Length - 1); + filesIntegrityWithInvalidVersion[i].Status = FileIntegrityStatus.MissingData; } else { - _context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId); - invalidVersionIdFile.Status = FileIntegrityStatus.Ok; + _context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId, file.Size, + i == filesIntegrityWithInvalidVersion.Length - 1); + filesIntegrityWithInvalidVersion[i].Status = FileIntegrityStatus.Ok; } } diff --git a/Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallContentCommand.cs b/Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallContentCommand.cs index 129b0252..04eb8861 100644 --- a/Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallContentCommand.cs +++ b/Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallContentCommand.cs @@ -138,11 +138,12 @@ public override void Execute(CancellationToken cancellationToken) for (int i = 0; i < _versionContentSummary.Files.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); + string filePath = _versionContentSummary.Files[i].Path; string nameHash; if (mapHashExtractedFiles.TryGetHash(filePath, out nameHash)) { - var sourceFile = new SourceFile(filePath, packageDir.Path, usedSuffix, nameHash); + var sourceFile = new SourceFile(filePath, packageDir.Path, usedSuffix, nameHash, _versionContentSummary.Size); if (unarchiver.HasErrors && !sourceFile.Exists()) // allow unexistent file only if does not have errors { @@ -152,7 +153,7 @@ public override void Execute(CancellationToken cancellationToken) } else { - InstallFile(sourceFile, cancellationToken); + InstallFile(sourceFile, cancellationToken, i == _versionContentSummary.Files.Length - 1); } } else @@ -185,7 +186,7 @@ private IUnarchiver CreateUnrachiver(string destinationDir, MapHashExtractedFile } } - private void InstallFile(SourceFile sourceFile, CancellationToken cancellationToken) + private void InstallFile(SourceFile sourceFile, CancellationToken cancellationToken, bool isLastEntry) { DebugLogger.Log(string.Format("Installing file {0}", sourceFile.Name)); @@ -202,6 +203,7 @@ private void InstallFile(SourceFile sourceFile, CancellationToken cancellationTo DebugLogger.LogFormat("Destination file {0} already exists, removing it.", destinationFilePath); FileOperations.Delete(destinationFilePath, cancellationToken); } + #if UNITY_STANDALONE_WIN if (destinationFilePath.Length > 259) { @@ -209,19 +211,20 @@ private void InstallFile(SourceFile sourceFile, CancellationToken cancellationTo } #endif FileOperations.Move(sourceFile.FullHashPath, destinationFilePath, cancellationToken); - _localMetaData.RegisterEntry(sourceFile.Name, _versionId); + _localMetaData.RegisterEntry(sourceFile.Name, _versionId, sourceFile.Size, isLastEntry); } struct SourceFile { public string Name { get; private set; } + public long Size { get; private set; } public string HashName { get; private set; } private string _suffix; private string _root; public string FullHashPath { get { return Path.Combine(_root, HashName + _suffix); } } - public SourceFile(string name, string root, string suffix, string hashName) + public SourceFile(string name, string root, string suffix, string hashName, long size) { Assert.IsNotNull(name); Assert.IsNotNull(root); @@ -229,6 +232,7 @@ public SourceFile(string name, string root, string suffix, string hashName) Assert.IsNotNull(hashName); Name = name; + Size = size; _root = root; _suffix = suffix; HashName = hashName; diff --git a/Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallDiffCommand.cs b/Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallDiffCommand.cs index 439e9f82..19f9439b 100644 --- a/Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallDiffCommand.cs +++ b/Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallDiffCommand.cs @@ -432,7 +432,7 @@ private void ProcessAddedFiles(string packageDirPath, string suffix, } else { - AddFile(entryName, packageDirPath, suffix, cancellationToken); + AddFile(entryName, packageDirPath, suffix, cancellationToken, i); } _addFilesStatusReporter.Progress.Value = (i + 1) / (double) _diffSummary.AddedFiles.Length; @@ -459,7 +459,8 @@ private void AddDirectory(string dirName, CancellationToken cancellationToken) _logger.LogDebug("Add directory entry processed."); } - private void AddFile(string fileName, string packageDirPath, string suffix, CancellationToken cancellationToken) + private void AddFile(string fileName, string packageDirPath, string suffix, CancellationToken cancellationToken, + int fileIndex) { _logger.LogDebug(string.Format("Processing add file entry {0}", fileName)); @@ -482,7 +483,7 @@ private void AddFile(string fileName, string packageDirPath, string suffix, Canc throw new MissingFileFromPackageException(string.Format("Cannot find file {0} in diff package.", fileName)); } - + _logger.LogDebug("Creating file parent directories in local data..."); var fileParentDirPath = Path.GetDirectoryName(filePath); _logger.LogTrace("fileParentDirPath = " + fileParentDirPath); @@ -495,7 +496,9 @@ private void AddFile(string fileName, string packageDirPath, string suffix, Canc FileOperations.Copy(sourceFilePath, filePath, true, cancellationToken); _logger.LogDebug("File copied to local data."); - _localMetaData.RegisterEntry(fileName, _versionId); + _localMetaData.RegisterEntry(fileName, _versionId, + _contentSummary.Files.First(x => x.Path == fileName).Size, + fileIndex == _diffSummary.AddedFiles.Length - 1); _logger.LogDebug("Add file entry processed."); } @@ -521,7 +524,7 @@ private void ProcessModifiedFiles(string packageDirPath, string suffix, Temporar if (!entryName.EndsWith("/")) { - PatchFile(entryName, packageDirPath, suffix, tempDiffDir, cancellationToken); + PatchFile(entryName, packageDirPath, suffix, tempDiffDir, cancellationToken, i); } _modifiedFilesStatusReporter.Progress.Value = (i + 1) / (double) _diffSummary.ModifiedFiles.Length; @@ -537,7 +540,7 @@ private void ProcessModifiedFiles(string packageDirPath, string suffix, Temporar private void PatchFile( string fileName, string packageDirPath, string suffix, - TemporaryDirectory tempDiffDir, CancellationToken cancellationToken) + TemporaryDirectory tempDiffDir, CancellationToken cancellationToken, int fileIndex) { _logger.LogDebug(string.Format("Processing patch file entry {0}", fileName)); @@ -592,8 +595,10 @@ private void PatchFile( { _logger.LogDebug("Patching is not necessary. File content is the same as in previous version."); } - - _localMetaData.RegisterEntry(fileName, _versionId); + + _localMetaData.RegisterEntry(fileName, _versionId, + _contentSummary.Files.First(x => x.Path == fileName).Size, + fileIndex == _diffSummary.ModifiedFiles.Length - 1); _logger.LogDebug("Patch file entry processed."); } diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e3a69e8..d109aaca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Checking path length on Windows - Support for HDPI +### Changed +- Speed up the installation/patching process due to less frequent meta data saving + ### Fixed - Paths too long when unpacking (#2156)