Clover icon

Coverage Report

  1. Project Clover database Mon Nov 18 2024 09:38:20 GMT
  2. Package jalview.workers

File AlignCalcManager.java

 

Coverage histogram

../../img/srcFileCovDistChart7.png
21% of files have more coverage

Code metrics

36
114
18
1
421
321
36
0.32
6.33
18
2

Classes

Class Line # Actions
AlignCalcManager 36 114 36
0.6309523663.1%
 

Contributing tests

This file is covered by 167 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.workers;
22   
23    import java.util.ArrayList;
24    import java.util.Collection;
25    import java.util.Collections;
26    import java.util.HashSet;
27    import java.util.Hashtable;
28    import java.util.List;
29    import java.util.Map;
30    import java.util.Set;
31   
32    import jalview.api.AlignCalcManagerI;
33    import jalview.api.AlignCalcWorkerI;
34    import jalview.datamodel.AlignmentAnnotation;
35   
 
36    public class AlignCalcManager implements AlignCalcManagerI
37    {
38    /*
39    * list of registered workers
40    */
41    private volatile List<AlignCalcWorkerI> restartable;
42   
43    /*
44    * types of worker _not_ to run (for example, because they have
45    * previously thrown errors)
46    */
47    private volatile List<Class<? extends AlignCalcWorkerI>> blackList;
48   
49    /*
50    * global record of calculations in progress
51    */
52    private volatile List<AlignCalcWorkerI> inProgress;
53   
54    /*
55    * record of calculations pending or in progress in the current context
56    */
57    private volatile Map<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>> updating;
58   
59    /*
60    * workers that have run to completion so are candidates for visual-only
61    * update of their results
62    */
63    private HashSet<AlignCalcWorkerI> canUpdate;
64   
65    /**
66    * Constructor
67    */
 
68  272 toggle public AlignCalcManager()
69    {
70  272 restartable = Collections
71    .synchronizedList(new ArrayList<AlignCalcWorkerI>());
72  272 blackList = Collections.synchronizedList(
73    new ArrayList<Class<? extends AlignCalcWorkerI>>());
74  272 inProgress = Collections
75    .synchronizedList(new ArrayList<AlignCalcWorkerI>());
76  272 updating = Collections.synchronizedMap(
77    new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>());
78  272 canUpdate = new HashSet<AlignCalcWorkerI>();
79    }
80   
 
81  980 toggle @Override
82    public void notifyStart(AlignCalcWorkerI worker)
83    {
84  980 synchronized (updating)
85    {
86  981 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
87  981 if (upd == null)
88    {
89  579 updating.put(worker.getClass(), upd = Collections
90    .synchronizedList(new ArrayList<AlignCalcWorkerI>()));
91    }
92  981 synchronized (upd)
93    {
94  981 upd.add(worker);
95    }
96    }
97    }
98   
99    /*
100    * (non-Javadoc)
101    *
102    * @see jalview.api.AlignCalcManagerI#isPending(jalview.api.AlignCalcWorkerI)
103    */
 
104  1515 toggle @Override
105    public boolean isPending(AlignCalcWorkerI workingClass)
106    {
107  1515 List<AlignCalcWorkerI> upd;
108  1515 synchronized (updating)
109    {
110  1515 upd = updating.get(workingClass.getClass());
111  1515 if (upd == null)
112    {
113  423 return false;
114    }
115  1092 synchronized (upd)
116    {
117  1092 if (upd.size() > 1)
118    {
119  2 return true;
120    }
121    }
122  1090 return false;
123    }
124    }
125   
 
126  980 toggle @Override
127    public boolean notifyWorking(AlignCalcWorkerI worker)
128    {
129  980 synchronized (inProgress)
130    {
131  980 if (inProgress.contains(worker))
132    {
133  4 return false; // worker is already working, so ask caller to wait around
134    }
135    else
136    {
137  976 inProgress.add(worker);
138    }
139    }
140  976 return true;
141    }
142   
 
143  989 toggle @Override
144    public void workerComplete(AlignCalcWorkerI worker)
145    {
146  989 synchronized (inProgress)
147    {
148    // jalview.bin.Console.errPrintln("Worker " + worker + " marked as
149    // complete.");
150  989 inProgress.remove(worker);
151  989 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
152  989 if (upd != null)
153    {
154  989 synchronized (upd)
155    {
156  989 upd.remove(worker);
157    }
158  989 canUpdate.add(worker);
159    }
160    }
161    }
162   
 
163  0 toggle @Override
164    public void disableWorker(AlignCalcWorkerI worker)
165    {
166  0 synchronized (blackList)
167    {
168  0 blackList.add(worker.getClass());
169    }
170    }
171   
 
172  981 toggle @Override
173    public boolean isDisabled(AlignCalcWorkerI worker)
174    {
175  981 synchronized (blackList)
176    {
177  981 return blackList.contains(worker.getClass());
178    }
179    }
180   
 
181  981 toggle @Override
182    public void startWorker(AlignCalcWorkerI worker)
183    {
184  981 if (!isDisabled(worker))
185    {
186  981 Thread tw = new Thread(worker);
187  981 tw.setName(worker.getClass().toString());
188  981 tw.start();
189    }
190    }
191   
 
192  0 toggle @Override
193    public boolean isWorking(AlignCalcWorkerI worker)
194    {
195  0 synchronized (inProgress)
196    {// jalview.bin.Console.errPrintln("isWorking : worker "+(worker!=null ?
197    // worker.getClass():"null")+ " "+hashCode());
198  0 return worker != null && inProgress.contains(worker);
199    }
200    }
201   
 
202  764 toggle @Override
203    public boolean isWorking()
204    {
205  764 boolean working = false;
206  764 synchronized (inProgress)
207    {
208    // jalview.bin.Console.errPrintln("isWorking "+hashCode());
209  764 working |= inProgress.size() > 0;
210    }
211  764 synchronized (updating)
212    {
213  764 Collection<List<AlignCalcWorkerI>> workersLists = updating.values();
214  764 synchronized (workersLists)
215    {
216  764 for (List<AlignCalcWorkerI> workers : workersLists)
217    {
218  1907 if (workers != null)
219    {
220  1906 synchronized (workers)
221    {
222  1907 working |= workers.size() > 0;
223    }
224    }
225    }
226    }
227    }
228  764 return working;
229    }
230   
 
231  581 toggle @Override
232    public void registerWorker(AlignCalcWorkerI worker)
233    {
234  581 synchronized (restartable)
235    {
236  581 if (!restartable.contains(worker))
237    {
238  581 restartable.add(worker);
239    }
240  581 startWorker(worker);
241    }
242    }
243   
 
244  168 toggle @Override
245    public void restartWorkers()
246    {
247  168 synchronized (restartable)
248    {
249  168 for (AlignCalcWorkerI worker : restartable)
250    {
251  400 startWorker(worker);
252    }
253    }
254    }
255   
 
256  1964 toggle @Override
257    public boolean workingInvolvedWith(
258    AlignmentAnnotation alignmentAnnotation)
259    {
260  1964 synchronized (inProgress)
261    {
262  1964 for (AlignCalcWorkerI worker : inProgress)
263    {
264  43 if (worker.involves(alignmentAnnotation))
265    {
266  10 return true;
267    }
268    }
269    }
270  1954 synchronized (updating)
271    {
272  1954 for (List<AlignCalcWorkerI> workers : updating.values())
273    {
274  5155 for (AlignCalcWorkerI worker : workers)
275    {
276  48 if (worker.involves(alignmentAnnotation))
277    {
278  8 return true;
279    }
280    }
281    }
282    }
283  1946 return false;
284    }
285   
 
286  0 toggle @Override
287    public void updateAnnotationFor(
288    Class<? extends AlignCalcWorkerI> workerClass)
289    {
290   
291  0 AlignCalcWorkerI[] workers;
292  0 synchronized (canUpdate)
293    {
294  0 workers = canUpdate.toArray(new AlignCalcWorkerI[0]);
295    }
296  0 for (AlignCalcWorkerI worker : workers)
297    {
298  0 if (workerClass.equals(worker.getClass()))
299    {
300  0 worker.updateAnnotation();
301    }
302    }
303    }
304   
 
305  1994 toggle @Override
306    public List<AlignCalcWorkerI> getRegisteredWorkersOfClass(
307    Class<? extends AlignCalcWorkerI> workerClass)
308    {
309  1994 List<AlignCalcWorkerI> workingClass = new ArrayList<AlignCalcWorkerI>();
310  1994 AlignCalcWorkerI[] workers;
311  1994 synchronized (canUpdate)
312    {
313  1994 workers = canUpdate.toArray(new AlignCalcWorkerI[0]);
314    }
315  1994 for (AlignCalcWorkerI worker : workers)
316    {
317  4017 if (workerClass.equals(worker.getClass()))
318    {
319  420 workingClass.add(worker);
320    }
321    }
322  1994 return (workingClass.size() == 0) ? null : workingClass;
323    }
324   
 
325  0 toggle @Override
326    public void enableWorker(AlignCalcWorkerI worker)
327    {
328  0 synchronized (blackList)
329    {
330  0 blackList.remove(worker.getClass());
331    }
332    }
333   
 
334  0 toggle @Override
335    public void removeRegisteredWorkersOfClass(
336    Class<? extends AlignCalcWorkerI> typeToRemove)
337    {
338  0 List<AlignCalcWorkerI> removable = new ArrayList<AlignCalcWorkerI>();
339  0 Set<AlignCalcWorkerI> toremovannot = new HashSet<AlignCalcWorkerI>();
340  0 synchronized (restartable)
341    {
342  0 for (AlignCalcWorkerI worker : restartable)
343    {
344  0 if (typeToRemove.equals(worker.getClass()))
345    {
346  0 removable.add(worker);
347  0 toremovannot.add(worker);
348    }
349    }
350  0 restartable.removeAll(removable);
351    }
352  0 synchronized (canUpdate)
353    {
354  0 for (AlignCalcWorkerI worker : canUpdate)
355    {
356  0 if (typeToRemove.equals(worker.getClass()))
357    {
358  0 removable.add(worker);
359  0 toremovannot.add(worker);
360    }
361    }
362  0 canUpdate.removeAll(removable);
363    }
364    // TODO: finish testing this extension
365   
366    /*
367    * synchronized (inProgress) { // need to kill or mark as dead any running
368    * threads... (inProgress.get(typeToRemove)); }
369    *
370    * if (workers == null) { return; } for (AlignCalcWorkerI worker : workers)
371    * {
372    *
373    * if (isPending(worker)) { worker.abortAndDestroy(); startWorker(worker); }
374    * else { jalview.bin.Console.errPrintln("Pending exists for " + workerClass); } }
375    */
376    }
377   
378    /**
379    * Deletes the worker that update the given annotation, provided it is marked
380    * as deletable.
381    */
 
382  0 toggle @Override
383    public void removeWorkerForAnnotation(AlignmentAnnotation ann)
384    {
385    /*
386    * first just find those to remove (to avoid
387    * ConcurrentModificationException)
388    */
389  0 List<AlignCalcWorkerI> toRemove = new ArrayList<AlignCalcWorkerI>();
390  0 for (AlignCalcWorkerI worker : restartable)
391    {
392  0 if (worker.involves(ann))
393    {
394  0 if (worker.isDeletable())
395    {
396  0 toRemove.add(worker);
397    }
398    }
399    }
400   
401    /*
402    * remove all references to deleted workers so any references
403    * they hold to annotation data can be garbage collected
404    */
405  0 for (AlignCalcWorkerI worker : toRemove)
406    {
407  0 restartable.remove(worker);
408  0 blackList.remove(worker.getClass());
409  0 inProgress.remove(worker);
410  0 canUpdate.remove(worker);
411  0 synchronized (updating)
412    {
413  0 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
414  0 if (upd != null)
415    {
416  0 upd.remove(worker);
417    }
418    }
419    }
420    }
421    }