mirror of
https://github.com/mitb-archive/filebot
synced 2024-12-24 16:58:51 -05:00
* cache MediaInfo instances
This commit is contained in:
parent
6d2667f3a1
commit
8c0ce2ed21
@ -29,7 +29,6 @@ import java.util.Scanner;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.WeakHashMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -45,6 +44,7 @@ import net.filebot.mediainfo.MediaInfo;
|
|||||||
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
||||||
import net.filebot.similarity.SimilarityComparator;
|
import net.filebot.similarity.SimilarityComparator;
|
||||||
import net.filebot.util.FileUtilities;
|
import net.filebot.util.FileUtilities;
|
||||||
|
import net.filebot.util.WeakValueHashMap;
|
||||||
import net.filebot.web.AudioTrack;
|
import net.filebot.web.AudioTrack;
|
||||||
import net.filebot.web.Episode;
|
import net.filebot.web.Episode;
|
||||||
import net.filebot.web.EpisodeListProvider;
|
import net.filebot.web.EpisodeListProvider;
|
||||||
@ -65,7 +65,6 @@ public class MediaBindingBean {
|
|||||||
private final File mediaFile;
|
private final File mediaFile;
|
||||||
private final Map<File, Object> context;
|
private final Map<File, Object> context;
|
||||||
|
|
||||||
private String mediaInfoKey;
|
|
||||||
private MediaInfo mediaInfo;
|
private MediaInfo mediaInfo;
|
||||||
private Object metaInfo;
|
private Object metaInfo;
|
||||||
|
|
||||||
@ -878,7 +877,7 @@ public class MediaBindingBean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<String, MediaInfo> sharedMediaInfoObjects = new WeakHashMap<String, MediaInfo>(64);
|
private static final Map<File, MediaInfo> sharedMediaInfoObjects = new WeakValueHashMap<File, MediaInfo>(64);
|
||||||
|
|
||||||
private synchronized MediaInfo getMediaInfo() {
|
private synchronized MediaInfo getMediaInfo() {
|
||||||
// make sure media file is defined
|
// make sure media file is defined
|
||||||
@ -886,25 +885,17 @@ public class MediaBindingBean {
|
|||||||
|
|
||||||
// lazy initialize
|
// lazy initialize
|
||||||
if (mediaInfo == null) {
|
if (mediaInfo == null) {
|
||||||
// lazy initialize
|
|
||||||
if (mediaInfoKey == null) {
|
|
||||||
// use inferred media file (e.g. actual movie file instead of subtitle file)
|
// use inferred media file (e.g. actual movie file instead of subtitle file)
|
||||||
try {
|
File inferredMediaFile = getInferredMediaFile();
|
||||||
// make sure to create a new String object which can be garbage collected as soon the binding object not used anymore
|
|
||||||
mediaInfoKey = new String(getInferredMediaFile().getCanonicalPath());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new IllegalStateException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (sharedMediaInfoObjects) {
|
synchronized (sharedMediaInfoObjects) {
|
||||||
mediaInfo = sharedMediaInfoObjects.get(mediaInfoKey);
|
mediaInfo = sharedMediaInfoObjects.get(inferredMediaFile);
|
||||||
if (mediaInfo == null) {
|
if (mediaInfo == null) {
|
||||||
MediaInfo mi = new MediaInfo();
|
MediaInfo mi = new MediaInfo();
|
||||||
if (!mi.open(new File(new String(mediaInfoKey)))) {
|
if (!mi.open(inferredMediaFile)) {
|
||||||
throw new RuntimeException("Cannot open media file: " + mediaInfoKey);
|
throw new RuntimeException("Cannot open media file: " + inferredMediaFile);
|
||||||
}
|
}
|
||||||
sharedMediaInfoObjects.put(mediaInfoKey, mi);
|
sharedMediaInfoObjects.put(inferredMediaFile, mi);
|
||||||
mediaInfo = mi;
|
mediaInfo = mi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,9 @@ public class MediaInfo implements Closeable {
|
|||||||
if (handle == null)
|
if (handle == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
// System.out.println("Dispose " + this);
|
||||||
|
|
||||||
// delete handle
|
// delete handle
|
||||||
MediaInfoLibrary.INSTANCE.Delete(handle);
|
MediaInfoLibrary.INSTANCE.Delete(handle);
|
||||||
handle = null;
|
handle = null;
|
||||||
|
128
source/net/filebot/util/WeakValueHashMap.java
Normal file
128
source/net/filebot/util/WeakValueHashMap.java
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package net.filebot.util;
|
||||||
|
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class WeakValueHashMap<K, V> extends AbstractMap<K, V> {
|
||||||
|
|
||||||
|
private HashMap<K, WeakValue<V>> references;
|
||||||
|
private ReferenceQueue<V> referenceQueue;
|
||||||
|
|
||||||
|
public WeakValueHashMap(int capacity) {
|
||||||
|
references = new HashMap<K, WeakValue<V>>(capacity);
|
||||||
|
referenceQueue = new ReferenceQueue<V>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V put(K key, V value) {
|
||||||
|
processQueue();
|
||||||
|
|
||||||
|
WeakValue<V> valueRef = new WeakValue<V>(key, value, referenceQueue);
|
||||||
|
return getReferenceValue(references.put(key, valueRef));
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V get(Object key) {
|
||||||
|
processQueue();
|
||||||
|
|
||||||
|
return getReferenceValue(references.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V remove(Object key) {
|
||||||
|
return getReferenceValue(references.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
references.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(Object key) {
|
||||||
|
processQueue();
|
||||||
|
|
||||||
|
return references.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsValue(Object value) {
|
||||||
|
processQueue();
|
||||||
|
|
||||||
|
for (Entry<K, WeakValue<V>> entry : references.entrySet()) {
|
||||||
|
if (value == getReferenceValue(entry.getValue())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<K> keySet() {
|
||||||
|
processQueue();
|
||||||
|
|
||||||
|
return references.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
processQueue();
|
||||||
|
|
||||||
|
return references.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Entry<K, V>> entrySet() {
|
||||||
|
processQueue();
|
||||||
|
|
||||||
|
Set<Entry<K, V>> entries = new LinkedHashSet<Entry<K, V>>();
|
||||||
|
for (Entry<K, WeakValue<V>> entry : references.entrySet()) {
|
||||||
|
entries.add(new SimpleImmutableEntry<K, V>(entry.getKey(), getReferenceValue(entry.getValue())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<V> values() {
|
||||||
|
processQueue();
|
||||||
|
|
||||||
|
Collection<V> values = new ArrayList<V>();
|
||||||
|
for (WeakValue<V> valueRef : references.values()) {
|
||||||
|
values.add(getReferenceValue(valueRef));
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
private V getReferenceValue(WeakValue<V> valueRef) {
|
||||||
|
return valueRef == null ? null : valueRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processQueue() {
|
||||||
|
WeakValue<?> valueRef;
|
||||||
|
while ((valueRef = (WeakValue<?>) referenceQueue.poll()) != null) {
|
||||||
|
references.remove(valueRef.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class WeakValue<T> extends WeakReference<T> {
|
||||||
|
|
||||||
|
private final K key;
|
||||||
|
|
||||||
|
private WeakValue(K key, T value, ReferenceQueue<T> queue) {
|
||||||
|
super(value, queue);
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
private K getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user