jpayne@68
|
1 package kmer;
|
jpayne@68
|
2
|
jpayne@68
|
3 import java.util.concurrent.atomic.AtomicIntegerArray;
|
jpayne@68
|
4 import java.util.concurrent.atomic.AtomicLong;
|
jpayne@68
|
5 import java.util.concurrent.locks.Lock;
|
jpayne@68
|
6
|
jpayne@68
|
7 import dna.AminoAcid;
|
jpayne@68
|
8 import fileIO.ByteStreamWriter;
|
jpayne@68
|
9 import fileIO.TextStreamWriter;
|
jpayne@68
|
10 import shared.KillSwitch;
|
jpayne@68
|
11 import shared.Shared;
|
jpayne@68
|
12 import shared.Tools;
|
jpayne@68
|
13 import structures.ByteBuilder;
|
jpayne@68
|
14 import structures.SuperLongList;
|
jpayne@68
|
15
|
jpayne@68
|
16
|
jpayne@68
|
17 /**
|
jpayne@68
|
18 * @author Brian Bushnell
|
jpayne@68
|
19 * @date Oct 23, 2013
|
jpayne@68
|
20 *
|
jpayne@68
|
21 */
|
jpayne@68
|
22 public abstract class AbstractKmerTable {
|
jpayne@68
|
23
|
jpayne@68
|
24 /*--------------------------------------------------------------*/
|
jpayne@68
|
25 /*---------------- Abstract Methods ----------------*/
|
jpayne@68
|
26 /*--------------------------------------------------------------*/
|
jpayne@68
|
27
|
jpayne@68
|
28 // /** Returns count */
|
jpayne@68
|
29 // public final int increment(long kmer){return increment(kmer, 1);}
|
jpayne@68
|
30
|
jpayne@68
|
31 /** Returns count */
|
jpayne@68
|
32 public abstract int increment(final long kmer, final int incr);
|
jpayne@68
|
33
|
jpayne@68
|
34 // /** Returns number of entries created */
|
jpayne@68
|
35 // public final int incrementAndReturnNumCreated(final long kmer){return incrementAndReturnNumCreated(kmer, 1);}
|
jpayne@68
|
36
|
jpayne@68
|
37 /** Returns number of entries created. Incr must be positive. */
|
jpayne@68
|
38 public abstract int incrementAndReturnNumCreated(final long kmer, final int incr);
|
jpayne@68
|
39
|
jpayne@68
|
40 public abstract int set(long kmer, int value);
|
jpayne@68
|
41
|
jpayne@68
|
42 // public abstract int set(long kmer, int[] vals);
|
jpayne@68
|
43
|
jpayne@68
|
44 /** This is for IntList3 support with HashArrayHybridFast */
|
jpayne@68
|
45 public abstract int set(long kmer, int[] vals, int vlen);
|
jpayne@68
|
46
|
jpayne@68
|
47 /** Returns number of kmers added */
|
jpayne@68
|
48 public abstract int setIfNotPresent(long kmer, int value);
|
jpayne@68
|
49
|
jpayne@68
|
50 /**
|
jpayne@68
|
51 * Fetch the value associated with a kmer.
|
jpayne@68
|
52 * @param kmer
|
jpayne@68
|
53 * @return A value. -1 means the kmer was not present.
|
jpayne@68
|
54 */
|
jpayne@68
|
55 public abstract int getValue(long kmer);
|
jpayne@68
|
56
|
jpayne@68
|
57 /**
|
jpayne@68
|
58 * Fetch the values associated with a kmer.
|
jpayne@68
|
59 * @param kmer
|
jpayne@68
|
60 * @param singleton A blank array of length 1.
|
jpayne@68
|
61 * @return An array filled with values. Values of -1 are invalid.
|
jpayne@68
|
62 */
|
jpayne@68
|
63 public abstract int[] getValues(long kmer, int[] singleton);
|
jpayne@68
|
64
|
jpayne@68
|
65 public abstract boolean contains(long kmer);
|
jpayne@68
|
66
|
jpayne@68
|
67 public final boolean contains(long kmer, int v){
|
jpayne@68
|
68 assert(TESTMODE);
|
jpayne@68
|
69 int[] set=getValues(kmer, new int[] {-1});
|
jpayne@68
|
70 if(set==null){return false;}
|
jpayne@68
|
71 for(int s : set){
|
jpayne@68
|
72 if(s==-1){break;}
|
jpayne@68
|
73 if(s==v){return true;}
|
jpayne@68
|
74 }
|
jpayne@68
|
75 return false;
|
jpayne@68
|
76 }
|
jpayne@68
|
77
|
jpayne@68
|
78 public final boolean contains(long kmer, int[] vals){
|
jpayne@68
|
79 assert(TESTMODE);
|
jpayne@68
|
80 int[] set=getValues(kmer, new int[] {-1});
|
jpayne@68
|
81 if(set==null){return false;}
|
jpayne@68
|
82 boolean success=true;
|
jpayne@68
|
83 for(int v : vals){
|
jpayne@68
|
84 if(v==-1){break;}
|
jpayne@68
|
85 success=false;
|
jpayne@68
|
86 for(int s : set){
|
jpayne@68
|
87 if(s==v){
|
jpayne@68
|
88 success=true;
|
jpayne@68
|
89 break;
|
jpayne@68
|
90 }
|
jpayne@68
|
91 }
|
jpayne@68
|
92 if(!success){break;}
|
jpayne@68
|
93 }
|
jpayne@68
|
94 return success;
|
jpayne@68
|
95 }
|
jpayne@68
|
96
|
jpayne@68
|
97 public abstract void rebalance();
|
jpayne@68
|
98
|
jpayne@68
|
99 public abstract long size();
|
jpayne@68
|
100 public abstract int arrayLength();
|
jpayne@68
|
101 public abstract boolean canRebalance();
|
jpayne@68
|
102
|
jpayne@68
|
103 public abstract boolean dumpKmersAsText(TextStreamWriter tsw, int k, int mincount, int maxcount);
|
jpayne@68
|
104 public abstract boolean dumpKmersAsBytes(ByteStreamWriter bsw, int k, int mincount, int maxcount, AtomicLong remaining);
|
jpayne@68
|
105 public abstract boolean dumpKmersAsBytes_MT(final ByteStreamWriter bsw, final ByteBuilder bb, final int k, final int mincount, int maxcount, AtomicLong remaining);
|
jpayne@68
|
106
|
jpayne@68
|
107 public abstract void fillHistogram(long[] ca, int max);
|
jpayne@68
|
108 public abstract void fillHistogram(SuperLongList sll);
|
jpayne@68
|
109 public abstract void countGC(long[] gcCounts, int max);
|
jpayne@68
|
110
|
jpayne@68
|
111 public static final int gc(long kmer){
|
jpayne@68
|
112 int gc=0;
|
jpayne@68
|
113 while(kmer>0){
|
jpayne@68
|
114 long x=kmer&3;
|
jpayne@68
|
115 kmer>>>=2;
|
jpayne@68
|
116 if(x==1 || x==2){gc++;}
|
jpayne@68
|
117 }
|
jpayne@68
|
118 return gc;
|
jpayne@68
|
119 }
|
jpayne@68
|
120
|
jpayne@68
|
121 abstract Object get(long kmer);
|
jpayne@68
|
122 abstract void resize();
|
jpayne@68
|
123 abstract boolean canResize();
|
jpayne@68
|
124
|
jpayne@68
|
125
|
jpayne@68
|
126
|
jpayne@68
|
127 /**
|
jpayne@68
|
128 * Removes entries with a value of the limit or less.
|
jpayne@68
|
129 * Rehashes the remainder.
|
jpayne@68
|
130 * @return Number removed.
|
jpayne@68
|
131 */
|
jpayne@68
|
132 abstract long regenerate(int limit);
|
jpayne@68
|
133
|
jpayne@68
|
134 final void lock(){getLock().lock();}
|
jpayne@68
|
135 final void unlock(){getLock().unlock();}
|
jpayne@68
|
136 final boolean tryLock(){return getLock().tryLock();}
|
jpayne@68
|
137 Lock getLock(){
|
jpayne@68
|
138 throw new RuntimeException("Unimplemented.");
|
jpayne@68
|
139 }
|
jpayne@68
|
140
|
jpayne@68
|
141 /*--------------------------------------------------------------*/
|
jpayne@68
|
142 /*--------------- Allocation Methods ----------------*/
|
jpayne@68
|
143 /*--------------------------------------------------------------*/
|
jpayne@68
|
144
|
jpayne@68
|
145 final static AtomicIntegerArray allocAtomicInt(int len){
|
jpayne@68
|
146 return KillSwitch.allocAtomicInt(len);
|
jpayne@68
|
147 }
|
jpayne@68
|
148
|
jpayne@68
|
149 final static long[] allocLong1D(int len){
|
jpayne@68
|
150 return KillSwitch.allocLong1D(len);
|
jpayne@68
|
151 }
|
jpayne@68
|
152
|
jpayne@68
|
153 final static long[][] allocLong2D(int mult, int len){
|
jpayne@68
|
154 return KillSwitch.allocLong2D(mult, len);
|
jpayne@68
|
155 }
|
jpayne@68
|
156
|
jpayne@68
|
157 final static int[] allocInt1D(int len){
|
jpayne@68
|
158 return KillSwitch.allocInt1D(len);
|
jpayne@68
|
159 }
|
jpayne@68
|
160
|
jpayne@68
|
161 final static int[][] allocInt2D(int len){
|
jpayne@68
|
162 return KillSwitch.allocInt2D(len);
|
jpayne@68
|
163 }
|
jpayne@68
|
164
|
jpayne@68
|
165 final static KmerNode[] allocKmerNodeArray(int len){
|
jpayne@68
|
166 KmerNode[] ret=null;
|
jpayne@68
|
167 try {
|
jpayne@68
|
168 ret=new KmerNode[len];
|
jpayne@68
|
169 } catch (OutOfMemoryError e) {
|
jpayne@68
|
170 synchronized(killMessage){
|
jpayne@68
|
171 e.printStackTrace();
|
jpayne@68
|
172 System.err.println(killMessage);
|
jpayne@68
|
173 // Shared.printMemory();
|
jpayne@68
|
174 KillSwitch.killSilent();
|
jpayne@68
|
175 }
|
jpayne@68
|
176 }
|
jpayne@68
|
177 return ret;
|
jpayne@68
|
178 }
|
jpayne@68
|
179
|
jpayne@68
|
180 /*--------------------------------------------------------------*/
|
jpayne@68
|
181 /*--------------- Ownership Methods ----------------*/
|
jpayne@68
|
182 /*--------------------------------------------------------------*/
|
jpayne@68
|
183
|
jpayne@68
|
184 /** Set the thread owning this kmer. Return the new owner.
|
jpayne@68
|
185 * Will only change the owner if newOwner is greater than current owner. */
|
jpayne@68
|
186 public abstract int setOwner(long kmer, int newOwner);
|
jpayne@68
|
187
|
jpayne@68
|
188 /** Reset owner to -1 if this is the current owner. */
|
jpayne@68
|
189 public abstract boolean clearOwner(long kmer, int owner);
|
jpayne@68
|
190
|
jpayne@68
|
191 /** Return the thread ID owning this kmer, or -1. */
|
jpayne@68
|
192 public abstract int getOwner(long kmer);
|
jpayne@68
|
193
|
jpayne@68
|
194 /** Create data structures needed for ownership representation */
|
jpayne@68
|
195 public abstract void initializeOwnership();
|
jpayne@68
|
196
|
jpayne@68
|
197 /** Eliminate ownership data structures or set them to -1. */
|
jpayne@68
|
198 public abstract void clearOwnership();
|
jpayne@68
|
199
|
jpayne@68
|
200 /*--------------------------------------------------------------*/
|
jpayne@68
|
201 /*---------------- Methods ----------------*/
|
jpayne@68
|
202 /*--------------------------------------------------------------*/
|
jpayne@68
|
203
|
jpayne@68
|
204 public static final StringBuilder toText(long kmer, int k){
|
jpayne@68
|
205 byte[] lookup=(Shared.AMINO_IN ? AminoAcid.numberToAcid : AminoAcid.numberToBase);
|
jpayne@68
|
206 int bits=(Shared.AMINO_IN ? 5 : 2);
|
jpayne@68
|
207 int mask=(Shared.AMINO_IN ? 31 : 3);
|
jpayne@68
|
208 StringBuilder sb=new StringBuilder(k);
|
jpayne@68
|
209 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
210 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
211 sb.append((char)lookup[x]);
|
jpayne@68
|
212 }
|
jpayne@68
|
213 return sb;
|
jpayne@68
|
214 }
|
jpayne@68
|
215
|
jpayne@68
|
216 static final StringBuilder toText(long kmer, int count, int k){
|
jpayne@68
|
217 StringBuilder sb=new StringBuilder(k+10);
|
jpayne@68
|
218 return toText(kmer, count, k, sb);
|
jpayne@68
|
219 }
|
jpayne@68
|
220
|
jpayne@68
|
221 static final ByteBuilder toBytes(long kmer, int count, int k){
|
jpayne@68
|
222 ByteBuilder bb=new ByteBuilder(k+10);
|
jpayne@68
|
223 return toBytes(kmer, count, k, bb);
|
jpayne@68
|
224 }
|
jpayne@68
|
225
|
jpayne@68
|
226 static final StringBuilder toText(long kmer, int[] values, int k){
|
jpayne@68
|
227 StringBuilder sb=new StringBuilder(k+10);
|
jpayne@68
|
228 return toText(kmer, values, k, sb);
|
jpayne@68
|
229 }
|
jpayne@68
|
230
|
jpayne@68
|
231 static final ByteBuilder toBytes(long kmer, int[] values, int k){
|
jpayne@68
|
232 ByteBuilder bb=new ByteBuilder(k+10);
|
jpayne@68
|
233 return toBytes(kmer, values, k, bb);
|
jpayne@68
|
234 }
|
jpayne@68
|
235
|
jpayne@68
|
236 static final StringBuilder toText(long kmer, int count, int k, StringBuilder sb){
|
jpayne@68
|
237 byte[] lookup=(Shared.AMINO_IN ? AminoAcid.numberToAcid : AminoAcid.numberToBase);
|
jpayne@68
|
238 int bits=(Shared.AMINO_IN ? 5 : 2);
|
jpayne@68
|
239 int mask=(Shared.AMINO_IN ? 31 : 3);
|
jpayne@68
|
240 if(FASTA_DUMP){
|
jpayne@68
|
241 sb.append('>');
|
jpayne@68
|
242 sb.append(count);
|
jpayne@68
|
243 sb.append('\n');
|
jpayne@68
|
244 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
245 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
246 sb.append((char)lookup[x]);
|
jpayne@68
|
247 }
|
jpayne@68
|
248 }else{
|
jpayne@68
|
249 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
250 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
251 sb.append((char)lookup[x]);
|
jpayne@68
|
252 }
|
jpayne@68
|
253 sb.append('\t');
|
jpayne@68
|
254 sb.append(count);
|
jpayne@68
|
255 }
|
jpayne@68
|
256 return sb;
|
jpayne@68
|
257 }
|
jpayne@68
|
258
|
jpayne@68
|
259 static final StringBuilder toText(long kmer, int[] values, int k, StringBuilder sb){
|
jpayne@68
|
260 byte[] lookup=(Shared.AMINO_IN ? AminoAcid.numberToAcid : AminoAcid.numberToBase);
|
jpayne@68
|
261 int bits=(Shared.AMINO_IN ? 5 : 2);
|
jpayne@68
|
262 int mask=(Shared.AMINO_IN ? 31 : 3);
|
jpayne@68
|
263 if(FASTA_DUMP){
|
jpayne@68
|
264 sb.append('>');
|
jpayne@68
|
265 for(int i=0; i<values.length; i++){
|
jpayne@68
|
266 int x=values[i];
|
jpayne@68
|
267 if(x==-1){break;}
|
jpayne@68
|
268 if(i>0){sb.append(',');}
|
jpayne@68
|
269 sb.append(x);
|
jpayne@68
|
270 }
|
jpayne@68
|
271 sb.append('\n');
|
jpayne@68
|
272 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
273 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
274 sb.append((char)lookup[x]);
|
jpayne@68
|
275 }
|
jpayne@68
|
276 }else{
|
jpayne@68
|
277 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
278 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
279 sb.append((char)lookup[x]);
|
jpayne@68
|
280 }
|
jpayne@68
|
281 sb.append('\t');
|
jpayne@68
|
282 for(int i=0; i<values.length; i++){
|
jpayne@68
|
283 int x=values[i];
|
jpayne@68
|
284 if(x==-1){break;}
|
jpayne@68
|
285 if(i>0){sb.append(',');}
|
jpayne@68
|
286 sb.append(x);
|
jpayne@68
|
287 }
|
jpayne@68
|
288 }
|
jpayne@68
|
289 return sb;
|
jpayne@68
|
290 }
|
jpayne@68
|
291
|
jpayne@68
|
292 public static final ByteBuilder toBytes(long kmer, long count, int k, ByteBuilder bb){
|
jpayne@68
|
293 byte[] lookup=(Shared.AMINO_IN ? AminoAcid.numberToAcid : AminoAcid.numberToBase);
|
jpayne@68
|
294 int bits=(Shared.AMINO_IN ? 5 : 2);
|
jpayne@68
|
295 int mask=(Shared.AMINO_IN ? 31 : 3);
|
jpayne@68
|
296 if(FASTA_DUMP){
|
jpayne@68
|
297 bb.append('>');
|
jpayne@68
|
298 bb.append(count);
|
jpayne@68
|
299 bb.nl();
|
jpayne@68
|
300 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
301 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
302 bb.append(lookup[x]);
|
jpayne@68
|
303 }
|
jpayne@68
|
304 // assert(false) : kmer+"->\n"+bb+"\n"+AminoAcid.kmerToStringAA(kmer, k);
|
jpayne@68
|
305 }else if(NUMERIC_DUMP){
|
jpayne@68
|
306 bb.append(Long.toHexString(kmer));
|
jpayne@68
|
307 bb.tab();
|
jpayne@68
|
308 bb.append(count);
|
jpayne@68
|
309 }else{
|
jpayne@68
|
310 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
311 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
312 bb.append(lookup[x]);
|
jpayne@68
|
313 }
|
jpayne@68
|
314 bb.tab();
|
jpayne@68
|
315 bb.append(count);
|
jpayne@68
|
316 }
|
jpayne@68
|
317 return bb;
|
jpayne@68
|
318 }
|
jpayne@68
|
319
|
jpayne@68
|
320 public static final ByteBuilder toBytes(long kmer, int[] values, int k, ByteBuilder bb){
|
jpayne@68
|
321 byte[] lookup=(Shared.AMINO_IN ? AminoAcid.numberToAcid : AminoAcid.numberToBase);
|
jpayne@68
|
322 int bits=(Shared.AMINO_IN ? 5 : 2);
|
jpayne@68
|
323 int mask=(Shared.AMINO_IN ? 31 : 3);
|
jpayne@68
|
324 if(FASTA_DUMP){
|
jpayne@68
|
325 bb.append('>');
|
jpayne@68
|
326 for(int i=0; i<values.length; i++){
|
jpayne@68
|
327 int x=values[i];
|
jpayne@68
|
328 if(x==-1){break;}
|
jpayne@68
|
329 if(i>0){bb.append(',');}
|
jpayne@68
|
330 bb.append(x);
|
jpayne@68
|
331 }
|
jpayne@68
|
332 bb.nl();
|
jpayne@68
|
333 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
334 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
335 bb.append(lookup[x]);
|
jpayne@68
|
336 }
|
jpayne@68
|
337 }else if(NUMERIC_DUMP){
|
jpayne@68
|
338 bb.append(Long.toHexString(kmer));
|
jpayne@68
|
339 bb.tab();
|
jpayne@68
|
340 for(int i=0; i<values.length; i++){
|
jpayne@68
|
341 int x=values[i];
|
jpayne@68
|
342 if(x==-1){break;}
|
jpayne@68
|
343 if(i>0){bb.append(',');}
|
jpayne@68
|
344 bb.append(x);
|
jpayne@68
|
345 }
|
jpayne@68
|
346 }else{
|
jpayne@68
|
347 for(int i=k-1; i>=0; i--){
|
jpayne@68
|
348 int x=(int)((kmer>>(bits*i))&mask);
|
jpayne@68
|
349 bb.append(lookup[x]);
|
jpayne@68
|
350 }
|
jpayne@68
|
351 bb.tab();
|
jpayne@68
|
352 for(int i=0; i<values.length; i++){
|
jpayne@68
|
353 int x=values[i];
|
jpayne@68
|
354 if(x==-1){break;}
|
jpayne@68
|
355 if(i>0){bb.append(',');}
|
jpayne@68
|
356 bb.append(x);
|
jpayne@68
|
357 }
|
jpayne@68
|
358 }
|
jpayne@68
|
359 return bb;
|
jpayne@68
|
360 }
|
jpayne@68
|
361
|
jpayne@68
|
362 // static void appendKmerText(long kmer, int count, int k, StringBuilder sb){
|
jpayne@68
|
363 // sb.setLength(0);
|
jpayne@68
|
364 // toText(kmer, count, k, sb);
|
jpayne@68
|
365 // sb.append('\n');
|
jpayne@68
|
366 // }
|
jpayne@68
|
367
|
jpayne@68
|
368 static void appendKmerText(long kmer, int count, int k, ByteBuilder bb){
|
jpayne@68
|
369 bb.setLength(0);
|
jpayne@68
|
370 toBytes(kmer, count, k, bb);
|
jpayne@68
|
371 bb.nl();
|
jpayne@68
|
372 }
|
jpayne@68
|
373
|
jpayne@68
|
374
|
jpayne@68
|
375 /** For buffered tables. */
|
jpayne@68
|
376 long flush(){
|
jpayne@68
|
377 throw new RuntimeException("Unsupported.");
|
jpayne@68
|
378 }
|
jpayne@68
|
379
|
jpayne@68
|
380 /**
|
jpayne@68
|
381 * This allocates the data structures in multiple threads. Unfortunately, it does not lead to any speedup, at least for ARRAY type.
|
jpayne@68
|
382 * @param ways
|
jpayne@68
|
383 * @param tableType
|
jpayne@68
|
384 * @param schedule
|
jpayne@68
|
385 * @param mask
|
jpayne@68
|
386 * @return The preallocated table
|
jpayne@68
|
387 */
|
jpayne@68
|
388 public static final AbstractKmerTable[] preallocate(int ways, int tableType, int[] schedule, long mask){
|
jpayne@68
|
389
|
jpayne@68
|
390 final AbstractKmerTable[] tables=new AbstractKmerTable[ways];
|
jpayne@68
|
391
|
jpayne@68
|
392 {
|
jpayne@68
|
393 shared.Timer tm=new shared.Timer();
|
jpayne@68
|
394 final int t=Tools.max(1, Tools.min(Shared.threads(), 2, ways)); //More than 2 still improves allocation time, but only slightly; ~25% faster at t=4.
|
jpayne@68
|
395 final AllocThread[] allocators=new AllocThread[t];
|
jpayne@68
|
396 for(int i=0; i<t; i++){
|
jpayne@68
|
397 allocators[i]=new AllocThread(tableType, schedule, i, t, mask, tables);
|
jpayne@68
|
398 }
|
jpayne@68
|
399 for(AllocThread at : allocators){at.start();}
|
jpayne@68
|
400 for(AllocThread at : allocators){
|
jpayne@68
|
401 while(at.getState()!=Thread.State.TERMINATED){
|
jpayne@68
|
402 try {
|
jpayne@68
|
403 at.join();
|
jpayne@68
|
404 } catch (InterruptedException e) {
|
jpayne@68
|
405 // TODO Auto-generated catch block
|
jpayne@68
|
406 e.printStackTrace();
|
jpayne@68
|
407 }
|
jpayne@68
|
408 }
|
jpayne@68
|
409 }
|
jpayne@68
|
410 tm.stop();
|
jpayne@68
|
411 if(AbstractKmerTableSet.DISPLAY_PROGRESS){System.err.println(tm);}
|
jpayne@68
|
412 }
|
jpayne@68
|
413
|
jpayne@68
|
414 synchronized(tables){
|
jpayne@68
|
415 for(int i=0; i<tables.length; i++){
|
jpayne@68
|
416 final AbstractKmerTable akt=tables[i];
|
jpayne@68
|
417 if(akt==null){
|
jpayne@68
|
418 throw new RuntimeException("KmerTable allocation failed, probably due to lack of RAM: "+i+", "+tables.length);
|
jpayne@68
|
419 }
|
jpayne@68
|
420 }
|
jpayne@68
|
421 }
|
jpayne@68
|
422
|
jpayne@68
|
423 return tables;
|
jpayne@68
|
424 }
|
jpayne@68
|
425
|
jpayne@68
|
426 /*--------------------------------------------------------------*/
|
jpayne@68
|
427 /*---------------- Nested Classes ----------------*/
|
jpayne@68
|
428 /*--------------------------------------------------------------*/
|
jpayne@68
|
429
|
jpayne@68
|
430 private static class AllocThread extends Thread{
|
jpayne@68
|
431
|
jpayne@68
|
432 AllocThread(int type_, int[] schedule_, int mod_, int div_,
|
jpayne@68
|
433 long mask_, AbstractKmerTable[] tables_){
|
jpayne@68
|
434 type=type_;
|
jpayne@68
|
435 schedule=schedule_;
|
jpayne@68
|
436 size=schedule[0];
|
jpayne@68
|
437 mod=mod_;
|
jpayne@68
|
438 div=div_;
|
jpayne@68
|
439 mask=mask_;
|
jpayne@68
|
440 growable=schedule.length>1;
|
jpayne@68
|
441 tables=tables_;
|
jpayne@68
|
442 }
|
jpayne@68
|
443
|
jpayne@68
|
444 @Override
|
jpayne@68
|
445 public void run(){
|
jpayne@68
|
446 //Initialize tables
|
jpayne@68
|
447 long sum=0;
|
jpayne@68
|
448
|
jpayne@68
|
449 // Shared.printMemory();}
|
jpayne@68
|
450 for(int i=mod; i<tables.length; i+=div){
|
jpayne@68
|
451 // System.err.println("T"+i+" allocating "+i);
|
jpayne@68
|
452 final AbstractKmerTable akt;
|
jpayne@68
|
453 if(type==FOREST1D){
|
jpayne@68
|
454 akt=new HashForest(size, growable, false);
|
jpayne@68
|
455 }else if(type==TABLE){
|
jpayne@68
|
456 akt=new KmerTable(size, growable);
|
jpayne@68
|
457 }else if(type==ARRAY1D){
|
jpayne@68
|
458 akt=new HashArray1D(schedule, mask);
|
jpayne@68
|
459 // long len=((HashArray1D)akt).arrayLength();
|
jpayne@68
|
460 // long mem=((HashArray1D)akt).calcMem();
|
jpayne@68
|
461 // sum+=mem;
|
jpayne@68
|
462 // akt=new HashArray1D(size, -1, mask, growable);//TODO: Set maxSize
|
jpayne@68
|
463 }else if(type==NODE1D){
|
jpayne@68
|
464 throw new RuntimeException("Must use forest, table, or array data structure. Type="+type);
|
jpayne@68
|
465 // akt=new KmerNode2(-1, 0);
|
jpayne@68
|
466 }else if(type==FOREST2D){
|
jpayne@68
|
467 akt=new HashForest(size, growable, true);
|
jpayne@68
|
468 }else if(type==TABLE2D){
|
jpayne@68
|
469 throw new RuntimeException("Must use forest, table, or array data structure. Type="+type);
|
jpayne@68
|
470 }else if(type==ARRAY2D){
|
jpayne@68
|
471 akt=new HashArray2D(schedule, mask);
|
jpayne@68
|
472 // akt=new HashArray2D(size, -1, mask, growable);//TODO: Set maxSize
|
jpayne@68
|
473 }else if(type==NODE2D){
|
jpayne@68
|
474 throw new RuntimeException("Must use forest, table, or array data structure. Type="+type);
|
jpayne@68
|
475 // akt=new KmerNode(-1, 0);
|
jpayne@68
|
476 }else if(type==ARRAYH){
|
jpayne@68
|
477 akt=new HashArrayHybrid(schedule, mask);
|
jpayne@68
|
478 // akt=new HashArrayHybrid(size, -1, mask, growable);//TODO: Set maxSize
|
jpayne@68
|
479 }else if(type==ARRAYHF){
|
jpayne@68
|
480 akt=new HashArrayHybridFast(schedule, mask);
|
jpayne@68
|
481 // akt=new HashArrayHybrid(size, -1, mask, growable);//TODO: Set maxSize
|
jpayne@68
|
482 }else{
|
jpayne@68
|
483 throw new RuntimeException("Must use forest, table, or array data structure. Type="+type);
|
jpayne@68
|
484 }
|
jpayne@68
|
485 synchronized(tables){
|
jpayne@68
|
486 tables[i]=akt;
|
jpayne@68
|
487 }
|
jpayne@68
|
488 // System.err.println("T"+i+" allocated "+i);
|
jpayne@68
|
489
|
jpayne@68
|
490 // if(i%100==0){
|
jpayne@68
|
491 // System.err.println("Allocated "+(sum/1000000)+"MB");
|
jpayne@68
|
492 // Shared.printMemory();
|
jpayne@68
|
493 // }
|
jpayne@68
|
494 }
|
jpayne@68
|
495 // Shared.printMemory();
|
jpayne@68
|
496 // assert(false) : ("Allocated "+(sum/1000000)+"MB");
|
jpayne@68
|
497 }
|
jpayne@68
|
498
|
jpayne@68
|
499 private final int type;
|
jpayne@68
|
500 private final int[] schedule;
|
jpayne@68
|
501 private final int size;
|
jpayne@68
|
502 private final int mod;
|
jpayne@68
|
503 private final int div;
|
jpayne@68
|
504 private final long mask;
|
jpayne@68
|
505 private final boolean growable;
|
jpayne@68
|
506 final AbstractKmerTable[] tables;
|
jpayne@68
|
507
|
jpayne@68
|
508 }
|
jpayne@68
|
509
|
jpayne@68
|
510 public Walker walk() {
|
jpayne@68
|
511 throw new RuntimeException("Unimplemented");
|
jpayne@68
|
512 }
|
jpayne@68
|
513
|
jpayne@68
|
514 /*--------------------------------------------------------------*/
|
jpayne@68
|
515 /*---------------- Fields ----------------*/
|
jpayne@68
|
516 /*--------------------------------------------------------------*/
|
jpayne@68
|
517
|
jpayne@68
|
518 public static boolean FASTA_DUMP=true;
|
jpayne@68
|
519 public static boolean NUMERIC_DUMP=false;
|
jpayne@68
|
520 public static boolean TWO_PASS_RESIZE=false;
|
jpayne@68
|
521
|
jpayne@68
|
522 public static final boolean verbose=false;
|
jpayne@68
|
523 public static final boolean TESTMODE=false; //123 SLOW!
|
jpayne@68
|
524
|
jpayne@68
|
525 public static final int UNKNOWN=0, ARRAY1D=1, FOREST1D=2, TABLE=3, NODE1D=4, ARRAY2D=5, FOREST2D=6, TABLE2D=7, NODE2D=8, ARRAYH=9, ARRAYHF=10;
|
jpayne@68
|
526
|
jpayne@68
|
527 public static final int NOT_PRESENT=-1, HASH_COLLISION=-2;
|
jpayne@68
|
528 public static final int NO_OWNER=-1;
|
jpayne@68
|
529
|
jpayne@68
|
530 private static final String killMessage=new String("\nThis program ran out of memory. Try increasing the -Xmx flag and setting prealloc.");
|
jpayne@68
|
531
|
jpayne@68
|
532 }
|