int build (char *ref_name, char *target_path, int k_mer, double error_rate, char *prefix) { char *position = mmaping (ref_name); bloom *bl = NEW (bloom); if (k_mer != 0) bl->k_mer = k_mer; else bl->k_mer = kmer_suggestion (get_size (ref_name)); bl->stat.e = error_rate; bl->dx = bl->k_mer*bl->k_mer; bl->stat.capacity = strlen (position); get_rec (&bl->stat); bloom_init (bl, bl->stat.elements, bl->stat.capacity, bl->stat.e, bl->stat.ideal_hashes, NULL, 3); ref_add (bl, position); save_bloom (ref_name, bl, prefix, target_path); return 0; }
static void * reach_thread (void *vdata) { struct tdata *data = vdata; int sw = data->sw; struct list_res *res = &data->res; const uint32_t *out = g_out; int nout = g_nout; int ntfs = data_file->ntfs - 1; //int count = 0, loops = 0; while (true) { struct list_res queue = {0}; pthread_mutex_lock (&wait_lock); //fprintf (stderr, "%d %d\n", sw, queues[sw].n); while (!queues[sw].head) { waiters |= 1 << sw; if (waiters + 1 == 1 << ntfs) { for (int i = 0; i < ntfs; i++) { if (i == sw) continue; pthread_cond_broadcast (&conds[i]); } pthread_mutex_unlock (&wait_lock); return NULL; } pthread_cond_wait (&conds[sw], &wait_lock); if (waiters + 1 == 1 << ntfs) { pthread_mutex_unlock (&wait_lock); return NULL; } assert (waiters | (1 << sw)); } queue = queues[sw]; memset (&queues[sw], 0, sizeof queues[sw]); pthread_mutex_unlock (&wait_lock); struct res *cur; while ((cur = queue.head)) { list_pop (&queue); bool new_res = false; struct list_res nextqs[ntfs]; memset (nextqs, 0, sizeof nextqs); struct list_res ntf_res = ntf_apply (cur, sw); struct res *ntf_cur = ntf_res.head; while (ntf_cur) { struct res *ntf_next = ntf_cur->next; if (!out || int_find (ntf_cur->port, out, nout)) { list_append (res, ntf_cur); ref_add (ntf_cur, cur); if (out) { ntf_cur = ntf_next; continue; } } struct list_res ttf_res = tf_apply (tf_get (0), ntf_cur, true); struct res *ttf_cur = ttf_res.head; while (ttf_cur) { struct res *ttf_next = ttf_cur->next; if (is_loop (ttf_cur->port, cur)) { res_free (ttf_cur); ttf_cur = ttf_next; //loops++; continue; } ref_add (ttf_cur, cur); if (out && int_find (ttf_cur->port, out, nout)) list_append (res, ttf_cur); else { int new_sw = ntf_get_sw (ttf_cur->port); list_append (&nextqs[new_sw], ttf_cur); //count++; new_res = true; } ttf_cur = ttf_next; } if (out) res_free (ntf_cur); ntf_cur = ntf_next; } res_free_mt (cur, true); if (!new_res) continue; pthread_mutex_lock (&wait_lock); unsigned int wake = 0; for (int i = 0; i < ntfs; i++) { if (!nextqs[i].head) continue; list_concat (&queues[i], &nextqs[i]); pthread_cond_broadcast (&conds[i]); wake |= 1 << i; } waiters &= ~wake; pthread_mutex_unlock (&wait_lock); } } }
int build_main (int argc, char **argv) { if (argc < 2) build_usage (); char *position; BIGNUM capacity; /*-------defaults for bloom filter building-------*/ int opt; int k_mer = 0; float error_rate = 0.0005; char *list = NULL; char *target_path = NULL; char *source = NULL; //XXX make -l and -r mutually exclusive while ((opt = getopt (argc, argv, "e:k:o:r:l:h")) != -1) { switch (opt) { case 'e': (optarg) && ((error_rate = atof (optarg)), 1); break; case 'k': (optarg) && ((k_mer = atoi (optarg)), 1); break; case 'o': (optarg) && ((target_path = optarg), 1); break; case 'r': (optarg) && (source = optarg, 1); break; case 'l': (optarg) && (list = optarg, 1); break; case 'h': return build_usage (); default: printf ("Unknown option: -%c\n", (char) optopt); return build_usage (); } } if (!list && !source) { fprintf (stderr, "\nPlease, at least specify a reference file (-r) and an output bloom filter (-o)\n"); exit (-1); } if (!list) { #ifdef DEBUG printf ("[bloom build]: source is %s\n", source); printf ("[bloom build]: target is %s\n", target_path); #endif build (source, target_path, k_mer, error_rate, argv[0]); } else { bloom *bl_2 = NEW (bloom); Queue *head = NEW (Queue); Queue *tail = NEW (Queue); head->next = tail; F_set *File_head = NEW (F_set); File_head = make_list (source, list); while (File_head) { //map query- into memory-------------- position = mmaping (File_head->filename); if (*position == '>') capacity = strlen (position); else capacity = strlen (position) / 2; init_bloom (bl_2, capacity, error_rate, k_mer, File_head->filename); ref_add (bl_2, position); save_bloom (File_head->filename, bl_2, argv[0], target_path); bloom_destroy (bl_2); munmap (position, strlen (position)); File_head = File_head->next; } } return 0; }