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.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
@ -90,6 +91,9 @@ public class FileBotPanelSelectionList extends JList {
public void actionPerformed(ActionEvent e) {
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 boolean active = false;
private Boolean active = false;
private long lastTaskCount = 0;
private static ChecksumComputationExecutor instance = null;
private static ChecksumComputationExecutor instance = new ChecksumComputationExecutor();
private LinkedBlockingQueue<ChecksumComputationTask> workQueue = new LinkedBlockingQueue<ChecksumComputationTask>();
@ -48,25 +48,20 @@ public class ChecksumComputationExecutor {
};
private ChecksumComputationExecutor() {
}
public static synchronized ChecksumComputationExecutor getInstance() {
if (instance == null)
instance = new ChecksumComputationExecutor();
public static ChecksumComputationExecutor getInstance() {
return instance;
}
public void execute(ChecksumComputationTask task) {
setActive(true);
synchronized (workQueue) {
setActive(true);
adjustPoolSize();
executor.execute(task);
}
adjustPoolSize();
executor.execute(task);
fireActiveSessionTaskCountChange();
}
@ -78,7 +73,7 @@ public class ChecksumComputationExecutor {
// for only a few files, use only one thread
// for lots of files, use multiple 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)
executor.setCorePoolSize(recommendedPoolSize);
@ -107,22 +102,24 @@ public class ChecksumComputationExecutor {
}
private synchronized void setActive(boolean b) {
if (this.active == b)
return;
this.active = b;
if (!this.active) {
// end of active computing session
lastTaskCount = executor.getTaskCount();
private void setActive(boolean b) {
synchronized (active) {
if (this.active == b)
return;
// reset pool size
adjustPoolSize();
this.active = b;
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) {
propertyChangeSupport.addPropertyChangeListener(listener);
}

View File

@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.panel.sfv;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
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) {
checksumMap.put(columnRoot, checksum);
}

View File

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

View File

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