2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.1)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
17 * The Jalview Authors are detailed in the 'AUTHORS' file.
19 package jalview.workers;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.Hashtable;
25 import java.util.List;
29 import jalview.api.AlignCalcManagerI;
30 import jalview.api.AlignCalcWorkerI;
31 import jalview.datamodel.AlignmentAnnotation;
33 public class AlignCalcManager implements AlignCalcManagerI
35 private volatile List<AlignCalcWorkerI> restartable = Collections
36 .synchronizedList(new ArrayList<AlignCalcWorkerI>());
38 private volatile List<Class> blackList = Collections
39 .synchronizedList(new ArrayList<Class>());
42 * global record of calculations in progress
44 private volatile Map<Class, AlignCalcWorkerI> inProgress = Collections
45 .synchronizedMap(new Hashtable<Class, AlignCalcWorkerI>());
48 * record of calculations pending or in progress in the current context
50 private volatile Map<Class, List<AlignCalcWorkerI>> updating = Collections
51 .synchronizedMap(new Hashtable<Class, List<AlignCalcWorkerI>>());
54 public void notifyStart(AlignCalcWorkerI worker)
56 synchronized (updating)
58 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
64 .synchronizedList(new ArrayList<AlignCalcWorkerI>()));
74 public boolean alreadyDoing(AlignCalcWorkerI worker)
76 synchronized (inProgress)
78 return inProgress.containsKey(worker.getClass());
85 * @see jalview.api.AlignCalcManagerI#isPending(jalview.api.AlignCalcWorkerI)
88 public boolean isPending(AlignCalcWorkerI workingClass)
90 List<AlignCalcWorkerI> upd;
91 synchronized (updating)
93 upd = updating.get(workingClass.getClass());
109 // TODO make into api method if needed ?
110 public int numberLive(AlignCalcWorkerI worker)
112 synchronized (updating)
114 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
125 public boolean notifyWorking(AlignCalcWorkerI worker)
127 synchronized (inProgress)
129 // TODO: decide if we should throw exceptions here if multiple workers
131 if (inProgress.get(worker.getClass()) != null)
136 .println("Warning: Multiple workers are running of type "
137 + worker.getClass());
141 inProgress.put(worker.getClass(), worker);
146 private final HashSet<AlignCalcWorkerI> canUpdate = new HashSet<AlignCalcWorkerI>();
149 public void workerComplete(AlignCalcWorkerI worker)
151 synchronized (inProgress)
153 // System.err.println("Worker "+worker.getClass()+" marked as complete.");
154 inProgress.remove(worker.getClass());
155 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
162 canUpdate.add(worker);
168 public void workerCannotRun(AlignCalcWorkerI worker)
170 synchronized (blackList)
172 blackList.add(worker.getClass());
176 public boolean isBlackListed(Class workerType)
178 synchronized (blackList)
180 return blackList.contains(workerType);
185 public void startWorker(AlignCalcWorkerI worker)
187 // System.err.println("Starting "+worker.getClass());
188 // new Exception("").printStackTrace();
189 Thread tw = new Thread(worker);
190 tw.setName(worker.getClass().toString());
195 public boolean isWorking(AlignCalcWorkerI worker)
197 synchronized (inProgress)
198 {// System.err.println("isWorking : worker "+(worker!=null ?
199 // worker.getClass():"null")+ " "+hashCode());
200 return worker != null && inProgress.get(worker.getClass()) == worker;
205 public boolean isWorking()
207 synchronized (inProgress)
209 // System.err.println("isWorking "+hashCode());
210 return inProgress.size() > 0;
215 public void registerWorker(AlignCalcWorkerI worker)
217 synchronized (restartable)
219 if (!restartable.contains(worker))
221 restartable.add(worker);
228 public void restartWorkers()
230 synchronized (restartable)
232 for (AlignCalcWorkerI worker : restartable)
240 public boolean workingInvolvedWith(AlignmentAnnotation alignmentAnnotation)
242 synchronized (inProgress)
244 for (AlignCalcWorkerI worker : inProgress.values())
246 if (worker.involves(alignmentAnnotation))
252 synchronized (updating)
254 for (List<AlignCalcWorkerI> workers : updating.values())
256 for (AlignCalcWorkerI worker : workers)
257 if (worker.involves(alignmentAnnotation))
267 public void updateAnnotationFor(Class workerClass)
270 AlignCalcWorkerI[] workers;
271 synchronized (canUpdate)
273 workers = canUpdate.toArray(new AlignCalcWorkerI[0]);
275 for (AlignCalcWorkerI worker : workers)
277 if (workerClass.equals(worker.getClass()))
279 worker.updateAnnotation();
285 public List<AlignCalcWorkerI> getRegisteredWorkersOfClass(
288 List<AlignCalcWorkerI> workingClass = new ArrayList<AlignCalcWorkerI>();
289 AlignCalcWorkerI[] workers;
290 synchronized (canUpdate)
292 workers = canUpdate.toArray(new AlignCalcWorkerI[0]);
294 for (AlignCalcWorkerI worker : workers)
296 if (workerClass.equals(worker.getClass()))
298 workingClass.add(worker);
301 return (workingClass.size() == 0) ? null : workingClass;
305 public boolean startRegisteredWorkersOfClass(Class workerClass)
307 List<AlignCalcWorkerI> workers = getRegisteredWorkersOfClass(workerClass);
312 for (AlignCalcWorkerI worker : workers)
314 if (!isPending(worker))
320 System.err.println("Pending exists for " + workerClass);
327 public void workerMayRun(AlignCalcWorkerI worker)
329 synchronized (blackList)
331 if (blackList.contains(worker.getClass()))
333 blackList.remove(worker.getClass());
339 public void removeRegisteredWorkersOfClass(Class typeToRemove)
341 List<AlignCalcWorkerI> workers = getRegisteredWorkersOfClass(typeToRemove);
342 List<AlignCalcWorkerI> removable = new ArrayList<AlignCalcWorkerI>();
343 Set<AlignCalcWorkerI> toremovannot = new HashSet<AlignCalcWorkerI>();
344 synchronized (restartable)
346 for (AlignCalcWorkerI worker : restartable)
348 if (typeToRemove.equals(worker.getClass()))
350 removable.add(worker);
351 toremovannot.add(worker);
354 restartable.removeAll(removable);
356 synchronized (canUpdate)
358 for (AlignCalcWorkerI worker : canUpdate)
360 if (typeToRemove.equals(worker.getClass()))
362 removable.add(worker);
363 toremovannot.add(worker);
366 canUpdate.removeAll(removable);
368 // TODO: finish testing this extension
371 * synchronized (inProgress) { // need to kill or mark as dead any running
372 * threads... (inProgress.get(typeToRemove)); }
374 * if (workers == null) { return; } for (AlignCalcWorkerI worker : workers)
377 * if (isPending(worker)) { worker.abortAndDestroy(); startWorker(worker); }
378 * else { System.err.println("Pending exists for " + workerClass); } }