calculate and display local cache size on cache changes, add clear cache button
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Dalamud.Game.ClientState;
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using MareSynchronos.FileCacheDB;
|
|
||||||
using MareSynchronos.Utils;
|
|
||||||
|
|
||||||
namespace MareSynchronos.Factories
|
|
||||||
{
|
|
||||||
public class FileCacheFactory
|
|
||||||
{
|
|
||||||
public FileCache Create(string file)
|
|
||||||
{
|
|
||||||
FileInfo fileInfo = new(file);
|
|
||||||
if (IsFileLocked(fileInfo))
|
|
||||||
{
|
|
||||||
throw new FileLoadException();
|
|
||||||
}
|
|
||||||
var sha1Hash = Crypto.GetFileHash(fileInfo.FullName);
|
|
||||||
return new FileCache()
|
|
||||||
{
|
|
||||||
Filepath = fileInfo.FullName,
|
|
||||||
Hash = sha1Hash,
|
|
||||||
LastModifiedDate = fileInfo.LastWriteTimeUtc.Ticks.ToString(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateFileCache(FileCache cache)
|
|
||||||
{
|
|
||||||
FileInfo fileInfo = new(cache.Filepath);
|
|
||||||
cache.Hash = Crypto.GetFileHash(cache.Filepath);
|
|
||||||
cache.LastModifiedDate = fileInfo.LastWriteTimeUtc.Ticks.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsFileLocked(FileInfo file)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using var fs = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -177,5 +177,7 @@ namespace MareSynchronos.Managers
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
using MareSynchronos.Factories;
|
|
||||||
using MareSynchronos.FileCacheDB;
|
using MareSynchronos.FileCacheDB;
|
||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
|
|
||||||
@@ -14,19 +13,18 @@ namespace MareSynchronos.Managers
|
|||||||
{
|
{
|
||||||
public class FileCacheManager : IDisposable
|
public class FileCacheManager : IDisposable
|
||||||
{
|
{
|
||||||
private readonly FileCacheFactory _fileCacheFactory;
|
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
private readonly Configuration _pluginConfiguration;
|
private readonly Configuration _pluginConfiguration;
|
||||||
private CancellationTokenSource? _scanCancellationTokenSource;
|
private CancellationTokenSource? _scanCancellationTokenSource;
|
||||||
private Task? _scanTask;
|
private Task? _scanTask;
|
||||||
private FileSystemWatcher? _penumbraDirWatcher;
|
private FileSystemWatcher? _penumbraDirWatcher;
|
||||||
private FileSystemWatcher? _cacheDirWatcher;
|
private FileSystemWatcher? _cacheDirWatcher;
|
||||||
|
public long FileCacheSize { get; set; }
|
||||||
|
|
||||||
public FileCacheManager(FileCacheFactory fileCacheFactory, IpcManager ipcManager, Configuration pluginConfiguration)
|
public FileCacheManager(IpcManager ipcManager, Configuration pluginConfiguration)
|
||||||
{
|
{
|
||||||
Logger.Debug("Creating " + nameof(FileCacheManager));
|
Logger.Debug("Creating " + nameof(FileCacheManager));
|
||||||
|
|
||||||
_fileCacheFactory = fileCacheFactory;
|
|
||||||
_ipcManager = ipcManager;
|
_ipcManager = ipcManager;
|
||||||
_pluginConfiguration = pluginConfiguration;
|
_pluginConfiguration = pluginConfiguration;
|
||||||
|
|
||||||
@@ -50,12 +48,12 @@ namespace MareSynchronos.Managers
|
|||||||
Logger.Debug("File created: " + e.FullPath);
|
Logger.Debug("File created: " + e.FullPath);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var createdFileCache = _fileCacheFactory.Create(fi.FullName);
|
var createdFileCache = Create(fi.FullName);
|
||||||
db.Add(createdFileCache);
|
db.Add(createdFileCache);
|
||||||
}
|
}
|
||||||
catch (FileLoadException)
|
catch (FileLoadException)
|
||||||
{
|
{
|
||||||
Logger.Debug("File was still being written to");
|
Logger.Debug("File was still being written to.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -71,12 +69,17 @@ namespace MareSynchronos.Managers
|
|||||||
foreach (var file in newFiles)
|
foreach (var file in newFiles)
|
||||||
{
|
{
|
||||||
Logger.Debug("Adding " + file);
|
Logger.Debug("Adding " + file);
|
||||||
db.Add(_fileCacheFactory.Create(file));
|
db.Add(Create(file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
|
|
||||||
|
if (e.FullPath.Contains(_pluginConfiguration.CacheFolder, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
Task.Run(RecalculateFileCacheSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDeleted(object sender, FileSystemEventArgs e)
|
private void OnDeleted(object sender, FileSystemEventArgs e)
|
||||||
@@ -104,6 +107,11 @@ namespace MareSynchronos.Managers
|
|||||||
}
|
}
|
||||||
|
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
|
|
||||||
|
if (e.FullPath.Contains(_pluginConfiguration.CacheFolder, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
Task.Run(RecalculateFileCacheSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnModified(object sender, FileSystemEventArgs e)
|
private void OnModified(object sender, FileSystemEventArgs e)
|
||||||
@@ -113,12 +121,17 @@ namespace MareSynchronos.Managers
|
|||||||
if (fi.Extension.ToLower() is not ".mdl" or ".tex" or ".mtrl") return;
|
if (fi.Extension.ToLower() is not ".mdl" or ".tex" or ".mtrl") return;
|
||||||
Logger.Debug("File changed: " + e.FullPath);
|
Logger.Debug("File changed: " + e.FullPath);
|
||||||
using var db = new FileCacheContext();
|
using var db = new FileCacheContext();
|
||||||
var modifiedFile = _fileCacheFactory.Create(fi.FullName);
|
var modifiedFile = Create(fi.FullName);
|
||||||
var fileInDb = db.FileCaches.SingleOrDefault(f => f.Filepath == fi.FullName.ToLower() || modifiedFile.Hash == f.Hash);
|
var fileInDb = db.FileCaches.SingleOrDefault(f => f.Filepath == fi.FullName.ToLower() || modifiedFile.Hash == f.Hash);
|
||||||
if (fileInDb == null) return;
|
if (fileInDb == null) return;
|
||||||
db.Remove(fileInDb);
|
db.Remove(fileInDb);
|
||||||
db.Add(modifiedFile);
|
db.Add(modifiedFile);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
|
|
||||||
|
if (e.FullPath.Contains(_pluginConfiguration.CacheFolder, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
Task.Run(RecalculateFileCacheSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long CurrentFileProgress { get; private set; }
|
public long CurrentFileProgress { get; private set; }
|
||||||
@@ -185,7 +198,7 @@ namespace MareSynchronos.Managers
|
|||||||
}
|
}
|
||||||
FileInfo fileInfo = new(cache.Filepath);
|
FileInfo fileInfo = new(cache.Filepath);
|
||||||
if (fileInfo.LastWriteTimeUtc.Ticks == long.Parse(cache.LastModifiedDate)) return;
|
if (fileInfo.LastWriteTimeUtc.Ticks == long.Parse(cache.LastModifiedDate)) return;
|
||||||
fileCachesToAdd.Add(_fileCacheFactory.Create(cache.Filepath));
|
fileCachesToAdd.Add(Create(cache.Filepath));
|
||||||
fileCachesToDelete.Add(cache);
|
fileCachesToDelete.Add(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +217,7 @@ namespace MareSynchronos.Managers
|
|||||||
},
|
},
|
||||||
file =>
|
file =>
|
||||||
{
|
{
|
||||||
fileCachesToAdd.Add(_fileCacheFactory.Create(file.Key));
|
fileCachesToAdd.Add(Create(file.Key));
|
||||||
|
|
||||||
var files = CurrentFileProgress;
|
var files = CurrentFileProgress;
|
||||||
Interlocked.Increment(ref files);
|
Interlocked.Increment(ref files);
|
||||||
@@ -275,6 +288,47 @@ namespace MareSynchronos.Managers
|
|||||||
_cacheDirWatcher.Filters.Add("*.tex");
|
_cacheDirWatcher.Filters.Add("*.tex");
|
||||||
_cacheDirWatcher.Error +=
|
_cacheDirWatcher.Error +=
|
||||||
(sender, args) => PluginLog.Error(args.GetException(), "Error in Cache Dir Watcher");
|
(sender, args) => PluginLog.Error(args.GetException(), "Error in Cache Dir Watcher");
|
||||||
|
|
||||||
|
Task.Run(RecalculateFileCacheSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecalculateFileCacheSize()
|
||||||
|
{
|
||||||
|
FileCacheSize = 0;
|
||||||
|
foreach (var file in Directory.EnumerateFiles(_pluginConfiguration.CacheFolder))
|
||||||
|
{
|
||||||
|
FileCacheSize += new FileInfo(file).Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsFileLocked(FileInfo file)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var fs = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileCache Create(string file)
|
||||||
|
{
|
||||||
|
FileInfo fileInfo = new(file);
|
||||||
|
if (IsFileLocked(fileInfo))
|
||||||
|
{
|
||||||
|
throw new FileLoadException();
|
||||||
|
}
|
||||||
|
var sha1Hash = Crypto.GetFileHash(fileInfo.FullName);
|
||||||
|
return new FileCache()
|
||||||
|
{
|
||||||
|
Filepath = fileInfo.FullName,
|
||||||
|
Hash = sha1Hash,
|
||||||
|
LastModifiedDate = fileInfo.LastWriteTimeUtc.Ticks.ToString(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace MareSynchronos
|
|||||||
|
|
||||||
_apiController = new ApiController(_configuration);
|
_apiController = new ApiController(_configuration);
|
||||||
_ipcManager = new IpcManager(_pluginInterface);
|
_ipcManager = new IpcManager(_pluginInterface);
|
||||||
_fileCacheManager = new FileCacheManager(new FileCacheFactory(), _ipcManager, _configuration);
|
_fileCacheManager = new FileCacheManager(_ipcManager, _configuration);
|
||||||
_dalamudUtil = new DalamudUtil(_clientState, _objectTable);
|
_dalamudUtil = new DalamudUtil(_clientState, _objectTable);
|
||||||
_characterCacheManager = new CharacterCacheManager(_clientState, framework, _objectTable, _apiController,
|
_characterCacheManager = new CharacterCacheManager(_clientState, framework, _objectTable, _apiController,
|
||||||
_dalamudUtil, _ipcManager);
|
_dalamudUtil, _ipcManager);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Dalamud.Interface.Windowing;
|
|||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using MareSynchronos.WebAPI;
|
using MareSynchronos.WebAPI;
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
@@ -190,7 +191,18 @@ namespace MareSynchronos.UI
|
|||||||
{
|
{
|
||||||
_uiShared.DrawFileScanState();
|
_uiShared.DrawFileScanState();
|
||||||
_uiShared.DrawCacheDirectorySetting();
|
_uiShared.DrawCacheDirectorySetting();
|
||||||
_uiShared.DrawParallelScansSetting();
|
ImGui.Text($"Local cache size: {UiShared.ByteToString(_uiShared.FileCacheSize)}");
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.Button("Clear local cache"))
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
foreach (var file in Directory.GetFiles(_configuration.CacheFolder))
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace MareSynchronos.UI
|
|||||||
private readonly ApiController _apiController;
|
private readonly ApiController _apiController;
|
||||||
private readonly FileCacheManager _fileCacheManager;
|
private readonly FileCacheManager _fileCacheManager;
|
||||||
private readonly Configuration _pluginConfiguration;
|
private readonly Configuration _pluginConfiguration;
|
||||||
|
public long FileCacheSize => _fileCacheManager.FileCacheSize;
|
||||||
|
|
||||||
public UiShared(IpcManager ipcManager, ApiController apiController, FileCacheManager fileCacheManager, Configuration pluginConfiguration)
|
public UiShared(IpcManager ipcManager, ApiController apiController, FileCacheManager fileCacheManager, Configuration pluginConfiguration)
|
||||||
{
|
{
|
||||||
@@ -115,16 +116,15 @@ namespace MareSynchronos.UI
|
|||||||
|
|
||||||
public static string ByteToString(long bytes)
|
public static string ByteToString(long bytes)
|
||||||
{
|
{
|
||||||
double output = bytes;
|
string[] suffix = { "B", "KiB", "MiB", "GiB", "TiB" };
|
||||||
var suffix = new[] { "B", "KiB", "MiB", "GiB" };
|
int i;
|
||||||
var suffixIdx = 0;
|
double dblSByte = bytes;
|
||||||
while (output / 1024.0 > 1024)
|
for (i = 0; i < suffix.Length && bytes >= 1024; i++, bytes /= 1024)
|
||||||
{
|
{
|
||||||
output /= 1024.0;
|
dblSByte = bytes / 1024.0;
|
||||||
suffixIdx++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return output.ToString("0.00") + " " + suffix[suffixIdx];
|
return $"{dblSByte:0.00} {suffix[i]}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _serverSelectionIndex = 0;
|
private int _serverSelectionIndex = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user