add CharacterAnalzyer, fix DtrEntry (I think)

This commit is contained in:
rootdarkarchon
2023-07-10 13:23:44 +02:00
parent 2473087da4
commit 417c08f9b2
7 changed files with 170 additions and 29 deletions

View File

@@ -0,0 +1,97 @@
using MareSynchronos.API.Data;
using MareSynchronos.FileCache;
using MareSynchronos.Services.Mediator;
using MareSynchronos.UI;
using MareSynchronos.Utils;
using Microsoft.Extensions.Logging;
namespace MareSynchronos.Services;
public sealed class CharacterAnalyzer : MediatorSubscriberBase, IDisposable
{
private readonly FileCacheManager _fileCacheManager;
private CharacterData? _lastCreatedData;
private CancellationTokenSource? _analysisCts;
public CharacterAnalyzer(ILogger<CharacterAnalyzer> logger, MareMediator mediator, FileCacheManager fileCacheManager) : base(logger, mediator)
{
Mediator.Subscribe<CharacterDataCreatedMessage>(this, (msg) =>
{
_lastCreatedData = msg.CharacterData.DeepClone();
});
_fileCacheManager = fileCacheManager;
}
public bool IsAnalysisRunning => _analysisCts != null;
public void CancelAnalyze()
{
_analysisCts?.CancelDispose();
_analysisCts = null;
}
public async Task Analyze()
{
_analysisCts = _analysisCts?.CancelRecreate() ?? new();
var cancelToken = _analysisCts.Token;
if (_lastCreatedData == null) return;
Logger.LogInformation("=== Calculating Character Analysis, this may take a while ===");
foreach (var obj in _lastCreatedData.FileReplacements)
{
Logger.LogInformation("=== File Calculation for {obj} ===", obj.Key);
Dictionary<string, List<DataEntry>> data = new(StringComparer.OrdinalIgnoreCase);
var totalFiles = obj.Value.Count(c => !string.IsNullOrEmpty(c.Hash));
var currentFile = 1;
foreach (var hash in obj.Value.Select(c => c.Hash))
{
var fileCacheEntry = _fileCacheManager.GetFileCacheByHash(hash);
if (fileCacheEntry == null) continue;
Logger.LogInformation("Computing File {x}/{y}: {hash}", currentFile, totalFiles, hash);
Logger.LogInformation(" File Path: {path}", fileCacheEntry.ResolvedFilepath);
var filePath = fileCacheEntry.ResolvedFilepath;
FileInfo fi = new(filePath);
var ext = fi.Extension;
if (!data.ContainsKey(ext)) data[ext] = new List<DataEntry>();
(_, byte[] fileLength) = await _fileCacheManager.GetCompressedFileData(hash, cancelToken).ConfigureAwait(false);
Logger.LogInformation(" Original Size: {size}, Compressed Size: {compr}",
UiSharedService.ByteToString(fi.Length), UiSharedService.ByteToString(fileLength.LongLength));
data[ext].Add(new DataEntry(fi.FullName, fi.Length, fileLength.LongLength));
currentFile++;
cancelToken.ThrowIfCancellationRequested();
}
Logger.LogInformation("=== Summary by file type for {obj} ===", obj.Key);
foreach (var entry in data)
{
Logger.LogInformation("{ext} files: {count}, size extracted: {size}, size compressed: {sizeComp}", entry.Key, entry.Value.Count,
UiSharedService.ByteToString(entry.Value.Sum(v => v.OriginalSize)), UiSharedService.ByteToString(entry.Value.Sum(v => v.CompressedSize)));
}
Logger.LogInformation("=== Total summary for {obj} ===", obj.Key);
Logger.LogInformation("Total files: {count}, size extracted: {size}, size compressed: {sizeComp}", data.Values.Sum(c => c.Count),
UiSharedService.ByteToString(data.Values.Sum(v => v.Sum(c => c.OriginalSize))), UiSharedService.ByteToString(data.Values.Sum(v => v.Sum(c => c.CompressedSize))));
Logger.LogInformation("IMPORTANT NOTES:\n\r- For Mare up- and downloads only the compressed size is relevant.\n\r- An unusually high total files count beyond 200 and up will also increase your download time to others significantly.");
}
_analysisCts.CancelDispose();
_analysisCts = null;
}
public void Dispose()
{
_analysisCts.CancelDispose();
}
private sealed record DataEntry(string filePath, long OriginalSize, long CompressedSize);
}

View File

@@ -14,6 +14,7 @@ public sealed class CommandManagerService : IDisposable
private readonly ApiController _apiController;
private readonly CommandManager _commandManager;
private readonly MareMediator _mediator;
private readonly CharacterAnalyzer _characterAnalyzer;
private readonly PerformanceCollectorService _performanceCollectorService;
private readonly PeriodicFileScanner _periodicFileScanner;
private readonly ServerConfigurationManager _serverConfigurationManager;
@@ -21,7 +22,7 @@ public sealed class CommandManagerService : IDisposable
public CommandManagerService(CommandManager commandManager, PerformanceCollectorService performanceCollectorService,
UiService uiService, ServerConfigurationManager serverConfigurationManager, PeriodicFileScanner periodicFileScanner,
ApiController apiController, MareMediator mediator)
ApiController apiController, MareMediator mediator, CharacterAnalyzer characterAnalyzer)
{
_commandManager = commandManager;
_performanceCollectorService = performanceCollectorService;
@@ -30,7 +31,7 @@ public sealed class CommandManagerService : IDisposable
_periodicFileScanner = periodicFileScanner;
_apiController = apiController;
_mediator = mediator;
_characterAnalyzer = characterAnalyzer;
_commandManager.AddHandler(_commandName, new CommandInfo(OnCommand)
{
HelpMessage = "Opens the Mare Synchronos UI"
@@ -99,5 +100,16 @@ public sealed class CommandManagerService : IDisposable
{
_mediator.PrintSubscriberInfo();
}
else if (string.Equals(splitArgs[0], "analyze", StringComparison.OrdinalIgnoreCase))
{
if (splitArgs.Length > 1 && string.Equals(splitArgs[1], "cancel", StringComparison.OrdinalIgnoreCase))
{
_characterAnalyzer.CancelAnalyze();
}
else
{
_ = _characterAnalyzer.Analyze();
}
}
}
}