예제 #1
0
    static void Grouper()
    {
        // Set up complements map
        map = new byte[256];
        for (byte b = 0; b < 255; b++)
        {
            map[b] = b;
        }
        map[(byte)'A'] = (byte)'T';
        map[(byte)'B'] = (byte)'V';
        map[(byte)'C'] = (byte)'G';
        map[(byte)'D'] = (byte)'H';
        map[(byte)'G'] = (byte)'C';
        map[(byte)'H'] = (byte)'D';
        map[(byte)'K'] = (byte)'M';
        map[(byte)'M'] = (byte)'K';
        map[(byte)'R'] = (byte)'Y';
        map[(byte)'T'] = (byte)'A';
        map[(byte)'V'] = (byte)'B';
        map[(byte)'Y'] = (byte)'R';
        map[(byte)'a'] = (byte)'T';
        map[(byte)'b'] = (byte)'V';
        map[(byte)'c'] = (byte)'G';
        map[(byte)'d'] = (byte)'H';
        map[(byte)'g'] = (byte)'C';
        map[(byte)'h'] = (byte)'D';
        map[(byte)'k'] = (byte)'M';
        map[(byte)'m'] = (byte)'K';
        map[(byte)'r'] = (byte)'Y';
        map[(byte)'t'] = (byte)'A';
        map[(byte)'v'] = (byte)'B';
        map[(byte)'y'] = (byte)'R';

        var  startHeader = 0;
        var  i           = 0;
        bool afterFirst  = false;
        var  data        = new List <byte[]>();

        byte[] bytes;
        while (tryTake(readQue, out bytes))
        {
            data.Add(bytes);
            while ((i = Array.IndexOf <byte>(bytes, GT, i + 1)) != -1)
            {
                var sequence = new RevCompSequence {
                    Pages         = data
                    , StartHeader = startHeader, EndExclusive = i
                };
                if (afterFirst)
                {
                    (sequence.ReverseThread = new Thread(() => Reverse(sequence))).Start();
                }
                else
                {
                    afterFirst = true;
                }
                writeQue.Add(sequence);
                startHeader = i;
                data        = new List <byte[]> {
                    bytes
                };
            }
        }
        i = Array.IndexOf <byte>(data[data.Count - 1], 0, 0);
        var lastSequence = new RevCompSequence {
            Pages         = data
            , StartHeader = startHeader, EndExclusive = i == -1 ? data[data.Count - 1].Length : i
        };

        Reverse(lastSequence);
        writeQue.Add(lastSequence);
        writeQue.CompleteAdding();
    }
예제 #2
0
    static void Reverse(RevCompSequence sequence)
    {
        var startPageId = 0;
        var startBytes  = sequence.Pages[0];
        var startIndex  = sequence.StartHeader;

        // Skip header line
        while ((startIndex = Array.IndexOf <byte>(startBytes, LF, startIndex)) == -1)
        {
            startBytes = sequence.Pages[++startPageId];
            startIndex = 0;
        }

        var endPageId = sequence.Pages.Count - 1;
        var endIndex  = sequence.EndExclusive - 1;

        if (endIndex == -1)
        {
            endIndex = sequence.Pages[--endPageId].Length - 1;
        }
        var endBytes = sequence.Pages[endPageId];

        // Swap in place across pages
        do
        {
            var startByte = startBytes[startIndex];
            if (startByte < SP)
            {
                if (++startIndex == startBytes.Length)
                {
                    startBytes = sequence.Pages[++startPageId];
                    startIndex = 0;
                }
                if (startIndex == endIndex && startPageId == endPageId)
                {
                    break;
                }
                startByte = startBytes[startIndex];
            }
            var endByte = endBytes[endIndex];
            if (endByte < SP)
            {
                if (--endIndex == -1)
                {
                    endBytes = sequence.Pages[--endPageId];
                    endIndex = endBytes.Length - 1;
                }
                if (startIndex == endIndex && startPageId == endPageId)
                {
                    break;
                }
                endByte = endBytes[endIndex];
            }

            startBytes[startIndex] = map[endByte];
            endBytes[endIndex]     = map[startByte];

            if (++startIndex == startBytes.Length)
            {
                startBytes = sequence.Pages[++startPageId];
                startIndex = 0;
            }
            if (--endIndex == -1)
            {
                endBytes = sequence.Pages[--endPageId];
                endIndex = endBytes.Length - 1;
            }
        } while (startPageId < endPageId || (startPageId == endPageId && startIndex < endIndex));
        if (startIndex == endIndex)
        {
            startBytes[startIndex] = map[startBytes[startIndex]];
        }
    }