threading bugfixes and improvements

This commit is contained in:
Reinhard Pointner 2007-12-24 21:16:14 +00:00
parent a94e60312c
commit ecf7674c95
5 changed files with 98 additions and 64 deletions

View File

@ -16,6 +16,7 @@ import javax.swing.DefaultListModel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer; import javax.swing.Timer;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
@ -90,6 +91,9 @@ public class FileBotPanelSelectionList extends JList {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
selectEnabled = true; selectEnabled = true;
// bring window to front when on dnd
SwingUtilities.getWindowAncestor(FileBotPanelSelectionList.this).toFront();
} }

View File

@ -22,10 +22,10 @@ public class ChecksumComputationExecutor {
private static final int MINIMUM_POOL_SIZE = 1; private static final int MINIMUM_POOL_SIZE = 1;
private boolean active = false; private Boolean active = false;
private long lastTaskCount = 0; private long lastTaskCount = 0;
private static ChecksumComputationExecutor instance = null; private static ChecksumComputationExecutor instance = new ChecksumComputationExecutor();
private LinkedBlockingQueue<ChecksumComputationTask> workQueue = new LinkedBlockingQueue<ChecksumComputationTask>(); private LinkedBlockingQueue<ChecksumComputationTask> workQueue = new LinkedBlockingQueue<ChecksumComputationTask>();
@ -48,25 +48,20 @@ public class ChecksumComputationExecutor {
}; };
private ChecksumComputationExecutor() { public static ChecksumComputationExecutor getInstance() {
}
public static synchronized ChecksumComputationExecutor getInstance() {
if (instance == null)
instance = new ChecksumComputationExecutor();
return instance; return instance;
} }
public void execute(ChecksumComputationTask task) { public void execute(ChecksumComputationTask task) {
setActive(true); synchronized (workQueue) {
setActive(true);
adjustPoolSize();
executor.execute(task);
}
adjustPoolSize();
executor.execute(task);
fireActiveSessionTaskCountChange(); fireActiveSessionTaskCountChange();
} }
@ -78,7 +73,7 @@ public class ChecksumComputationExecutor {
// for only a few files, use only one thread // for only a few files, use only one thread
// for lots of files, use multiple threads // for lots of files, use multiple threads
// e.g 200 files ~ 1 thread, 1000 files ~ 2 threads, 40000 files ~ 4 threads // e.g 200 files ~ 1 thread, 1000 files ~ 2 threads, 40000 files ~ 4 threads
int recommendedPoolSize = (int) Math.max(Math.log10(Math.max(workQueue.size(), 1)), MINIMUM_POOL_SIZE); int recommendedPoolSize = (int) Math.log10(Math.max(workQueue.size(), 1) + MINIMUM_POOL_SIZE);
if (executor.getCorePoolSize() != recommendedPoolSize) if (executor.getCorePoolSize() != recommendedPoolSize)
executor.setCorePoolSize(recommendedPoolSize); executor.setCorePoolSize(recommendedPoolSize);
@ -107,22 +102,24 @@ public class ChecksumComputationExecutor {
} }
private synchronized void setActive(boolean b) { private void setActive(boolean b) {
if (this.active == b) synchronized (active) {
return; if (this.active == b)
return;
this.active = b;
if (!this.active) {
// end of active computing session
lastTaskCount = executor.getTaskCount();
// reset pool size this.active = b;
adjustPoolSize();
if (!this.active) {
// end of active computing session
lastTaskCount = executor.getTaskCount();
// reset pool size
adjustPoolSize();
}
// invoke property change events on EDT
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(ACTIVE_PROPERTY, null, active));
} }
// invoke property change events on EDT
SwingUtilities.invokeLater(new FirePropertyChangeRunnable(ACTIVE_PROPERTY, null, active));
} }
@ -160,6 +157,20 @@ public class ChecksumComputationExecutor {
} }
public void clear() {
synchronized (workQueue) {
executor.purge();
workQueue.clear();
adjustPoolSize();
if (executor.getActiveCount() == 0) {
setActive(false);
}
}
}
public void addPropertyChangeListener(PropertyChangeListener listener) { public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener); propertyChangeSupport.addPropertyChangeListener(listener);
} }

View File

@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.panel.sfv;
import java.io.File; import java.io.File;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -77,6 +78,11 @@ public class ChecksumRow {
} }
public Collection<Checksum> getChecksums() {
return checksumMap.values();
}
public void putChecksum(File columnRoot, Checksum checksum) { public void putChecksum(File columnRoot, Checksum checksum) {
checksumMap.put(columnRoot, checksum); checksumMap.put(columnRoot, checksum);
} }

View File

@ -30,11 +30,6 @@ public class SfvTableModel extends AbstractTableModel {
private int checksumColumnsOffset = 2; private int checksumColumnsOffset = 2;
public SfvTableModel() {
}
@Override @Override
public String getColumnName(int columnIndex) { public String getColumnName(int columnIndex) {
if (columnIndex == 0) if (columnIndex == 0)
@ -152,16 +147,16 @@ public class SfvTableModel extends AbstractTableModel {
public synchronized void clear() { public synchronized void clear() {
// stop any running computations // stop any running computations
for (ChecksumRow row : rows) { for (ChecksumRow row : rows) {
for (File columnRoot : checksumColumnRoots) { for (Checksum checksum : row.getChecksums()) {
Checksum c = row.getChecksum(columnRoot); checksum.cancelComputationTask();
if (c != null)
c.cancelComputationTask();
} }
} }
ChecksumComputationExecutor.getInstance().clear();
checksumColumnRoots.clear(); checksumColumnRoots.clear();
rows.clear(); rows.clear();
rowMap.clear(); rowMap.clear();

View File

@ -6,14 +6,12 @@ import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import net.sourceforge.filebot.ui.FileFormat; import net.sourceforge.filebot.ui.FileFormat;
import net.sourceforge.filebot.ui.transferablepolicies.BackgroundFileTransferablePolicy; import net.sourceforge.filebot.ui.transferablepolicies.BackgroundFileTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.FileTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.MultiTransferablePolicy; import net.sourceforge.filebot.ui.transferablepolicies.MultiTransferablePolicy;
@ -30,7 +28,7 @@ public class SfvTransferablePolicy extends MultiTransferablePolicy {
} }
private class SfvFilePolicy extends FileTransferablePolicy { private class SfvFilePolicy extends BackgroundFileTransferablePolicy<SfvTableModel.Entry> {
@Override @Override
protected boolean accept(File file) { protected boolean accept(File file) {
@ -45,6 +43,28 @@ public class SfvTransferablePolicy extends MultiTransferablePolicy {
} }
@Override
protected void process(List<SfvTableModel.Entry> chunks) {
tableModel.addAll(chunks);
}
@Override
protected boolean load(List<File> files) {
synchronized (ChecksumComputationExecutor.getInstance()) {
ChecksumComputationExecutor.getInstance().pause();
for (File file : files) {
load(file);
}
ChecksumComputationExecutor.getInstance().resume();
}
return true;
}
@Override @Override
protected boolean load(File sfvFile) { protected boolean load(File sfvFile) {
@ -54,8 +74,6 @@ public class SfvTransferablePolicy extends MultiTransferablePolicy {
String line = null; String line = null;
Pattern pattern = Pattern.compile("(.*)\\s+(\\p{XDigit}{8})"); Pattern pattern = Pattern.compile("(.*)\\s+(\\p{XDigit}{8})");
ArrayList<SfvTableModel.Entry> entries = new ArrayList<SfvTableModel.Entry>(50);
while ((line = in.readLine()) != null) { while ((line = in.readLine()) != null) {
if (line.startsWith(";")) if (line.startsWith(";"))
continue; continue;
@ -68,21 +86,17 @@ public class SfvTransferablePolicy extends MultiTransferablePolicy {
String filename = matcher.group(1); String filename = matcher.group(1);
String checksumString = matcher.group(2); String checksumString = matcher.group(2);
entries.add(new SfvTableModel.Entry(filename, new Checksum(checksumString), sfvFile)); publish(new SfvTableModel.Entry(filename, new Checksum(checksumString), sfvFile));
File compareColumnRoot = sfvFile.getParentFile(); File compareColumnRoot = sfvFile.getParentFile();
File compareFile = new File(compareColumnRoot, filename); File compareFile = new File(compareColumnRoot, filename);
if (compareFile.exists()) { if (compareFile.exists()) {
entries.add(new SfvTableModel.Entry(filename, new Checksum(compareFile), compareColumnRoot)); publish(new SfvTableModel.Entry(filename, new Checksum(compareFile), compareColumnRoot));
} }
} }
in.close(); in.close();
if (!entries.isEmpty()) {
tableModel.addAll(entries);
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return false; return false;
@ -124,22 +138,26 @@ public class SfvTransferablePolicy extends MultiTransferablePolicy {
if (files.isEmpty()) if (files.isEmpty())
return true; return true;
ChecksumComputationExecutor.getInstance().pause(); synchronized (ChecksumComputationExecutor.getInstance()) {
ChecksumComputationExecutor.getInstance().pause();
File firstFile = files.get(0);
if ((files.size() == 1 && firstFile.isDirectory())) {
for (File f : firstFile.listFiles())
load(f, firstFile, "");
} else {
File columnRoot = firstFile.getParentFile();
for (File f : files) File firstFile = files.get(0);
load(f, columnRoot, "");
if ((files.size() == 1 && firstFile.isDirectory())) {
for (File f : firstFile.listFiles()) {
load(f, firstFile, "");
}
} else {
File columnRoot = firstFile.getParentFile();
for (File f : files) {
load(f, columnRoot, "");
}
}
ChecksumComputationExecutor.getInstance().resume();
} }
ChecksumComputationExecutor.getInstance().resume();
return true; return true;
} }