Replace Dictionary + locks with ConcurrentDictionary (#143)

This commit is contained in:
rlauuzo 2024-05-08 16:27:16 +02:00 committed by GitHub
parent e0aca4785a
commit 9d4cb0a4ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 41 additions and 103 deletions

View File

@ -128,7 +128,7 @@ public class SkipIntroController : ControllerBase
Plugin.Instance!.Credits.Clear();
}
Plugin.Instance!.SaveTimestamps();
Plugin.Instance!.SaveTimestamps(mode);
return NoContent();
}

View File

@ -139,11 +139,12 @@ public class VisualizationController : ControllerBase
foreach (var e in episodes)
{
Plugin.Instance!.Intros.Remove(e.EpisodeId);
Plugin.Instance!.Credits.Remove(e.EpisodeId);
Plugin.Instance!.Intros.TryRemove(e.EpisodeId, out _);
Plugin.Instance!.Credits.TryRemove(e.EpisodeId, out _);
}
Plugin.Instance!.SaveTimestamps();
Plugin.Instance!.SaveTimestamps(AnalysisMode.Introduction);
Plugin.Instance!.SaveTimestamps(AnalysisMode.Credits);
return NoContent();
}
@ -160,7 +161,7 @@ public class VisualizationController : ControllerBase
{
var tr = new TimeRange(timestamps.IntroStart, timestamps.IntroEnd);
Plugin.Instance!.Intros[id] = new Intro(id, tr);
Plugin.Instance.SaveTimestamps();
Plugin.Instance.SaveTimestamps(AnalysisMode.Introduction);
return NoContent();
}

View File

@ -33,7 +33,7 @@ public static class FFmpegWrapper
private static Dictionary<string, string> ChromaprintLogs { get; set; } = new();
private static ConcurrentDictionary<AnalysisMode, ConcurrentDictionary<Guid, Dictionary<uint, int>>> InvertedIndexCache { get; set; } = new();
private static ConcurrentDictionary<(Guid Id, AnalysisMode Mode), Dictionary<uint, int>> InvertedIndexCache { get; set; } = new();
/// <summary>
/// Check that the installed version of ffmpeg supports chromaprint.
@ -140,10 +140,7 @@ public static class FFmpegWrapper
/// <returns>Inverted index.</returns>
public static Dictionary<uint, int> CreateInvertedIndex(Guid id, uint[] fingerprint, AnalysisMode mode)
{
var innerDictionary = InvertedIndexCache.GetOrAdd(mode, _ => new ConcurrentDictionary<Guid, Dictionary<uint, int>>());
// Check if cached for the ID
if (innerDictionary.TryGetValue(id, out var cached))
if (InvertedIndexCache.TryGetValue((id, mode), out var cached))
{
return cached;
}
@ -159,7 +156,7 @@ public static class FFmpegWrapper
invIndex[point] = i;
}
innerDictionary[id] = invIndex;
InvertedIndexCache[(id, mode)] = invIndex;
return invIndex;
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
@ -140,17 +141,17 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
/// <summary>
/// Gets the results of fingerprinting all episodes.
/// </summary>
public Dictionary<Guid, Intro> Intros { get; } = new();
public ConcurrentDictionary<Guid, Intro> Intros { get; } = new();
/// <summary>
/// Gets all discovered ending credits.
/// </summary>
public Dictionary<Guid, Intro> Credits { get; } = new();
public ConcurrentDictionary<Guid, Intro> Credits { get; } = new();
/// <summary>
/// Gets the most recent media item queue.
/// </summary>
public Dictionary<Guid, List<QueuedEpisode>> QueuedMediaItems { get; } = new();
public ConcurrentDictionary<Guid, List<QueuedEpisode>> QueuedMediaItems { get; } = new();
/// <summary>
/// Gets or sets the total number of episodes in the queue.
@ -183,91 +184,33 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
/// </summary>
public static Plugin? Instance { get; private set; }
/// <summary>
/// Save timestamps to disk.
/// </summary>
public void SaveTimestamps()
{
lock (_serializationLock)
{
var introList = new List<Intro>();
// Serialize intros
foreach (var intro in Instance!.Intros)
{
introList.Add(intro.Value);
}
try
{
XmlSerializationHelper.SerializeToXml(introList, _introPath);
}
catch (Exception e)
{
_logger.LogError("SaveTimestamps intros {Message}", e.Message);
}
// Serialize credits
introList.Clear();
foreach (var intro in Instance.Credits)
{
introList.Add(intro.Value);
}
try
{
XmlSerializationHelper.SerializeToXml(introList, _creditsPath);
}
catch (Exception e)
{
_logger.LogError("SaveTimestamps credits {Message}", e.Message);
}
}
}
/// <summary>
/// Save timestamps to disk.
/// </summary>
/// <param name="mode">Mode.</param>
public void SaveTimestamps(AnalysisMode mode)
{
List<Intro> introList = new List<Intro>();
var filePath = mode == AnalysisMode.Introduction
? _introPath
: _creditsPath;
lock (_introsLock)
{
introList.AddRange(mode == AnalysisMode.Introduction
? Instance!.Intros.Values
: Instance!.Credits.Values);
}
lock (_serializationLock)
{
var introList = new List<Intro>();
// Serialize intros
if (mode == AnalysisMode.Introduction)
try
{
foreach (var intro in Instance!.Intros)
{
introList.Add(intro.Value);
}
try
{
XmlSerializationHelper.SerializeToXml(introList, _introPath);
}
catch (Exception e)
{
_logger.LogError("SaveTimestamps intros {Message}", e.Message);
}
XmlSerializationHelper.SerializeToXml(introList, filePath);
}
else if (mode == AnalysisMode.Credits)
catch (Exception e)
{
foreach (var intro in Instance!.Credits)
{
introList.Add(intro.Value);
}
try
{
XmlSerializationHelper.SerializeToXml(introList, _creditsPath);
}
catch (Exception e)
{
_logger.LogError("SaveTimestamps credits {Message}", e.Message);
}
_logger.LogError("SaveTimestamps {Message}", e.Message);
}
}
}
@ -284,7 +227,7 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
foreach (var intro in introList)
{
Instance!.Intros[intro.EpisodeId] = intro;
Instance!.Intros.TryAdd(intro.EpisodeId, intro);
}
}
@ -294,7 +237,7 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
foreach (var credit in creditList)
{
Instance!.Credits[credit.EpisodeId] = credit;
Instance!.Credits.TryAdd(credit.EpisodeId, credit);
}
}
}
@ -394,22 +337,19 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
internal void UpdateTimestamps(Dictionary<Guid, Intro> newTimestamps, AnalysisMode mode)
{
lock (_introsLock)
foreach (var intro in newTimestamps)
{
foreach (var intro in newTimestamps)
if (mode == AnalysisMode.Introduction)
{
if (mode == AnalysisMode.Introduction)
{
Instance!.Intros[intro.Key] = intro.Value;
}
else if (mode == AnalysisMode.Credits)
{
Instance!.Credits[intro.Key] = intro.Value;
}
Instance!.Intros.AddOrUpdate(intro.Key, intro.Value, (key, oldValue) => intro.Value);
}
else if (mode == AnalysisMode.Credits)
{
Instance!.Credits.AddOrUpdate(intro.Key, intro.Value, (key, oldValue) => intro.Value);
}
Instance!.SaveTimestamps(mode);
}
SaveTimestamps(mode);
}
/// <summary>

View File

@ -84,7 +84,7 @@ public class QueueManager
Plugin.Instance.QueuedMediaItems.Clear();
foreach (var kvp in _queuedEpisodes)
{
Plugin.Instance.QueuedMediaItems[kvp.Key] = kvp.Value;
Plugin.Instance.QueuedMediaItems.TryAdd(kvp.Key, kvp.Value);
}
return new(_queuedEpisodes);