Initialize migration. (#88)
Co-authored-by: defnotken <itsdefnotken@gmail.com> Co-authored-by: cake <admin@cakeandbanana.nl> Reviewed-on: #88 Reviewed-by: cake <cake@noreply.git.lightless-sync.org> Co-authored-by: defnotken <defnotken@noreply.git.lightless-sync.org> Co-committed-by: defnotken <defnotken@noreply.git.lightless-sync.org>
This commit was merged in pull request #88.
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
using LightlessSync.API.Data;
|
||||
using LightlessSync.API.Data.Enum;
|
||||
using LightlessSync.FileCache;
|
||||
using LightlessSync.Services.CharaData;
|
||||
using LightlessSync.Services.CharaData.Models;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using LightlessSync.UI;
|
||||
using LightlessSync.Utils;
|
||||
using Lumina.Data.Files;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
namespace LightlessSync.Services;
|
||||
|
||||
public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
|
||||
@@ -51,31 +49,47 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
|
||||
_analysisCts = _analysisCts?.CancelRecreate() ?? new();
|
||||
var cancelToken = _analysisCts.Token;
|
||||
var allFiles = LastAnalysis.SelectMany(v => v.Value.Select(d => d.Value)).ToList();
|
||||
if (allFiles.Exists(c => !c.IsComputed || recalculate))
|
||||
|
||||
var remaining = allFiles.Where(c => !c.IsComputed || recalculate).ToList();
|
||||
|
||||
if (remaining.Count == 0)
|
||||
return;
|
||||
|
||||
TotalFiles = remaining.Count;
|
||||
CurrentFile = 0;
|
||||
|
||||
Logger.LogDebug("=== Computing {amount} remaining files ===", remaining.Count);
|
||||
|
||||
Mediator.Publish(new HaltScanMessage(nameof(CharacterAnalyzer)));
|
||||
|
||||
try
|
||||
{
|
||||
var remaining = allFiles.Where(c => !c.IsComputed || recalculate).ToList();
|
||||
TotalFiles = remaining.Count;
|
||||
CurrentFile = 1;
|
||||
Logger.LogDebug("=== Computing {amount} remaining files ===", remaining.Count);
|
||||
Mediator.Publish(new HaltScanMessage(nameof(CharacterAnalyzer)));
|
||||
try
|
||||
foreach (var file in remaining)
|
||||
{
|
||||
foreach (var file in remaining)
|
||||
{
|
||||
Logger.LogDebug("Computing file {file}", file.FilePaths[0]);
|
||||
await file.ComputeSizes(_fileCacheManager, cancelToken).ConfigureAwait(false);
|
||||
CurrentFile++;
|
||||
}
|
||||
_fileCacheManager.WriteOutFullCsv();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning(ex, "Failed to analyze files");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Mediator.Publish(new ResumeScanMessage(nameof(CharacterAnalyzer)));
|
||||
cancelToken.ThrowIfCancellationRequested();
|
||||
|
||||
var path = file.FilePaths.FirstOrDefault() ?? "<unknown>";
|
||||
Logger.LogDebug("Computing file {file}", path);
|
||||
|
||||
await file.ComputeSizes(_fileCacheManager, cancelToken).ConfigureAwait(false);
|
||||
|
||||
CurrentFile++;
|
||||
}
|
||||
|
||||
await _fileCacheManager.WriteOutFullCsvAsync(cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Logger.LogInformation("File analysis cancelled");
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogWarning(ex, "Failed to analyze files");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Mediator.Publish(new ResumeScanMessage(nameof(CharacterAnalyzer)));
|
||||
}
|
||||
|
||||
RecalculateSummary();
|
||||
@@ -87,6 +101,7 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
|
||||
public void Dispose()
|
||||
{
|
||||
_analysisCts.CancelDispose();
|
||||
_baseAnalysisCts.Dispose();
|
||||
}
|
||||
public async Task UpdateFileEntriesAsync(IEnumerable<string> filePaths, CancellationToken token)
|
||||
{
|
||||
@@ -120,7 +135,8 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
|
||||
foreach (var fileEntry in obj.Value)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
var fileCacheEntries = _fileCacheManager.GetAllFileCachesByHash(fileEntry.Hash, ignoreCacheEntries: true, validate: false).ToList();
|
||||
|
||||
var fileCacheEntries = (await _fileCacheManager.GetAllFileCachesByHashAsync(fileEntry.Hash, ignoreCacheEntries: true, validate: false, token).ConfigureAwait(false)).ToList();
|
||||
if (fileCacheEntries.Count == 0) continue;
|
||||
var filePath = fileCacheEntries[0].ResolvedFilepath;
|
||||
FileInfo fi = new(filePath);
|
||||
@@ -138,7 +154,7 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
|
||||
{
|
||||
data[fileEntry.Hash] = new FileDataEntry(fileEntry.Hash, ext,
|
||||
[.. fileEntry.GamePaths],
|
||||
fileCacheEntries.Select(c => c.ResolvedFilepath).Distinct().ToList(),
|
||||
[.. fileCacheEntries.Select(c => c.ResolvedFilepath).Distinct(StringComparer.Ordinal)],
|
||||
entry.Size > 0 ? entry.Size.Value : 0,
|
||||
entry.CompressedSize > 0 ? entry.CompressedSize.Value : 0,
|
||||
tris);
|
||||
@@ -226,7 +242,7 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
|
||||
{
|
||||
var compressedsize = await fileCacheManager.GetCompressedFileData(Hash, token).ConfigureAwait(false);
|
||||
var normalSize = new FileInfo(FilePaths[0]).Length;
|
||||
var entries = fileCacheManager.GetAllFileCachesByHash(Hash, ignoreCacheEntries: true, validate: false);
|
||||
var entries = await fileCacheManager.GetAllFileCachesByHashAsync(Hash, ignoreCacheEntries: true, validate: false, token).ConfigureAwait(false);
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
entry.Size = normalSize;
|
||||
@@ -263,23 +279,3 @@ public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public readonly record struct CharacterAnalysisObjectSummary(int EntryCount, long TotalTriangles, long TexOriginalBytes, long TexCompressedBytes)
|
||||
{
|
||||
public bool HasEntries => EntryCount > 0;
|
||||
}
|
||||
|
||||
public sealed class CharacterAnalysisSummary
|
||||
{
|
||||
public static CharacterAnalysisSummary Empty { get; } =
|
||||
new(ImmutableDictionary<ObjectKind, CharacterAnalysisObjectSummary>.Empty);
|
||||
|
||||
internal CharacterAnalysisSummary(IImmutableDictionary<ObjectKind, CharacterAnalysisObjectSummary> objects)
|
||||
{
|
||||
Objects = objects;
|
||||
}
|
||||
|
||||
public IImmutableDictionary<ObjectKind, CharacterAnalysisObjectSummary> Objects { get; }
|
||||
|
||||
public bool HasData => Objects.Any(kvp => kvp.Value.HasEntries);
|
||||
}
|
||||
Reference in New Issue
Block a user