static bool read_touches_graph(const read_t *r, const dBGraph *db_graph, LoadingStats *stats) { bool found = false; BinaryKmer bkmer; Nucleotide nuc; dBNode node; const size_t kmer_size = db_graph->kmer_size; size_t i, num_contigs = 0, num_kmers_loaded = 0; size_t search_pos = 0, start, end = 0, contig_len; if(r->seq.end >= kmer_size) { while((start = seq_contig_start(r, search_pos, kmer_size, 0,0)) < r->seq.end && !found) { end = seq_contig_end(r, start, kmer_size, 0, 0, &search_pos); contig_len = end - start; __sync_fetch_and_add((volatile size_t*)&stats->total_bases_loaded, contig_len); num_contigs++; bkmer = binary_kmer_from_str(r->seq.b + start, kmer_size); num_kmers_loaded++; node = db_graph_find(db_graph, bkmer); if(node.key != HASH_NOT_FOUND) { found = true; break; } for(i = start+kmer_size; i < end; i++) { nuc = dna_char_to_nuc(r->seq.b[i]); bkmer = binary_kmer_left_shift_add(bkmer, kmer_size, nuc); num_kmers_loaded++; node = db_graph_find(db_graph, bkmer); if(node.key != HASH_NOT_FOUND) { found = true; break; } } } } // Update stats __sync_fetch_and_add((volatile size_t*)&stats->total_bases_read, r->seq.end); __sync_fetch_and_add((volatile size_t*)&stats->num_kmers_loaded, num_kmers_loaded); __sync_fetch_and_add((volatile size_t*)&stats->num_kmers_novel, num_kmers_loaded - found); __sync_fetch_and_add((volatile size_t*)&stats->num_good_reads, num_contigs > 0); __sync_fetch_and_add((volatile size_t*)&stats->num_bad_reads, num_contigs == 0); return found; }
// Extend a supernode, nlist[offset] must already be set // Walk along nodes starting from node/or, storing the supernode in nlist // Returns the number of nodes added, adds no more than `limit` // return false if out of space and limit > 0 bool supernode_extend(dBNodeBuffer *nbuf, size_t limit, const dBGraph *db_graph) { ctx_assert(nbuf->len > 0); const size_t kmer_size = db_graph->kmer_size; dBNode node0 = nbuf->data[0], node1 = nbuf->data[nbuf->len-1], node = node1; BinaryKmer bkmer = db_node_oriented_bkmer(db_graph, node); Edges edges = db_node_get_edges_union(db_graph, node.key); Nucleotide nuc; while(edges_has_precisely_one_edge(edges, node.orient, &nuc)) { bkmer = binary_kmer_left_shift_add(bkmer, kmer_size, nuc); node = db_graph_find(db_graph, bkmer); edges = db_node_get_edges_union(db_graph, node.key); ctx_assert(node.key != HASH_NOT_FOUND); if(edges_has_precisely_one_edge(edges, rev_orient(node.orient), &nuc)) { if(node.key == node0.key || node.key == nbuf->data[nbuf->len-1].key) { // don't create a loop A->B->A or a->b->B->A break; } if(limit && nbuf->len >= limit) return false; db_node_buf_add(nbuf, node); } else break; } return true; }