diff --git a/source/net/sourceforge/filebot/cli/CmdlineOperations.java b/source/net/sourceforge/filebot/cli/CmdlineOperations.java index 7205ad17..30f0f408 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineOperations.java +++ b/source/net/sourceforge/filebot/cli/CmdlineOperations.java @@ -150,7 +150,7 @@ public class CmdlineOperations implements CmdlineInterface { if (strict) { sequence = new SimilarityMetric[] { StrictMetric.EpisodeIdentifier, StrictMetric.Title, StrictMetric.Name }; // use SEI for matching and SN for excluding false positives } else { - sequence = MatchSimilarityMetric.defaultSequence(); // same as in GUI + sequence = MatchSimilarityMetric.defaultSequence(false); // same as in GUI } List> matches = new ArrayList>(); diff --git a/source/net/sourceforge/filebot/ui/rename/EpisodeListMatcher.java b/source/net/sourceforge/filebot/ui/rename/EpisodeListMatcher.java index 43189b57..0676aad2 100644 --- a/source/net/sourceforge/filebot/ui/rename/EpisodeListMatcher.java +++ b/source/net/sourceforge/filebot/ui/rename/EpisodeListMatcher.java @@ -192,7 +192,7 @@ class EpisodeListMatcher implements AutoCompleteMatcher { // group by subtitles first and then by files in general for (List filesPerType : mapByExtension(mediaFiles).values()) { - Matcher matcher = new Matcher(filesPerType, episodes, false, MatchSimilarityMetric.defaultSequence()); + Matcher matcher = new Matcher(filesPerType, episodes, false, MatchSimilarityMetric.defaultSequence(false)); matches.addAll(matcher.match()); } diff --git a/source/net/sourceforge/filebot/ui/rename/MatchAction.java b/source/net/sourceforge/filebot/ui/rename/MatchAction.java index ba328e4a..1aa14ca5 100644 --- a/source/net/sourceforge/filebot/ui/rename/MatchAction.java +++ b/source/net/sourceforge/filebot/ui/rename/MatchAction.java @@ -49,7 +49,7 @@ class MatchAction extends AbstractAction { Window window = getWindow(evt.getSource()); window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - BackgroundMatcher backgroundMatcher = new BackgroundMatcher(model, MatchSimilarityMetric.defaultSequence()); + BackgroundMatcher backgroundMatcher = new BackgroundMatcher(model, MatchSimilarityMetric.defaultSequence(true)); backgroundMatcher.execute(); try { diff --git a/source/net/sourceforge/filebot/ui/rename/MatchSimilarityMetric.java b/source/net/sourceforge/filebot/ui/rename/MatchSimilarityMetric.java index f72d5a41..72097098 100644 --- a/source/net/sourceforge/filebot/ui/rename/MatchSimilarityMetric.java +++ b/source/net/sourceforge/filebot/ui/rename/MatchSimilarityMetric.java @@ -3,12 +3,14 @@ package net.sourceforge.filebot.ui.rename; import static java.lang.Math.*; +import static java.util.Arrays.*; +import static java.util.Collections.*; import static net.sourceforge.tuned.FileUtilities.*; import java.io.File; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; import net.sourceforge.filebot.similarity.DateMetric; import net.sourceforge.filebot.similarity.FileSizeMetric; @@ -65,8 +67,16 @@ public enum MatchSimilarityMetric implements SimilarityMetric { // Match by season / episode numbers SeasonEpisode(new SeasonEpisodeMetric() { + private final Map> matchCache = synchronizedMap(new WeakHashMap>(64, 4)); + + @Override protected Collection parse(Object object) { + Collection result = matchCache.get(object); + if (result != null) { + return result; + } + if (object instanceof Episode) { Episode episode = (Episode) object; @@ -74,26 +84,39 @@ public enum MatchSimilarityMetric implements SimilarityMetric { SxE seasonEpisode = new SxE(episode.getSeason(), episode.getEpisode()); SxE absoluteEpisode = new SxE(null, episode.getAbsolute()); - return seasonEpisode.equals(absoluteEpisode) ? Collections.singleton(absoluteEpisode) : Arrays.asList(seasonEpisode, absoluteEpisode); + result = seasonEpisode.equals(absoluteEpisode) ? singleton(absoluteEpisode) : asList(seasonEpisode, absoluteEpisode); + } else { + result = super.parse(object); } - return super.parse(object); + matchCache.put(object, result); + return result; } }), // Match episode airdate AirDate(new DateMetric() { + private final Map matchCache = synchronizedMap(new WeakHashMap(64, 4)); + + @Override protected Date parse(Object object) { if (object instanceof Episode) { Episode episode = (Episode) object; - // create SxE from episode + // use airdate from episode return episode.airdate(); } - return super.parse(object); + Date result = matchCache.get(object); + if (result != null) { + return result; + } + + result = super.parse(object); + matchCache.put(object, result); + return result; } }), @@ -152,7 +175,6 @@ public enum MatchSimilarityMetric implements SimilarityMetric { return new Object[] { object }; } - }), // Match by generic name similarity @@ -220,13 +242,17 @@ public enum MatchSimilarityMetric implements SimilarityMetric { } - public static SimilarityMetric[] defaultSequence() { + public static SimilarityMetric[] defaultSequence(boolean includeFileMetrics) { // 1. pass: match by file length (fast, but only works when matching torrents or files) // 2. pass: match by season / episode numbers - // 3. pass: match by checking series/episode title against the file path + // 3. pass: match by checking series / episode title against the file path // 4. pass: match by generic name similarity (slow, but most matches will have been determined in second pass) // 5. pass: match by generic numeric similarity - return new SimilarityMetric[] { FileSize, EpisodeIdentifier, Title, Name, Numeric }; + if (includeFileMetrics) { + return new SimilarityMetric[] { FileSize, EpisodeIdentifier, Title, Name, Numeric }; + } else { + return new SimilarityMetric[] { EpisodeIdentifier, Title, Name, Numeric }; + } } }