Skip to content

Instantly share code, notes, and snippets.

@JervenBolleman
Created August 12, 2014 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JervenBolleman/36efc27e1e35b0db20a1 to your computer and use it in GitHub Desktop.
Save JervenBolleman/36efc27e1e35b0db20a1 to your computer and use it in GitHub Desktop.
GC 5 threaded GC count in java
package gc;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class GC5
{
static final int GC = 0;
static final int AT = 1;
static final int N = 2;
static final int SECOND_RIGHTMOST_BITS_SET = 2;
static final int FOURTH_RIGHMOST_BIT_SET = 8;
static final byte greaterthan = '>';
static final byte newline = '\n';
public static void main(String[] args)
throws java.io.IOException
{
final RandomAccessFile randomAccessFile = new RandomAccessFile("Homo_sapiens.GRCh37.67.dna_rm.chromosome.Y.fa",
"r");
final MappedByteBuffer channel = randomAccessFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0
, randomAccessFile.length());
new GC5(channel);
randomAccessFile.close();
}
private GC5(ByteBuffer channel) throws IOException
{
long start = System.currentTimeMillis();
int gc = 0;
int at = 0;
int n = 0;
final int threads = Runtime.getRuntime().availableProcessors();
Counter next = null;
List<Future<int[]>> futures = new ArrayList<>(threads);
ExecutorService exec = Executors.newFixedThreadPool(threads);
for (int thread = threads; thread > 0; thread--)
{
next = new Counter((channel.limit() / threads) * (thread - 1), next, channel);
futures.add(exec.submit(next));
}
while (!futures.isEmpty())
{
Iterator<Future<int[]>> iter = futures.iterator();
while (iter.hasNext())
{
try
{
final int[] is = iter.next().get();
if (is != null)
{
gc += is[GC];
at += is[AT];
n += is[N];
iter.remove();
}
} catch (InterruptedException | ExecutionException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
exec.shutdown();
System.out.printf("GC5 count %f\n", gc / (double) (gc + (at-n)));
System.out.printf("Elapsed %d ms\n", System.currentTimeMillis() - start);
}
private static class Counter
implements Callable<int[]>
{
private final int start;
private final ByteBuffer channel;
private final int finish;
public Counter(int starts, Counter next, ByteBuffer channel)
{
super();
this.channel = channel;
for (int i = starts; i < channel.limit(); i++)
{
if (channel.get(i) == newline)
{
starts = i + 1;//Don't need to retest the newline later
break;
}
}
this.start = starts;
if (next == null)
finish = channel.limit();
else
finish = next.start - 1;
}
@Override
public int[] call()
throws Exception
{
int gc = 0;
int at = 0;
int n = 0;
boolean header = true;
for (int i = start; i < finish; i++)
{
byte c = channel.get(i);
//While branches are bad these are not to bad as both are very rare so there will be few branch predictions.
if (c == greaterthan)
header = true;
else if (header && c == newline)
header = false; //Fasta header are always one line.
else if (!header)
{
int lgc = ((c & SECOND_RIGHTMOST_BITS_SET) >> 1) - ((c & FOURTH_RIGHMOST_BIT_SET) >>> 3);
gc += lgc;
at += (((~lgc) & 1));
n += ((c & FOURTH_RIGHMOST_BIT_SET) >>> 3);
}
}
return new int[] { gc, at, n};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment