private void FlushBufferedRecords(ReadsForPosition reads) { foreach (byte[] buffer in reads.Reads) { _bamWriter.WriteAlignment(buffer); } }
/// <summary> /// We're finished processing a read. Add it to the read buffer, and flush /// old nodes to disk. /// </summary> public void WriteRead(ref BamAlignment read, bool remapped) { if (remapped) { var info = new RemapInfo(read.Position, read.Position + (int)read.CigarData.GetReferenceSpan() - 1); _remappings[string.Format("{0}-{1}", read.Name, read.IsFirstMate() ? 1 : 2)] = info; } LinkedListNode <ReadsForPosition> node = _readBuffer.First; LinkedListNode <ReadsForPosition> nextNode; byte[] buffer = BamWriter.SerializeAlignment(ref read); while (node != null) { // Flush reads that are earlier than the earliest possible read we could see in the future (i.e. 2x max shift less than current read). // Reasoning: The realign shift could go in two directions. So, for example with max shift of 10, you could receive // and buffer reads in an order like this: 100, 100, 110, 115 (originally 110, shifted right to 115), // 100 (originally 110, shifted left to 100), 120 (originally 110, shifted right to 120), // 101 (originally 110, shifted left to 100), 121, 130, etc. If you had been flushing reads // using the max shift only as the threshold, upon hitting the 115 (fourth read) you would have // flushed the 100s (because 100 < 115 - 10), even though there still may be 100s coming through. // By the time we hit 121, we know that all of the reads we encounter in the future are going to be > 100 (at minimum, the 121 could represent a max-right-shift from 111 and other 111 reads could be max-left-shifted to 101). if (node.Value.Position < read.Position - (_maxRealignShift * 2)) { MinimumRealignmentStartPosition = Math.Max(MinimumRealignmentStartPosition, node.Value.Position); nextNode = node.Next; FlushBufferedRecords(node.Value); _readBuffer.Remove(node); node = nextNode; continue; } if (node.Value.Position == read.Position) { node.Value.Reads.Add(buffer); return; } if (node.Value.Position > read.Position) { ReadsForPosition reads = new ReadsForPosition(); reads.Position = read.Position; reads.Reads.Add(buffer); _readBuffer.AddBefore(node, reads); return; } node = node.Next; } ReadsForPosition readList = new ReadsForPosition(); readList.Position = read.Position; readList.Reads.Add(buffer); _readBuffer.AddLast(readList); }