Switch from ReadOnlyCollections to raw arrays
This commit is contained in:
parent
259bddfc1a
commit
2bd6c90409
@ -67,7 +67,7 @@ public class TestAudioFingerprinting
|
|||||||
public void TestIndexGeneration()
|
public void TestIndexGeneration()
|
||||||
{
|
{
|
||||||
// 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
var fpr = new List<uint>(new uint[] { 1, 2, 3, 1, 5, 77, 42, 2 }).AsReadOnly();
|
var fpr = new uint[] { 1, 2, 3, 1, 5, 77, 42, 2 };
|
||||||
var expected = new Dictionary<uint, int>()
|
var expected = new Dictionary<uint, int>()
|
||||||
{
|
{
|
||||||
{1, 3},
|
{1, 3},
|
||||||
|
@ -66,10 +66,10 @@ public static class Chromaprint
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="episode">Queued episode to fingerprint.</param>
|
/// <param name="episode">Queued episode to fingerprint.</param>
|
||||||
/// <returns>Numerical fingerprint points.</returns>
|
/// <returns>Numerical fingerprint points.</returns>
|
||||||
public static ReadOnlyCollection<uint> Fingerprint(QueuedEpisode episode)
|
public static uint[] Fingerprint(QueuedEpisode episode)
|
||||||
{
|
{
|
||||||
// Try to load this episode from cache before running ffmpeg.
|
// Try to load this episode from cache before running ffmpeg.
|
||||||
if (LoadCachedFingerprint(episode, out ReadOnlyCollection<uint> cachedFingerprint))
|
if (LoadCachedFingerprint(episode, out uint[] cachedFingerprint))
|
||||||
{
|
{
|
||||||
Logger?.LogDebug("Fingerprint cache hit on {File}", episode.Path);
|
Logger?.LogDebug("Fingerprint cache hit on {File}", episode.Path);
|
||||||
return cachedFingerprint;
|
return cachedFingerprint;
|
||||||
@ -106,7 +106,7 @@ public static class Chromaprint
|
|||||||
// Try to cache this fingerprint.
|
// Try to cache this fingerprint.
|
||||||
CacheFingerprint(episode, results);
|
CacheFingerprint(episode, results);
|
||||||
|
|
||||||
return results.AsReadOnly();
|
return results.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -114,11 +114,11 @@ public static class Chromaprint
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fingerprint">Chromaprint fingerprint.</param>
|
/// <param name="fingerprint">Chromaprint fingerprint.</param>
|
||||||
/// <returns>Inverted index.</returns>
|
/// <returns>Inverted index.</returns>
|
||||||
public static Dictionary<uint, int> CreateInvertedIndex(ReadOnlyCollection<uint> fingerprint)
|
public static Dictionary<uint, int> CreateInvertedIndex(uint[] fingerprint)
|
||||||
{
|
{
|
||||||
var invIndex = new Dictionary<uint, int>();
|
var invIndex = new Dictionary<uint, int>();
|
||||||
|
|
||||||
for (int i = 0; i < fingerprint.Count; i++)
|
for (int i = 0; i < fingerprint.Length; i++)
|
||||||
{
|
{
|
||||||
// Get the current point.
|
// Get the current point.
|
||||||
var point = fingerprint[i];
|
var point = fingerprint[i];
|
||||||
@ -183,11 +183,11 @@ public static class Chromaprint
|
|||||||
/// Tries to load an episode's fingerprint from cache. If caching is not enabled, calling this function is a no-op.
|
/// Tries to load an episode's fingerprint from cache. If caching is not enabled, calling this function is a no-op.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="episode">Episode to try to load from cache.</param>
|
/// <param name="episode">Episode to try to load from cache.</param>
|
||||||
/// <param name="fingerprint">ReadOnlyCollection to store the fingerprint in.</param>
|
/// <param name="fingerprint">Array to store the fingerprint in.</param>
|
||||||
/// <returns>true if the episode was successfully loaded from cache, false on any other error.</returns>
|
/// <returns>true if the episode was successfully loaded from cache, false on any other error.</returns>
|
||||||
private static bool LoadCachedFingerprint(QueuedEpisode episode, out ReadOnlyCollection<uint> fingerprint)
|
private static bool LoadCachedFingerprint(QueuedEpisode episode, out uint[] fingerprint)
|
||||||
{
|
{
|
||||||
fingerprint = new List<uint>().AsReadOnly();
|
fingerprint = Array.Empty<uint>();
|
||||||
|
|
||||||
// If fingerprint caching isn't enabled, don't try to load anything.
|
// If fingerprint caching isn't enabled, don't try to load anything.
|
||||||
if (!(Plugin.Instance?.Configuration.CacheFingerprints ?? false))
|
if (!(Plugin.Instance?.Configuration.CacheFingerprints ?? false))
|
||||||
@ -228,7 +228,7 @@ public static class Chromaprint
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fingerprint = result.AsReadOnly();
|
fingerprint = result.ToArray();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ public class VisualizationController : ControllerBase
|
|||||||
/// <param name="id">Episode id.</param>
|
/// <param name="id">Episode id.</param>
|
||||||
/// <returns>Read only collection of fingerprint points.</returns>
|
/// <returns>Read only collection of fingerprint points.</returns>
|
||||||
[HttpGet("Fingerprint/{Id}")]
|
[HttpGet("Fingerprint/{Id}")]
|
||||||
public ActionResult<ReadOnlyCollection<uint>> GetEpisodeFingerprint([FromRoute] Guid id)
|
public ActionResult<uint[]> GetEpisodeFingerprint([FromRoute] Guid id)
|
||||||
{
|
{
|
||||||
var queue = Plugin.Instance!.AnalysisQueue;
|
var queue = Plugin.Instance!.AnalysisQueue;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
/// Temporary fingerprint cache to speed up reanalysis.
|
/// Temporary fingerprint cache to speed up reanalysis.
|
||||||
/// Fingerprints are removed from this after a season is analyzed.
|
/// Fingerprints are removed from this after a season is analyzed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<Guid, ReadOnlyCollection<uint>> _fingerprintCache;
|
private Dictionary<Guid, uint[]> _fingerprintCache;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Statistics for the currently running analysis task.
|
/// Statistics for the currently running analysis task.
|
||||||
@ -92,7 +92,7 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
_logger = loggerFactory.CreateLogger<FingerprinterTask>();
|
_logger = loggerFactory.CreateLogger<FingerprinterTask>();
|
||||||
_queueLogger = loggerFactory.CreateLogger<QueueManager>();
|
_queueLogger = loggerFactory.CreateLogger<QueueManager>();
|
||||||
|
|
||||||
_fingerprintCache = new Dictionary<Guid, ReadOnlyCollection<uint>>();
|
_fingerprintCache = new Dictionary<Guid, uint[]>();
|
||||||
|
|
||||||
EdlManager.Initialize(_logger);
|
EdlManager.Initialize(_logger);
|
||||||
}
|
}
|
||||||
@ -431,9 +431,9 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
/// <returns>Intros for the first and second episodes.</returns>
|
/// <returns>Intros for the first and second episodes.</returns>
|
||||||
public (Intro Lhs, Intro Rhs) FingerprintEpisodes(
|
public (Intro Lhs, Intro Rhs) FingerprintEpisodes(
|
||||||
Guid lhsId,
|
Guid lhsId,
|
||||||
ReadOnlyCollection<uint> lhsPoints,
|
uint[] lhsPoints,
|
||||||
Guid rhsId,
|
Guid rhsId,
|
||||||
ReadOnlyCollection<uint> rhsPoints,
|
uint[] rhsPoints,
|
||||||
bool isFirstPass)
|
bool isFirstPass)
|
||||||
{
|
{
|
||||||
// If this isn't running as part of the first analysis pass, don't count this CPU time as first pass time.
|
// If this isn't running as part of the first analysis pass, don't count this CPU time as first pass time.
|
||||||
@ -468,7 +468,7 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
|
|
||||||
// ===== Method 3: Full scan =====
|
// ===== Method 3: Full scan =====
|
||||||
// Compares all elements of the shortest fingerprint to the other fingerprint.
|
// Compares all elements of the shortest fingerprint to the other fingerprint.
|
||||||
var limit = Math.Min(lhsPoints.Count, rhsPoints.Count);
|
var limit = Math.Min(lhsPoints.Length, rhsPoints.Length);
|
||||||
(lhsRanges, rhsRanges) = ShiftEpisodes(lhsPoints, rhsPoints, -1 * limit, limit);
|
(lhsRanges, rhsRanges) = ShiftEpisodes(lhsPoints, rhsPoints, -1 * limit, limit);
|
||||||
|
|
||||||
if (lhsRanges.Count > 0)
|
if (lhsRanges.Count > 0)
|
||||||
@ -535,8 +535,8 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
/// <param name="rhsPoints">Right episode fingerprint points.</param>
|
/// <param name="rhsPoints">Right episode fingerprint points.</param>
|
||||||
/// <returns>List of shared TimeRanges between the left and right episodes.</returns>
|
/// <returns>List of shared TimeRanges between the left and right episodes.</returns>
|
||||||
private (List<TimeRange> Lhs, List<TimeRange> Rhs) SearchInvertedIndex(
|
private (List<TimeRange> Lhs, List<TimeRange> Rhs) SearchInvertedIndex(
|
||||||
ReadOnlyCollection<uint> lhsPoints,
|
uint[] lhsPoints,
|
||||||
ReadOnlyCollection<uint> rhsPoints)
|
uint[] rhsPoints)
|
||||||
{
|
{
|
||||||
var lhsRanges = new List<TimeRange>();
|
var lhsRanges = new List<TimeRange>();
|
||||||
var rhsRanges = new List<TimeRange>();
|
var rhsRanges = new List<TimeRange>();
|
||||||
@ -579,8 +579,8 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
/// <param name="lower">Lower end of the shift range.</param>
|
/// <param name="lower">Lower end of the shift range.</param>
|
||||||
/// <param name="upper">Upper end of the shift range.</param>
|
/// <param name="upper">Upper end of the shift range.</param>
|
||||||
private static (List<TimeRange> Lhs, List<TimeRange> Rhs) ShiftEpisodes(
|
private static (List<TimeRange> Lhs, List<TimeRange> Rhs) ShiftEpisodes(
|
||||||
ReadOnlyCollection<uint> lhs,
|
uint[] lhs,
|
||||||
ReadOnlyCollection<uint> rhs,
|
uint[] rhs,
|
||||||
int lower,
|
int lower,
|
||||||
int upper)
|
int upper)
|
||||||
{
|
{
|
||||||
@ -610,8 +610,8 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
/// <param name="rhs">Second fingerprint to compare.</param>
|
/// <param name="rhs">Second fingerprint to compare.</param>
|
||||||
/// <param name="shiftAmount">Amount to shift one fingerprint by.</param>
|
/// <param name="shiftAmount">Amount to shift one fingerprint by.</param>
|
||||||
private static (TimeRange Lhs, TimeRange Rhs) FindContiguous(
|
private static (TimeRange Lhs, TimeRange Rhs) FindContiguous(
|
||||||
ReadOnlyCollection<uint> lhs,
|
uint[] lhs,
|
||||||
ReadOnlyCollection<uint> rhs,
|
uint[] rhs,
|
||||||
int shiftAmount)
|
int shiftAmount)
|
||||||
{
|
{
|
||||||
var leftOffset = 0;
|
var leftOffset = 0;
|
||||||
@ -630,7 +630,7 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
// Store similar times for both LHS and RHS.
|
// Store similar times for both LHS and RHS.
|
||||||
var lhsTimes = new List<double>();
|
var lhsTimes = new List<double>();
|
||||||
var rhsTimes = new List<double>();
|
var rhsTimes = new List<double>();
|
||||||
var upperLimit = Math.Min(lhs.Count, rhs.Count) - Math.Abs(shiftAmount);
|
var upperLimit = Math.Min(lhs.Length, rhs.Length) - Math.Abs(shiftAmount);
|
||||||
|
|
||||||
// XOR all elements in LHS and RHS, using the shift amount from above.
|
// XOR all elements in LHS and RHS, using the shift amount from above.
|
||||||
for (var i = 0; i < upperLimit; i++)
|
for (var i = 0; i < upperLimit; i++)
|
||||||
@ -785,7 +785,7 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
|
|
||||||
// TODO: add limit and make it customizable
|
// TODO: add limit and make it customizable
|
||||||
var count = maxBucket.Episodes.Count - 1;
|
var count = maxBucket.Episodes.Count - 1;
|
||||||
var goodFingerprints = new List<ReadOnlyCollection<uint>>();
|
var goodFingerprints = new List<uint[]>();
|
||||||
foreach (var id in maxBucket.Episodes)
|
foreach (var id in maxBucket.Episodes)
|
||||||
{
|
{
|
||||||
if (!_fingerprintCache.TryGetValue(id, out var fp))
|
if (!_fingerprintCache.TryGetValue(id, out var fp))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user