Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.workers

File AlignCalcManager.java

 

Coverage histogram

../../img/srcFileCovDistChart9.png
12% of files have more coverage

Code metrics

34
103
18
1
398
299
35
0.34
5.72
18
1.94

Classes

Class Line # Actions
AlignCalcManager 35 103 35 29
0.812903281.3%
 

Contributing tests

This file is covered by 142 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 jalview.api.AlignCalcManagerI;
24    import jalview.api.AlignCalcWorkerI;
25    import jalview.datamodel.AlignmentAnnotation;
26   
27    import java.util.ArrayList;
28    import java.util.Collections;
29    import java.util.HashSet;
30    import java.util.Hashtable;
31    import java.util.List;
32    import java.util.Map;
33    import java.util.Set;
34   
 
35    public class AlignCalcManager implements AlignCalcManagerI
36    {
37    /*
38    * list of registered workers
39    */
40    private volatile List<AlignCalcWorkerI> restartable;
41   
42    /*
43    * types of worker _not_ to run (for example, because they have
44    * previously thrown errors)
45    */
46    private volatile List<Class<? extends AlignCalcWorkerI>> blackList;
47   
48    /*
49    * global record of calculations in progress
50    */
51    private volatile List<AlignCalcWorkerI> inProgress;
52   
53    /*
54    * record of calculations pending or in progress in the current context
55    */
56    private volatile Map<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>> updating;
57   
58    /*
59    * workers that have run to completion so are candidates for visual-only
60    * update of their results
61    */
62    private HashSet<AlignCalcWorkerI> canUpdate;
63   
64    /**
65    * Constructor
66    */
 
67  244 toggle public AlignCalcManager()
68    {
69  244 restartable = Collections
70    .synchronizedList(new ArrayList<AlignCalcWorkerI>());
71  244 blackList = Collections.synchronizedList(
72    new ArrayList<Class<? extends AlignCalcWorkerI>>());
73  244 inProgress = Collections
74    .synchronizedList(new ArrayList<AlignCalcWorkerI>());
75  244 updating = Collections.synchronizedMap(
76    new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>());
77  244 canUpdate = new HashSet<AlignCalcWorkerI>();
78    }
79   
 
80  945 toggle @Override
81    public void notifyStart(AlignCalcWorkerI worker)
82    {
83  945 synchronized (updating)
84    {
85  945 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
86  945 if (upd == null)
87    {
88  371 updating.put(worker.getClass(), upd = Collections
89    .synchronizedList(new ArrayList<AlignCalcWorkerI>()));
90    }
91  945 synchronized (upd)
92    {
93  945 upd.add(worker);
94    }
95    }
96    }
97   
98    /*
99    * (non-Javadoc)
100    *
101    * @see jalview.api.AlignCalcManagerI#isPending(jalview.api.AlignCalcWorkerI)
102    */
 
103  930 toggle @Override
104    public boolean isPending(AlignCalcWorkerI workingClass)
105    {
106  930 List<AlignCalcWorkerI> upd;
107  930 synchronized (updating)
108    {
109  930 upd = updating.get(workingClass.getClass());
110  930 if (upd == null)
111    {
112  191 return false;
113    }
114  739 synchronized (upd)
115    {
116  739 if (upd.size() > 1)
117    {
118  2 return true;
119    }
120    }
121  737 return false;
122    }
123    }
124   
 
125  944 toggle @Override
126    public boolean notifyWorking(AlignCalcWorkerI worker)
127    {
128  944 synchronized (inProgress)
129    {
130  944 if (inProgress.contains(worker))
131    {
132  2 return false; // worker is already working, so ask caller to wait around
133    }
134    else
135    {
136  942 inProgress.add(worker);
137    }
138    }
139  942 return true;
140    }
141   
 
142  948 toggle @Override
143    public void workerComplete(AlignCalcWorkerI worker)
144    {
145  948 synchronized (inProgress)
146    {
147    // System.err.println("Worker " + worker + " marked as complete.");
148  948 inProgress.remove(worker);
149  948 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
150  948 if (upd != null)
151    {
152  948 synchronized (upd)
153    {
154  948 upd.remove(worker);
155    }
156  948 canUpdate.add(worker);
157    }
158    }
159    }
160   
 
161  0 toggle @Override
162    public void disableWorker(AlignCalcWorkerI worker)
163    {
164  0 synchronized (blackList)
165    {
166  0 blackList.add(worker.getClass());
167    }
168    }
169   
 
170  951 toggle @Override
171    public boolean isDisabled(AlignCalcWorkerI worker)
172    {
173  951 synchronized (blackList)
174    {
175  951 return blackList.contains(worker.getClass());
176    }
177    }
178   
 
179  945 toggle @Override
180    public void startWorker(AlignCalcWorkerI worker)
181    {
182  945 if (!isDisabled(worker))
183    {
184  945 Thread tw = new Thread(worker);
185  945 tw.setName(worker.getClass().toString());
186  945 tw.start();
187    }
188    }
189   
 
190  25 toggle @Override
191    public boolean isWorking(AlignCalcWorkerI worker)
192    {
193  25 synchronized (inProgress)
194    {// System.err.println("isWorking : worker "+(worker!=null ?
195    // worker.getClass():"null")+ " "+hashCode());
196  25 return worker != null && inProgress.contains(worker);
197    }
198    }
199   
 
200  618 toggle @Override
201    public boolean isWorking()
202    {
203  618 synchronized (inProgress)
204    {
205    // System.err.println("isWorking "+hashCode());
206  618 return inProgress.size() > 0;
207    }
208    }
209   
 
210  380 toggle @Override
211    public void registerWorker(AlignCalcWorkerI worker)
212    {
213  380 synchronized (restartable)
214    {
215  380 if (!restartable.contains(worker))
216    {
217  380 restartable.add(worker);
218    }
219  380 startWorker(worker);
220    }
221    }
222   
 
223  267 toggle @Override
224    public void restartWorkers()
225    {
226  267 synchronized (restartable)
227    {
228  267 for (AlignCalcWorkerI worker : restartable)
229    {
230  565 startWorker(worker);
231    }
232    }
233    }
234   
 
235  4028 toggle @Override
236    public boolean workingInvolvedWith(
237    AlignmentAnnotation alignmentAnnotation)
238    {
239  4028 synchronized (inProgress)
240    {
241  4028 for (AlignCalcWorkerI worker : inProgress)
242    {
243  164 if (worker.involves(alignmentAnnotation))
244    {
245  62 return true;
246    }
247    }
248    }
249  3966 synchronized (updating)
250    {
251  3966 for (List<AlignCalcWorkerI> workers : updating.values())
252    {
253  7930 for (AlignCalcWorkerI worker : workers)
254    {
255  106 if (worker.involves(alignmentAnnotation))
256    {
257  2 return true;
258    }
259    }
260    }
261    }
262  3964 return false;
263    }
264   
 
265  72 toggle @Override
266    public void updateAnnotationFor(
267    Class<? extends AlignCalcWorkerI> workerClass)
268    {
269   
270  72 AlignCalcWorkerI[] workers;
271  72 synchronized (canUpdate)
272    {
273  72 workers = canUpdate.toArray(new AlignCalcWorkerI[0]);
274    }
275  72 for (AlignCalcWorkerI worker : workers)
276    {
277  156 if (workerClass.equals(worker.getClass()))
278    {
279  25 worker.updateAnnotation();
280    }
281    }
282    }
283   
 
284  1847 toggle @Override
285    public List<AlignCalcWorkerI> getRegisteredWorkersOfClass(
286    Class<? extends AlignCalcWorkerI> workerClass)
287    {
288  1847 List<AlignCalcWorkerI> workingClass = new ArrayList<AlignCalcWorkerI>();
289  1847 synchronized (canUpdate)
290    {
291  1847 for (AlignCalcWorkerI worker : canUpdate)
292    {
293  2971 if (workerClass.equals(worker.getClass()))
294    {
295  566 workingClass.add(worker);
296    }
297    }
298    }
299  1847 return (workingClass.size() == 0) ? null : workingClass;
300    }
301   
 
302  0 toggle @Override
303    public void enableWorker(AlignCalcWorkerI worker)
304    {
305  0 synchronized (blackList)
306    {
307  0 blackList.remove(worker.getClass());
308    }
309    }
310   
 
311  0 toggle @Override
312    public void removeRegisteredWorkersOfClass(
313    Class<? extends AlignCalcWorkerI> typeToRemove)
314    {
315  0 List<AlignCalcWorkerI> removable = new ArrayList<AlignCalcWorkerI>();
316  0 Set<AlignCalcWorkerI> toremovannot = new HashSet<AlignCalcWorkerI>();
317  0 synchronized (restartable)
318    {
319  0 for (AlignCalcWorkerI worker : restartable)
320    {
321  0 if (typeToRemove.equals(worker.getClass()))
322    {
323  0 removable.add(worker);
324  0 toremovannot.add(worker);
325    }
326    }
327  0 restartable.removeAll(removable);
328    }
329  0 synchronized (canUpdate)
330    {
331  0 for (AlignCalcWorkerI worker : canUpdate)
332    {
333  0 if (typeToRemove.equals(worker.getClass()))
334    {
335  0 removable.add(worker);
336  0 toremovannot.add(worker);
337    }
338    }
339  0 canUpdate.removeAll(removable);
340    }
341    // TODO: finish testing this extension
342   
343    /*
344    * synchronized (inProgress) { // need to kill or mark as dead any running
345    * threads... (inProgress.get(typeToRemove)); }
346    *
347    * if (workers == null) { return; } for (AlignCalcWorkerI worker : workers)
348    * {
349    *
350    * if (isPending(worker)) { worker.abortAndDestroy(); startWorker(worker); }
351    * else { System.err.println("Pending exists for " + workerClass); } }
352    */
353    }
354   
355    /**
356    * Deletes the worker that update the given annotation, provided it is marked
357    * as deletable.
358    */
 
359  2 toggle @Override
360    public void removeWorkerForAnnotation(AlignmentAnnotation ann)
361    {
362    /*
363    * first just find those to remove (to avoid
364    * ConcurrentModificationException)
365    */
366  2 List<AlignCalcWorkerI> toRemove = new ArrayList<AlignCalcWorkerI>();
367  2 for (AlignCalcWorkerI worker : restartable)
368    {
369  8 if (worker.involves(ann))
370    {
371  2 if (worker.isDeletable())
372    {
373  1 toRemove.add(worker);
374    }
375    }
376    }
377   
378    /*
379    * remove all references to deleted workers so any references
380    * they hold to annotation data can be garbage collected
381    */
382  2 for (AlignCalcWorkerI worker : toRemove)
383    {
384  1 restartable.remove(worker);
385  1 blackList.remove(worker.getClass());
386  1 inProgress.remove(worker);
387  1 canUpdate.remove(worker);
388  1 synchronized (updating)
389    {
390  1 List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
391  1 if (upd != null)
392    {
393  1 upd.remove(worker);
394    }
395    }
396    }
397    }
398    }