Skip to content

Commit b0bc89e

Browse files
Szczyrkwitcher112JakubSzczyrk
authored
Experimental/optimized app data writing (#162)
* Restriction on saving the app_dat.json file * fixed naming * code refactoring * fix last entry from diff * lastEntry to isLastEntry * Saving executable name and arguments - only when changed. Update Changelog * Refactoring * Update CHANGELOG.md Co-authored-by: Tomasz Jaworski <[email protected]> Co-authored-by: JakubSzczyrk <[email protected]> Co-authored-by: Jakub Szczyrk <Jakub Szczyrk>
1 parent bbf771b commit b0bc89e

File tree

7 files changed

+71
-29
lines changed

7 files changed

+71
-29
lines changed

Assets/Editor/Tests/LocalMetaDataTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void CreateMetaDataFile()
3131

3232
var localMetaData = new LocalMetaData(_filePath, _deprecatedFilePath);
3333

34-
localMetaData.RegisterEntry("test", 1);
34+
localMetaData.RegisterEntry("test", 1, 0, true);
3535

3636
Assert.True(File.Exists(_filePath));
3737
}
@@ -41,8 +41,8 @@ public void SaveValidFileSinglePass()
4141
{
4242
var localMetaData = new LocalMetaData(_filePath, _deprecatedFilePath);
4343

44-
localMetaData.RegisterEntry("a", 1);
45-
localMetaData.RegisterEntry("b", 2);
44+
localMetaData.RegisterEntry("a", 1, 0 , true);
45+
localMetaData.RegisterEntry("b", 2, 0 , true);
4646

4747
var localMetaData2 = new LocalMetaData(_filePath, _deprecatedFilePath);
4848

Assets/PatchKit Patcher/Scripts/AppData/Local/ILocalMetaData.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ public interface ILocalMetaData
1616
/// </summary>
1717
/// <param name="entryName">Name of the entry.</param>
1818
/// <param name="versionId">The version id.</param>
19-
void RegisterEntry(string entryName, int versionId);
19+
/// <param name="entrySize">Size of entry.</param>
20+
/// <param name="isLastEntry">If set to true, it is last entry.</param>
21+
void RegisterEntry(string entryName, int versionId, long entrySize, bool isLastEntry);
2022

2123
/// <summary>
2224
/// Unregisters the entry.

Assets/PatchKit Patcher/Scripts/AppData/Local/LocalMetaData.cs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ namespace PatchKit.Unity.Patcher.AppData.Local
2020
public class LocalMetaData : ILocalMetaData
2121
{
2222
private readonly ILogger _logger;
23+
private long _unsavedEntriesSize = 0;
2324
private const string DeprecatedCachePatchKitKey = "patchkit-key";
25+
private const long UnsavedEntriesSizeLimit = 104857600; //100MiB
2426

2527
/// <summary>
2628
/// Data structure stored in file.
@@ -79,7 +81,7 @@ public string[] GetRegisteredEntries()
7981
return _data.FileVersionIds.Select(pair => pair.Key).ToArray();
8082
}
8183

82-
public void RegisterEntry([NotNull] string entryName, int versionId)
84+
public void RegisterEntry([NotNull] string entryName, int versionId, long entrySize, bool isLastEntry)
8385
{
8486
if (entryName == null)
8587
{
@@ -103,7 +105,10 @@ public void RegisterEntry([NotNull] string entryName, int versionId)
103105

104106
_data.FileVersionIds[entryName] = versionId;
105107

106-
SaveData();
108+
if (ShouldSaveEntry(entrySize, isLastEntry))
109+
{
110+
SaveData();
111+
}
107112

108113
_logger.LogDebug("Entry registered.");
109114
}
@@ -114,6 +119,22 @@ public void RegisterEntry([NotNull] string entryName, int versionId)
114119
}
115120
}
116121

122+
private bool ShouldSaveEntry(long entrySize, bool isLastEntry)
123+
{
124+
if (isLastEntry)
125+
{
126+
return true;
127+
}
128+
129+
_unsavedEntriesSize += entrySize;
130+
if (_unsavedEntriesSize > UnsavedEntriesSizeLimit)
131+
{
132+
_unsavedEntriesSize = 0;
133+
return true;
134+
}
135+
return false;
136+
}
137+
117138
public void UnregisterEntry([NotNull] string entryName)
118139
{
119140
if (entryName == null)
@@ -183,10 +204,14 @@ public string GetProductKey()
183204

184205
public void SetMainExecutableAndArgs(string mainExecutable, string mainExecutableArgs)
185206
{
186-
_data.MainExecutable = mainExecutable;
187-
_data.MainExecutableArgs = mainExecutableArgs;
207+
if (_data.MainExecutable != mainExecutable ||
208+
_data.MainExecutableArgs != mainExecutableArgs)
209+
{
210+
_data.MainExecutable = mainExecutable;
211+
_data.MainExecutableArgs = mainExecutableArgs;
188212

189-
SaveData();
213+
SaveData();
214+
}
190215
}
191216

192217
public string GetMainExecutable()

Assets/PatchKit Patcher/Scripts/AppUpdater/AppUpdaterRepairStrategy.cs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@ ICheckVersionIntegrityCommand checkVersionIntegrityCommand
8484

8585
var contentSummary = _context.App.RemoteMetaData.GetContentSummary(installedVersionId, cancellationToken);
8686

87-
foreach (var invalidVersionIdFile in filesIntegrity.Where(x =>
88-
x.Status == FileIntegrityStatus.InvalidVersion).ToArray())
87+
var filesIntegrityWithInvalidVersion = filesIntegrity.Where(x =>
88+
x.Status == FileIntegrityStatus.InvalidVersion).ToArray();
89+
for (int i = 0; i < filesIntegrityWithInvalidVersion.Length; i++)
8990
{
90-
var fileName = invalidVersionIdFile.FileName;
91+
var fileName = filesIntegrityWithInvalidVersion[i].FileName;
9192
var file = contentSummary.Files.First(x => x.Path == fileName);
9293

9394
var localPath = _context.App.LocalDirectory.Path.PathCombine(file.Path);
@@ -96,13 +97,15 @@ ICheckVersionIntegrityCommand checkVersionIntegrityCommand
9697
if (actualFileHash != file.Hash)
9798
{
9899
FileOperations.Delete(localPath, cancellationToken);
99-
_context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId);
100-
invalidVersionIdFile.Status = FileIntegrityStatus.MissingData;
100+
_context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId, file.Size,
101+
i == filesIntegrityWithInvalidVersion.Length - 1);
102+
filesIntegrityWithInvalidVersion[i].Status = FileIntegrityStatus.MissingData;
101103
}
102104
else
103105
{
104-
_context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId);
105-
invalidVersionIdFile.Status = FileIntegrityStatus.Ok;
106+
_context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId, file.Size,
107+
i == filesIntegrityWithInvalidVersion.Length - 1);
108+
filesIntegrityWithInvalidVersion[i].Status = FileIntegrityStatus.Ok;
106109
}
107110
}
108111

Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallContentCommand.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,12 @@ public override void Execute(CancellationToken cancellationToken)
138138
for (int i = 0; i < _versionContentSummary.Files.Length; i++)
139139
{
140140
cancellationToken.ThrowIfCancellationRequested();
141+
141142
string filePath = _versionContentSummary.Files[i].Path;
142143
string nameHash;
143144
if (mapHashExtractedFiles.TryGetHash(filePath, out nameHash))
144145
{
145-
var sourceFile = new SourceFile(filePath, packageDir.Path, usedSuffix, nameHash);
146+
var sourceFile = new SourceFile(filePath, packageDir.Path, usedSuffix, nameHash, _versionContentSummary.Size);
146147

147148
if (unarchiver.HasErrors && !sourceFile.Exists()) // allow unexistent file only if does not have errors
148149
{
@@ -152,7 +153,7 @@ public override void Execute(CancellationToken cancellationToken)
152153
}
153154
else
154155
{
155-
InstallFile(sourceFile, cancellationToken);
156+
InstallFile(sourceFile, cancellationToken, i == _versionContentSummary.Files.Length - 1);
156157
}
157158
}
158159
else
@@ -185,7 +186,7 @@ private IUnarchiver CreateUnrachiver(string destinationDir, MapHashExtractedFile
185186
}
186187
}
187188

188-
private void InstallFile(SourceFile sourceFile, CancellationToken cancellationToken)
189+
private void InstallFile(SourceFile sourceFile, CancellationToken cancellationToken, bool isLastEntry)
189190
{
190191
DebugLogger.Log(string.Format("Installing file {0}", sourceFile.Name));
191192

@@ -202,33 +203,36 @@ private void InstallFile(SourceFile sourceFile, CancellationToken cancellationTo
202203
DebugLogger.LogFormat("Destination file {0} already exists, removing it.", destinationFilePath);
203204
FileOperations.Delete(destinationFilePath, cancellationToken);
204205
}
206+
205207
#if UNITY_STANDALONE_WIN
206208
if (destinationFilePath.Length > 259)
207209
{
208210
throw new FilePathTooLongException(string.Format("Cannot install file {0}, the destination path length has exceeded Windows path length limit (260).", destinationFilePath));
209211
}
210212
#endif
211213
FileOperations.Move(sourceFile.FullHashPath, destinationFilePath, cancellationToken);
212-
_localMetaData.RegisterEntry(sourceFile.Name, _versionId);
214+
_localMetaData.RegisterEntry(sourceFile.Name, _versionId, sourceFile.Size, isLastEntry);
213215
}
214216

215217
struct SourceFile
216218
{
217219
public string Name { get; private set; }
220+
public long Size { get; private set; }
218221
public string HashName { get; private set; }
219222
private string _suffix;
220223
private string _root;
221224

222225
public string FullHashPath { get { return Path.Combine(_root, HashName + _suffix); } }
223226

224-
public SourceFile(string name, string root, string suffix, string hashName)
227+
public SourceFile(string name, string root, string suffix, string hashName, long size)
225228
{
226229
Assert.IsNotNull(name);
227230
Assert.IsNotNull(root);
228231
Assert.IsNotNull(suffix);
229232
Assert.IsNotNull(hashName);
230233

231234
Name = name;
235+
Size = size;
232236
_root = root;
233237
_suffix = suffix;
234238
HashName = hashName;

Assets/PatchKit Patcher/Scripts/AppUpdater/Commands/InstallDiffCommand.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ private void ProcessAddedFiles(string packageDirPath, string suffix,
432432
}
433433
else
434434
{
435-
AddFile(entryName, packageDirPath, suffix, cancellationToken);
435+
AddFile(entryName, packageDirPath, suffix, cancellationToken, i);
436436
}
437437

438438
_addFilesStatusReporter.Progress.Value = (i + 1) / (double) _diffSummary.AddedFiles.Length;
@@ -459,7 +459,8 @@ private void AddDirectory(string dirName, CancellationToken cancellationToken)
459459
_logger.LogDebug("Add directory entry processed.");
460460
}
461461

462-
private void AddFile(string fileName, string packageDirPath, string suffix, CancellationToken cancellationToken)
462+
private void AddFile(string fileName, string packageDirPath, string suffix, CancellationToken cancellationToken,
463+
int fileIndex)
463464
{
464465
_logger.LogDebug(string.Format("Processing add file entry {0}", fileName));
465466

@@ -482,7 +483,7 @@ private void AddFile(string fileName, string packageDirPath, string suffix, Canc
482483
throw new MissingFileFromPackageException(string.Format("Cannot find file {0} in diff package.",
483484
fileName));
484485
}
485-
486+
486487
_logger.LogDebug("Creating file parent directories in local data...");
487488
var fileParentDirPath = Path.GetDirectoryName(filePath);
488489
_logger.LogTrace("fileParentDirPath = " + fileParentDirPath);
@@ -495,7 +496,9 @@ private void AddFile(string fileName, string packageDirPath, string suffix, Canc
495496
FileOperations.Copy(sourceFilePath, filePath, true, cancellationToken);
496497
_logger.LogDebug("File copied to local data.");
497498

498-
_localMetaData.RegisterEntry(fileName, _versionId);
499+
_localMetaData.RegisterEntry(fileName, _versionId,
500+
_contentSummary.Files.First(x => x.Path == fileName).Size,
501+
fileIndex == _diffSummary.AddedFiles.Length - 1);
499502

500503
_logger.LogDebug("Add file entry processed.");
501504
}
@@ -521,7 +524,7 @@ private void ProcessModifiedFiles(string packageDirPath, string suffix, Temporar
521524

522525
if (!entryName.EndsWith("/"))
523526
{
524-
PatchFile(entryName, packageDirPath, suffix, tempDiffDir, cancellationToken);
527+
PatchFile(entryName, packageDirPath, suffix, tempDiffDir, cancellationToken, i);
525528
}
526529

527530
_modifiedFilesStatusReporter.Progress.Value = (i + 1) / (double) _diffSummary.ModifiedFiles.Length;
@@ -537,7 +540,7 @@ private void ProcessModifiedFiles(string packageDirPath, string suffix, Temporar
537540

538541
private void PatchFile(
539542
string fileName, string packageDirPath, string suffix,
540-
TemporaryDirectory tempDiffDir, CancellationToken cancellationToken)
543+
TemporaryDirectory tempDiffDir, CancellationToken cancellationToken, int fileIndex)
541544
{
542545
_logger.LogDebug(string.Format("Processing patch file entry {0}", fileName));
543546

@@ -592,8 +595,10 @@ private void PatchFile(
592595
{
593596
_logger.LogDebug("Patching is not necessary. File content is the same as in previous version.");
594597
}
595-
596-
_localMetaData.RegisterEntry(fileName, _versionId);
598+
599+
_localMetaData.RegisterEntry(fileName, _versionId,
600+
_contentSummary.Files.First(x => x.Path == fileName).Size,
601+
fileIndex == _diffSummary.ModifiedFiles.Length - 1);
597602

598603
_logger.LogDebug("Patch file entry processed.");
599604
}

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99
- Checking path length on Windows
1010
- Support for HDPI
1111

12+
### Changed
13+
- Speed up the installation/patching process due to less frequent meta data saving
14+
1215
### Fixed
1316
- Paths too long when unpacking (#2156)
1417

0 commit comments

Comments
 (0)