jpayne@68
|
1 package kmer;
|
jpayne@68
|
2
|
jpayne@68
|
3 import java.util.concurrent.atomic.AtomicInteger;
|
jpayne@68
|
4
|
jpayne@68
|
5 import shared.Shared;
|
jpayne@68
|
6 import shared.Tools;
|
jpayne@68
|
7 import structures.SuperLongList;
|
jpayne@68
|
8
|
jpayne@68
|
9 public final class HistogramMaker {
|
jpayne@68
|
10
|
jpayne@68
|
11
|
jpayne@68
|
12 public static long[] fillHistogram(final AbstractKmerTable[] tables, final int histMax) {
|
jpayne@68
|
13 if(Shared.threads()>2){
|
jpayne@68
|
14 return fillHistogram_MT(tables, histMax);
|
jpayne@68
|
15 }else{
|
jpayne@68
|
16 return fillHistogram_ST(tables, histMax);
|
jpayne@68
|
17 }
|
jpayne@68
|
18 }
|
jpayne@68
|
19
|
jpayne@68
|
20 private static long[] fillHistogram_ST(final AbstractKmerTable[] tables, final int histMax) {
|
jpayne@68
|
21 long[] ca=new long[histMax+1];
|
jpayne@68
|
22 for(AbstractKmerTable set : tables){
|
jpayne@68
|
23 set.fillHistogram(ca, histMax);
|
jpayne@68
|
24 }
|
jpayne@68
|
25 return ca;
|
jpayne@68
|
26 }
|
jpayne@68
|
27
|
jpayne@68
|
28 private static long[] fillHistogram_MT(final AbstractKmerTable[] tables, final int histMax) {
|
jpayne@68
|
29 boolean errorState=false;
|
jpayne@68
|
30 int threads=Shared.threads();
|
jpayne@68
|
31 threads=Tools.min((threads>20 ? threads/2 : threads), (tables.length+1)/2, 32);
|
jpayne@68
|
32 if(threads<2){return fillHistogram_ST(tables, histMax);}
|
jpayne@68
|
33
|
jpayne@68
|
34 final FillThread[] array=new FillThread[threads];
|
jpayne@68
|
35 final AtomicInteger next=new AtomicInteger(0);
|
jpayne@68
|
36 for(int i=0; i<threads; i++){array[i]=new FillThread(tables, histMax, next);}
|
jpayne@68
|
37 for(int i=0; i<threads; i++){array[i].start();}
|
jpayne@68
|
38
|
jpayne@68
|
39 //Wait for completion of all threads
|
jpayne@68
|
40 final long[] ca=new long[histMax+1];
|
jpayne@68
|
41 boolean success=true;
|
jpayne@68
|
42 for(FillThread pt : array){
|
jpayne@68
|
43
|
jpayne@68
|
44 //Wait until this thread has terminated
|
jpayne@68
|
45 while(pt.getState()!=Thread.State.TERMINATED){
|
jpayne@68
|
46 try {
|
jpayne@68
|
47 //Attempt a join operation
|
jpayne@68
|
48 pt.join();
|
jpayne@68
|
49 } catch (InterruptedException e) {
|
jpayne@68
|
50 //Potentially handle this, if it is expected to occur
|
jpayne@68
|
51 e.printStackTrace();
|
jpayne@68
|
52 }
|
jpayne@68
|
53 }
|
jpayne@68
|
54
|
jpayne@68
|
55 //Accumulate per-thread statistics
|
jpayne@68
|
56
|
jpayne@68
|
57 pt.sll.addTo(ca);
|
jpayne@68
|
58 pt.sll=null;
|
jpayne@68
|
59 }
|
jpayne@68
|
60
|
jpayne@68
|
61 //Track whether any threads failed
|
jpayne@68
|
62 if(!success){errorState=true;}
|
jpayne@68
|
63
|
jpayne@68
|
64 return ca;
|
jpayne@68
|
65 }
|
jpayne@68
|
66
|
jpayne@68
|
67 private static class FillThread extends Thread{
|
jpayne@68
|
68
|
jpayne@68
|
69 FillThread(final AbstractKmerTable[] tables_, int histMax_, AtomicInteger next_){
|
jpayne@68
|
70 tables=tables_;
|
jpayne@68
|
71 next=next_;
|
jpayne@68
|
72 sll=new SuperLongList(Tools.mid(5000, histMax_, 100000));
|
jpayne@68
|
73 }
|
jpayne@68
|
74
|
jpayne@68
|
75 @Override
|
jpayne@68
|
76 public void run(){
|
jpayne@68
|
77 for(int tnum=next.getAndIncrement(); tnum<tables.length; tnum=next.getAndIncrement()){
|
jpayne@68
|
78 tables[tnum].fillHistogram(sll);
|
jpayne@68
|
79 }
|
jpayne@68
|
80 }
|
jpayne@68
|
81
|
jpayne@68
|
82 final AbstractKmerTable[] tables;
|
jpayne@68
|
83 final AtomicInteger next;
|
jpayne@68
|
84 SuperLongList sll;
|
jpayne@68
|
85
|
jpayne@68
|
86 }
|
jpayne@68
|
87
|
jpayne@68
|
88 }
|