<commit_before>/*
 * Copyright (c) 2018 <NAME>
 * This code is licensed under MIT license (see LICENSE for details).
 */

#include <vcf2multialign/generate_graph_context.hh>


namespace lb = libbio;


namespace vcf2multialign {
	
	void generate_graph_context::open_files(
		char const *reference_fname,
		char const *variants_fname,
		char const *report_fname,
		char const *output_fname
	)
	{
		generate_context_base::open_files(reference_fname, variants_fname, report_fname);
		
		lb::open_file_for_writing(output_fname, m_output_stream, m_should_overwrite_files);
	}
	
	
	void generate_graph_context::swap_buffers_and_generate_graph()
	{
		// Make sure that m_graph_writer has finished with the previous set of buffers.
		dispatch_semaphore_wait(*m_output_sema, DISPATCH_TIME_FOREVER);

		// Swap buffers between haplotypes and m_buffers.
		// Also reset the range pointers in the new haplotype buffers.
		std::size_t i(0);
		for (auto &kv : m_haplotypes)
		{
			auto &haplotype_vec(kv.second);
			for (auto &haplotype : haplotype_vec)
			{
				auto &buffer(m_buffers[i]);
				
				using std::swap;
				swap(haplotype.output_sequence, buffer);
				
				haplotype.output_sequence.clear();
				++i;
			}
		}
		
		// Process in background thread.
		lb::dispatch_async_fn(*m_output_queue, [this](){
			m_graph_writer.process_segment(m_buffers);
		});
	}
	
	
	void generate_graph_context::graph_writer_did_process_segment(graph_writer &)
	{
		// Done with the previous segment, buffers are writable again.
		dispatch_semaphore_signal(*m_output_sema);
	}
	
	
	void generate_graph_context::variant_handler_did_process_overlap_stack(variant_handler &handler)
	{
		if (1 == handler.m_overlap_stack.size())
			swap_buffers_and_generate_graph();
	}
	
	
	void generate_graph_context::variant_handler_did_finish(variant_handler &handler)
	{
		// Handle the last segment.
		swap_buffers_and_generate_graph();
		
		// Finalize the graph.
		lb::dispatch_caller caller(&m_graph_writer);
		caller.template sync <&graph_writer::finish>(*m_output_queue);
		
		// Everything done.
		finish();
	}
	
	
	void generate_graph_context::prepare_haplotypes()
	{
		std::size_t count(0);
		auto const &sample_names(m_vcf_reader.sample_names());
		for (auto const &kv : sample_names)
		{
			auto const &sample_name(kv.first);
			auto const sample_no(kv.second);
			auto const current_ploidy(m_ploidy.find(sample_no)->second);
			
			auto const did_emplace(m_haplotypes.emplace(
				std::piecewise_construct,
				std::forward_as_tuple(sample_no),
				std::forward_as_tuple(current_ploidy)
			).second);
			lb::always_assert(did_emplace);<commit_msg>Add haplotype for the reference, count the haplotypes correctly<commit_after>/*
 * Copyright (c) 2018 <NAME>
 * This code is licensed under MIT license (see LICENSE for details).
 */

#include <vcf2multialign/generate_graph_context.hh>


namespace lb = libbio;


namespace vcf2multialign {
	
	void generate_graph_context::open_files(
		char const *reference_fname,
		char const *variants_fname,
		char const *report_fname,
		char const *output_fname
	)
	{
		generate_context_base::open_files(reference_fname, variants_fname, report_fname);
		
		lb::open_file_for_writing(output_fname, m_output_stream, m_should_overwrite_files);
	}
	
	
	void generate_graph_context::swap_buffers_and_generate_graph()
	{
		// Make sure that m_graph_writer has finished with the previous set of buffers.
		dispatch_semaphore_wait(*m_output_sema, DISPATCH_TIME_FOREVER);

		// Swap buffers between haplotypes and m_buffers.
		// Also reset the range pointers in the new haplotype buffers.
		std::size_t i(0);
		for (auto &kv : m_haplotypes)
		{
			auto &haplotype_vec(kv.second);
			for (auto &haplotype : haplotype_vec)
			{
				assert(i < m_buffers.size());
				auto &buffer(m_buffers[i]);
				
				using std::swap;
				swap(haplotype.output_sequence, buffer);
				
				haplotype.output_sequence.clear();
				++i;
			}
		}
		
		// Process in background thread.
		lb::dispatch_async_fn(*m_output_queue, [this](){
			m_graph_writer.process_segment(m_buffers);
		});
	}
	
	
	void generate_graph_context::graph_writer_did_process_segment(graph_writer &)
	{
		// Done with the previous segment, buffers are writable again.
		dispatch_semaphore_signal(*m_output_sema);
	}
	
	
	void generate_graph_context::variant_handler_did_process_overlap_stack(variant_handler &handler)
	{
		if (1 == handler.m_overlap_stack.size())
			swap_buffers_and_generate_graph();
	}
	
	
	void generate_graph_context::variant_handler_did_finish(variant_handler &handler)
	{
		// Handle the last segment.
		swap_buffers_and_generate_graph();
		
		// Finalize the graph.
		lb::dispatch_caller caller(&m_graph_writer);
		caller.template sync <&graph_writer::finish>(*m_output_queue);
		
		// Everything done.
		finish();
	}
	
	
	void generate_graph_context::prepare_haplotypes()
	{
		std::size_t count(0);
		auto const &sample_names(m_vcf_reader.sample_names());
		for (auto const &kv : sample_names)
		{
			auto const &sample_name(kv.first);
			auto const sample_no(kv.second);
			auto const current_ploidy(m_ploidy.find(sample_no)->second);
			
			auto const did_emplace(m_haplotypes.emplace(
				std::piecewise_construct,
				std::forward_as_tuple(sample_no),
				std::forward_as_tuple(current_ploidy)
			).second);
			lb::always_assert(did_emplace);
			count += current_ploidy;
		}
		
		{
			lb::always_assert(
				m_haplotypes.cend() == m_haplotypes.find(REF_SAMPLE_NUMBER),
				"REF_SAMPLE_NUMBER already in use"
			);
			
			auto const did_emplace(m_haplotypes.emplace(
				std::piecewise_construct,
				std::forward_as_tuple(REF_SAMPLE_NUMBER),
				std::forward_as_tuple(1)
			).second);
			lb::always_assert(did_emplace);
{'fraction_non_alphanumeric': 0.10370240393051412, 'fraction_numerical': 0.0033339182312686435, 'mean_word_length': 4.7114228456913825, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5805767', 'n_tokens_mistral': 2282, 'n_tokens_neox': 1937, 'n_words': 364}