1. Project Clover database Fri Dec 6 2024 13:47:14 GMT
  2. Package jalview.workers

File AlignCalcManager.java

 

Coverage histogram

../../img/srcFileCovDistChart9.png
12% 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.821428682.1%
 

Contributing tests

This file is covered by 215 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  508 toggle public AlignCalcManager()
69    {
70  508 restartable = Collections
71    .synchronizedList(new ArrayList<AlignCalcWorkerI>());
72  508 blackList = Collections.synchronizedList(
73    new ArrayList<Class<? extends AlignCalcWorkerI>>());
74  508 inProgress = Collections
75    .synchronizedList(new ArrayList<AlignCalcWorkerI>());
76  508 updating = Collections.synchronizedMap(
77    new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>());
78  508 canUpdate = new HashSet<AlignCalcWorkerI>();
79    }
80   
 
81  3068 toggle @Override
82    public void notifyStart(AlignCalcWorkerI worker)
83    {
84  3068 synchronized (updating)
85    {
86  3068 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
87  3068 if (upd == null)
88    {
89  1267 updating.put(worker.getClass(), upd = Collections
90    .synchronizedList(new ArrayList<AlignCalcWorkerI>()));
91    }
92  3068 synchronized (upd)
93    {
94  3068 upd.add(worker);
95    }
96    }
97    }
98   
99    /*
100    * (non-Javadoc)
101    *
102    * @see jalview.api.AlignCalcManagerI#isPending(jalview.api.AlignCalcWorkerI)
103    */
 
104  4075 toggle @Override
105    public boolean isPending(AlignCalcWorkerI workingClass)
106    {
107  4075 List<AlignCalcWorkerI> upd;
108  4075 synchronized (updating)
109    {
110  4075 upd = updating.get(workingClass.getClass());
111  4075 if (upd == null)
112    {
113  900 return false;
114    }
115  3175 synchronized (upd)
116    {
117  3175 if (upd.size() > 1)
118    {
119  128 return true;
120    }
121    }
122  3047 return false;
123    }
124    }
125   
 
126  3172 toggle @Override
127    public boolean notifyWorking(AlignCalcWorkerI worker)
128    {
129  3172 synchronized (inProgress)
130    {
131  3172 if (inProgress.contains(worker))
132    {
133  214 return false; // worker is already working, so ask caller to wait around
134    }
135    else
136    {
137  2958 inProgress.add(worker);
138    }
139    }
140  2958 return true;
141    }
142   
 
143  3176 toggle @Override
144    public void workerComplete(AlignCalcWorkerI worker)
145    {
146  3176 synchronized (inProgress)
147    {
148    // jalview.bin.Console.errPrintln("Worker " + worker + " marked as
149    // complete.");
150  3176 inProgress.remove(worker);
151  3176 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
152  3176 if (upd != null)
153    {
154  3176 synchronized (upd)
155    {
156  3176 upd.remove(worker);
157    }
158  3176 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  3106 toggle @Override
173    public boolean isDisabled(AlignCalcWorkerI worker)
174    {
175  3106 synchronized (blackList)
176    {
177  3106 return blackList.contains(worker.getClass());
178    }
179    }
180   
 
181  3100 toggle @Override
182    public void startWorker(AlignCalcWorkerI worker)
183    {
184  3100 if (!isDisabled(worker))
185    {
186  3100 Thread tw = new Thread(worker);
187  3100 tw.setName(worker.getClass().toString());
188  3100 tw.start();
189    }
190    }
191   
 
192  32 toggle @Override
193    public boolean isWorking(AlignCalcWorkerI worker)
194    {
195  32 synchronized (inProgress)
196    {// jalview.bin.Console.errPrintln("isWorking : worker "+(worker!=null ?
197    // worker.getClass():"null")+ " "+hashCode());
198  32 return worker != null && inProgress.contains(worker);
199    }
200    }
201   
 
202  2754 toggle @Override
203    public boolean isWorking()
204    {
205  2754 boolean working = false;
206  2754 synchronized (inProgress)
207    {
208    // jalview.bin.Console.errPrintln("isWorking "+hashCode());
209  2754 working |= inProgress.size() > 0;
210    }
211  2754 synchronized (updating)
212    {
213  2754 Collection<List<AlignCalcWorkerI>> workersLists = updating.values();
214  2754 synchronized (workersLists)
215    {
216  2754 for (List<AlignCalcWorkerI> workers : workersLists)
217    {
218  7861 if (workers != null)
219    {
220  7861 synchronized (workers)
221    {
222  7861 working |= workers.size() > 0;
223    }
224    }
225    }
226    }
227    }
228  2754 return working;
229    }
230   
 
231  1370 toggle @Override
232    public void registerWorker(AlignCalcWorkerI worker)
233    {
234  1370 synchronized (restartable)
235    {
236  1370 if (!restartable.contains(worker))
237    {
238  1370 restartable.add(worker);
239    }
240  1370 startWorker(worker);
241    }
242    }
243   
 
244  549 toggle @Override
245    public void restartWorkers()
246    {
247  549 synchronized (restartable)
248    {
249  549 for (AlignCalcWorkerI worker : restartable)
250    {
251  1730 startWorker(worker);
252    }
253    }
254    }
255   
 
256  9353 toggle @Override
257    public boolean workingInvolvedWith(
258    AlignmentAnnotation alignmentAnnotation)
259    {
260  9353 synchronized (inProgress)
261    {
262  9353 for (AlignCalcWorkerI worker : inProgress)
263    {
264  878 if (worker.involves(alignmentAnnotation))
265    {
266  316 return true;
267    }
268    }
269    }
270  9037 synchronized (updating)
271    {
272  9037 for (List<AlignCalcWorkerI> workers : updating.values())
273    {
274  26291 for (AlignCalcWorkerI worker : workers)
275    {
276  800 if (worker.involves(alignmentAnnotation))
277    {
278  70 return true;
279    }
280    }
281    }
282    }
283  8967 return false;
284    }
285   
 
286  64 toggle @Override
287    public void updateAnnotationFor(
288    Class<? extends AlignCalcWorkerI> workerClass)
289    {
290   
291  64 AlignCalcWorkerI[] workers;
292  64 synchronized (canUpdate)
293    {
294  64 workers = canUpdate.toArray(new AlignCalcWorkerI[0]);
295    }
296  64 for (AlignCalcWorkerI worker : workers)
297    {
298  184 if (workerClass.equals(worker.getClass()))
299    {
300  32 worker.updateAnnotation();
301    }
302    }
303    }
304   
 
305  2895 toggle @Override
306    public List<AlignCalcWorkerI> getRegisteredWorkersOfClass(
307    Class<? extends AlignCalcWorkerI> workerClass)
308    {
309  2895 List<AlignCalcWorkerI> workingClass = new ArrayList<AlignCalcWorkerI>();
310  2895 AlignCalcWorkerI[] workers;
311  2895 synchronized (canUpdate)
312    {
313  2895 workers = canUpdate.toArray(new AlignCalcWorkerI[0]);
314    }
315  2895 for (AlignCalcWorkerI worker : workers)
316    {
317  4570 if (workerClass.equals(worker.getClass()))
318    {
319  1525 workingClass.add(worker);
320    }
321    }
322  2895 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  2 toggle @Override
383    public void removeWorkerForAnnotation(AlignmentAnnotation ann)
384    {
385    /*
386    * first just find those to remove (to avoid
387    * ConcurrentModificationException)
388    */
389  2 List<AlignCalcWorkerI> toRemove = new ArrayList<AlignCalcWorkerI>();
390  2 for (AlignCalcWorkerI worker : restartable)
391    {
392  10 if (worker.involves(ann))
393    {
394  2 if (worker.isDeletable())
395    {
396  1 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  2 for (AlignCalcWorkerI worker : toRemove)
406    {
407  1 restartable.remove(worker);
408  1 blackList.remove(worker.getClass());
409  1 inProgress.remove(worker);
410  1 canUpdate.remove(worker);
411  1 synchronized (updating)
412    {
413  1 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
414  1 if (upd != null)
415    {
416  1 upd.remove(worker);
417    }
418    }
419    }
420    }
421    }