Replace Dictionary + locks with ConcurrentDictionary (#143)
This commit is contained in:
parent
e0aca4785a
commit
9d4cb0a4ec
@ -128,7 +128,7 @@ public class SkipIntroController : ControllerBase
|
|||||||
Plugin.Instance!.Credits.Clear();
|
Plugin.Instance!.Credits.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin.Instance!.SaveTimestamps();
|
Plugin.Instance!.SaveTimestamps(mode);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,11 +139,12 @@ public class VisualizationController : ControllerBase
|
|||||||
|
|
||||||
foreach (var e in episodes)
|
foreach (var e in episodes)
|
||||||
{
|
{
|
||||||
Plugin.Instance!.Intros.Remove(e.EpisodeId);
|
Plugin.Instance!.Intros.TryRemove(e.EpisodeId, out _);
|
||||||
Plugin.Instance!.Credits.Remove(e.EpisodeId);
|
Plugin.Instance!.Credits.TryRemove(e.EpisodeId, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin.Instance!.SaveTimestamps();
|
Plugin.Instance!.SaveTimestamps(AnalysisMode.Introduction);
|
||||||
|
Plugin.Instance!.SaveTimestamps(AnalysisMode.Credits);
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
@ -160,7 +161,7 @@ public class VisualizationController : ControllerBase
|
|||||||
{
|
{
|
||||||
var tr = new TimeRange(timestamps.IntroStart, timestamps.IntroEnd);
|
var tr = new TimeRange(timestamps.IntroStart, timestamps.IntroEnd);
|
||||||
Plugin.Instance!.Intros[id] = new Intro(id, tr);
|
Plugin.Instance!.Intros[id] = new Intro(id, tr);
|
||||||
Plugin.Instance.SaveTimestamps();
|
Plugin.Instance.SaveTimestamps(AnalysisMode.Introduction);
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public static class FFmpegWrapper
|
|||||||
|
|
||||||
private static Dictionary<string, string> ChromaprintLogs { get; set; } = new();
|
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>
|
/// <summary>
|
||||||
/// Check that the installed version of ffmpeg supports chromaprint.
|
/// Check that the installed version of ffmpeg supports chromaprint.
|
||||||
@ -140,10 +140,7 @@ public static class FFmpegWrapper
|
|||||||
/// <returns>Inverted index.</returns>
|
/// <returns>Inverted index.</returns>
|
||||||
public static Dictionary<uint, int> CreateInvertedIndex(Guid id, uint[] fingerprint, AnalysisMode mode)
|
public static Dictionary<uint, int> CreateInvertedIndex(Guid id, uint[] fingerprint, AnalysisMode mode)
|
||||||
{
|
{
|
||||||
var innerDictionary = InvertedIndexCache.GetOrAdd(mode, _ => new ConcurrentDictionary<Guid, Dictionary<uint, int>>());
|
if (InvertedIndexCache.TryGetValue((id, mode), out var cached))
|
||||||
|
|
||||||
// Check if cached for the ID
|
|
||||||
if (innerDictionary.TryGetValue(id, out var cached))
|
|
||||||
{
|
{
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
@ -159,7 +156,7 @@ public static class FFmpegWrapper
|
|||||||
invIndex[point] = i;
|
invIndex[point] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
innerDictionary[id] = invIndex;
|
InvertedIndexCache[(id, mode)] = invIndex;
|
||||||
|
|
||||||
return invIndex;
|
return invIndex;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@ -140,17 +141,17 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the results of fingerprinting all episodes.
|
/// Gets the results of fingerprinting all episodes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<Guid, Intro> Intros { get; } = new();
|
public ConcurrentDictionary<Guid, Intro> Intros { get; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all discovered ending credits.
|
/// Gets all discovered ending credits.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<Guid, Intro> Credits { get; } = new();
|
public ConcurrentDictionary<Guid, Intro> Credits { get; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the most recent media item queue.
|
/// Gets the most recent media item queue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<Guid, List<QueuedEpisode>> QueuedMediaItems { get; } = new();
|
public ConcurrentDictionary<Guid, List<QueuedEpisode>> QueuedMediaItems { get; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the total number of episodes in the queue.
|
/// Gets or sets the total number of episodes in the queue.
|
||||||
@ -183,91 +184,33 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static Plugin? Instance { get; private set; }
|
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>
|
/// <summary>
|
||||||
/// Save timestamps to disk.
|
/// Save timestamps to disk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="mode">Mode.</param>
|
/// <param name="mode">Mode.</param>
|
||||||
public void SaveTimestamps(AnalysisMode mode)
|
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)
|
lock (_serializationLock)
|
||||||
{
|
{
|
||||||
var introList = new List<Intro>();
|
try
|
||||||
|
|
||||||
// Serialize intros
|
|
||||||
if (mode == AnalysisMode.Introduction)
|
|
||||||
{
|
{
|
||||||
foreach (var intro in Instance!.Intros)
|
XmlSerializationHelper.SerializeToXml(introList, filePath);
|
||||||
{
|
|
||||||
introList.Add(intro.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
XmlSerializationHelper.SerializeToXml(introList, _introPath);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.LogError("SaveTimestamps intros {Message}", e.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (mode == AnalysisMode.Credits)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
foreach (var intro in Instance!.Credits)
|
_logger.LogError("SaveTimestamps {Message}", e.Message);
|
||||||
{
|
|
||||||
introList.Add(intro.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
XmlSerializationHelper.SerializeToXml(introList, _creditsPath);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.LogError("SaveTimestamps credits {Message}", e.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,7 +227,7 @@ public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
|||||||
|
|
||||||
foreach (var intro in introList)
|
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)
|
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)
|
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.AddOrUpdate(intro.Key, intro.Value, (key, oldValue) => intro.Value);
|
||||||
{
|
}
|
||||||
Instance!.Intros[intro.Key] = intro.Value;
|
else if (mode == AnalysisMode.Credits)
|
||||||
}
|
{
|
||||||
else if (mode == AnalysisMode.Credits)
|
Instance!.Credits.AddOrUpdate(intro.Key, intro.Value, (key, oldValue) => intro.Value);
|
||||||
{
|
|
||||||
Instance!.Credits[intro.Key] = intro.Value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance!.SaveTimestamps(mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SaveTimestamps(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -84,7 +84,7 @@ public class QueueManager
|
|||||||
Plugin.Instance.QueuedMediaItems.Clear();
|
Plugin.Instance.QueuedMediaItems.Clear();
|
||||||
foreach (var kvp in _queuedEpisodes)
|
foreach (var kvp in _queuedEpisodes)
|
||||||
{
|
{
|
||||||
Plugin.Instance.QueuedMediaItems[kvp.Key] = kvp.Value;
|
Plugin.Instance.QueuedMediaItems.TryAdd(kvp.Key, kvp.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new(_queuedEpisodes);
|
return new(_queuedEpisodes);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user