// Copyright (C) 2011-2012 CRS4.
//
// This file is part of Seal.
//
// Seal is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// Seal is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with Seal. If not, see <http://www.gnu.org/licenses/>.
package it.crs4.seal.demux;
import it.crs4.seal.common.SequenceId;
import org.apache.hadoop.io.RawComparator;
import org.apache.hadoop.io.WritableComparator;
import org.apache.hadoop.io.WritableUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Sort sequence ids so that read 2 comes first (the index read),
* then read 1 and read 3.
*/
public class TwoOneThreeSortComparator implements RawComparator<SequenceId>
{
private static final Log LOG = LogFactory.getLog(TwoOneThreeSortComparator.class);
private static final int ByteSize = Byte.SIZE/8; // Byte.SIZE is the byte size in bits
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)
{
if (ByteSize != 1)
throw new RuntimeException("Byte size != 1 (it's " + ByteSize + "). Make sure this code still works!");
int sizeVint1 = WritableUtils.decodeVIntSize(b1[s1]);
int sizeVint2 = WritableUtils.decodeVIntSize(b2[s2]);
// compare by the location field (i.e. everything except the last byte.
int locationCmp = WritableComparator.compareBytes(
b1, s1+sizeVint1, l1-sizeVint1-ByteSize,
b2, s2+sizeVint2, l2-sizeVint2-ByteSize);
if (locationCmp == 0) // same location
{
// SequenceId writes the read number to the last byte of the record.
byte r1 = b1[s1+l1-1];
byte r2 = b2[s2+l2-1];
int retval;
if (r1 == r2)
retval = 0;
else if (r1 == 2)
retval = -1;
else if (r2 == 2)
retval = 1;
else
retval = (r1 < r2) ? -1 : 1;
return retval;
}
else
return locationCmp;
}
@Override
public int compare(SequenceId s1, SequenceId s2)
{
int locationCmp = s1.getLocation().compareTo(s2.getLocation());
if (locationCmp == 0) // same location
{
int r1 = s1.getRead();
int r2 = s2.getRead();
if (r1 == r2)
return 0;
else if (r1 == 2)
return -1;
else if (r2 == 2)
return 1;
else
return (r1 < r2) ? -1 : 1;
}
else
return locationCmp;
}
}