Cache the fingerprints for a season temporarily
This commit is contained in:
parent
cf1878382b
commit
05c5526bca
@ -46,6 +46,14 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
|
|
||||||
private readonly ILogger<FingerprinterTask> _logger;
|
private readonly ILogger<FingerprinterTask> _logger;
|
||||||
|
|
||||||
|
private readonly object _fingerprintCacheLock = new object();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary fingerprint cache to speed up reanalysis.
|
||||||
|
/// Fingerprints are removed from this after a season is analyzed.
|
||||||
|
/// </summary>
|
||||||
|
private Dictionary<Guid, ReadOnlyCollection<uint>> _fingerprintCache;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="FingerprinterTask"/> class.
|
/// Initializes a new instance of the <see cref="FingerprinterTask"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -53,6 +61,7 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
public FingerprinterTask(ILogger<FingerprinterTask> logger)
|
public FingerprinterTask(ILogger<FingerprinterTask> logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_fingerprintCache = new Dictionary<Guid, ReadOnlyCollection<uint>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -88,9 +97,38 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
|
|
||||||
Parallel.ForEach(queue, (season) =>
|
Parallel.ForEach(queue, (season) =>
|
||||||
{
|
{
|
||||||
AnalyzeSeason(season, cancellationToken);
|
var first = season.Value[0];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AnalyzeSeason(season, cancellationToken);
|
||||||
|
}
|
||||||
|
catch (FingerprintException ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(
|
||||||
|
"Unable to analyze {Series} season {Season}: unable to fingerprint: {Ex}",
|
||||||
|
first.SeriesName,
|
||||||
|
first.SeasonNumber,
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
catch (KeyNotFoundException ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(
|
||||||
|
"Unable to analyze {Series} season {Season}: cache miss: {Ex}",
|
||||||
|
first.SeriesName,
|
||||||
|
first.SeasonNumber,
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear this season's episodes from the temporary fingerprint cache.
|
||||||
|
lock (_fingerprintCacheLock)
|
||||||
|
{
|
||||||
|
foreach (var ep in season.Value)
|
||||||
|
{
|
||||||
|
_fingerprintCache.Remove(ep.EpisodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: report progress on a per episode basis
|
|
||||||
totalProcessed += season.Value.Count;
|
totalProcessed += season.Value.Count;
|
||||||
progress.Report((totalProcessed * 100) / Plugin.Instance!.TotalQueued);
|
progress.Report((totalProcessed * 100) / Plugin.Instance!.TotalQueued);
|
||||||
});
|
});
|
||||||
@ -159,12 +197,6 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
lhs.EpisodeId,
|
lhs.EpisodeId,
|
||||||
rhs.EpisodeId);
|
rhs.EpisodeId);
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: bring back
|
|
||||||
totalProcessed += 2;
|
|
||||||
progress.Report((totalProcessed * 100) / Plugin.Instance!.TotalQueued);
|
|
||||||
*/
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,14 +221,6 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
{
|
{
|
||||||
_logger.LogError("Caught fingerprint error: {Ex}", ex);
|
_logger.LogError("Caught fingerprint error: {Ex}", ex);
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
TODO: bring back
|
|
||||||
totalProcessed += 2;
|
|
||||||
progress.Report((totalProcessed * 100) / Plugin.Instance!.TotalQueued);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin.Instance!.SaveTimestamps();
|
Plugin.Instance!.SaveTimestamps();
|
||||||
@ -221,6 +245,13 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
var lhsFingerprint = FPCalc.Fingerprint(lhsEpisode);
|
var lhsFingerprint = FPCalc.Fingerprint(lhsEpisode);
|
||||||
var rhsFingerprint = FPCalc.Fingerprint(rhsEpisode);
|
var rhsFingerprint = FPCalc.Fingerprint(rhsEpisode);
|
||||||
|
|
||||||
|
// Cache the fingerprints for quicker recall in the second pass (if one is needed).
|
||||||
|
lock (_fingerprintCacheLock)
|
||||||
|
{
|
||||||
|
_fingerprintCache[lhsEpisode.EpisodeId] = lhsFingerprint;
|
||||||
|
_fingerprintCache[rhsEpisode.EpisodeId] = rhsFingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
return FingerprintEpisodes(
|
return FingerprintEpisodes(
|
||||||
lhsEpisode.EpisodeId,
|
lhsEpisode.EpisodeId,
|
||||||
lhsFingerprint,
|
lhsFingerprint,
|
||||||
@ -501,7 +532,6 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
_logger.LogInformation("Reanalyzing {Count} episodes", totalCount - maxBucket.Count);
|
_logger.LogInformation("Reanalyzing {Count} episodes", totalCount - maxBucket.Count);
|
||||||
|
|
||||||
// TODO: pick two episodes at random
|
// TODO: pick two episodes at random
|
||||||
// Cache the fingerprint of the first episode in the max bucket to save CPU cycles
|
|
||||||
var lhs = episodes.Find(x => x.EpisodeId == maxBucket.Episodes[1]);
|
var lhs = episodes.Find(x => x.EpisodeId == maxBucket.Episodes[1]);
|
||||||
if (lhs is null)
|
if (lhs is null)
|
||||||
{
|
{
|
||||||
@ -509,17 +539,7 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlyCollection<uint> lhsFingerprint;
|
var lhsFingerprint = _fingerprintCache[lhs.EpisodeId];
|
||||||
try
|
|
||||||
{
|
|
||||||
lhsFingerprint = FPCalc.Fingerprint(lhs);
|
|
||||||
}
|
|
||||||
catch (FingerprintException ex)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("Skipping reanalysis of {Show} season {Season}: {Exception}", lhs.SeriesName, lhs.SeasonNumber, ex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var lhsDuration = GetIntroDuration(lhs.EpisodeId);
|
var lhsDuration = GetIntroDuration(lhs.EpisodeId);
|
||||||
var (lowTargetDuration, highTargetDuration) = (
|
var (lowTargetDuration, highTargetDuration) = (
|
||||||
lhsDuration - ReanalysisTolerance,
|
lhsDuration - ReanalysisTolerance,
|
||||||
@ -561,7 +581,7 @@ public class FingerprinterTask : IScheduledTask
|
|||||||
lhs.EpisodeId,
|
lhs.EpisodeId,
|
||||||
lhsFingerprint,
|
lhsFingerprint,
|
||||||
episode.EpisodeId,
|
episode.EpisodeId,
|
||||||
FPCalc.Fingerprint(episode));
|
_fingerprintCache[episode.EpisodeId]);
|
||||||
|
|
||||||
// Ensure that the new intro duration is within the targeted bucket and longer than what was found previously.
|
// Ensure that the new intro duration is within the targeted bucket and longer than what was found previously.
|
||||||
var newDuration = Math.Round(newRhs.IntroEnd - newRhs.IntroStart, 2);
|
var newDuration = Math.Round(newRhs.IntroEnd - newRhs.IntroStart, 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user