static int find_shortest_path (Bitmap *bitmap, GraphPath **path_r) /* current optimal path */ { GraphPath *path = *path_r; GraphPath *found_path = NULL; int cur_path_size = path->num_edges; int j,i; size_t num_p; int status = 1; int two_pass_mode = (cur_path_size < num_nodes); GraphNode **idc = alloca ( (path->num_edges + 1)*sizeof (GraphNode*) ); path_transform_to_reverse_nodes_aray (path, &idc, &num_p); _loop_enter: for (j = 0 ; j < num_p ;j++) { GraphNode *curnode = idc[j]; for (i = 0; i < curnode->num_edges; i++) { GraphEdge *curedge = curnode->edges[i]; GraphNode *node_to = curedge->node_ptr; if (path->total_weight + curedge->weight >= _found_min){ #ifdef DEBUG _stat_cut_by_weight++; #endif continue; //don't go this way } if (two_pass_mode && status && bmap_get_in (bitmap, node_to->arr_idx)){ continue; } if (two_pass_mode && !status && !bmap_get_in (bitmap, node_to->arr_idx)){ continue; } if (bmap_get (bitmap, curnode->arr_idx, node_to->arr_idx)){ #ifdef DEBUG _stat_cut_by_presence++; #endif continue; //already passed by this edge } _stop_cnt++; if (_stop_cnt > MAXIMUM_SEARCH_ITERATION){ //up until third level if (cur_path_size < _update_path){ _update_path -= 2; // printf ("max path update: %d\n", _update_path); _stop_cnt = 0; } goto _loop_exit; } #ifdef DEBUG _stat_evaluated++; #endif void *bitmap_n = bmap_clone (bitmap); // printf ("before(%d,%d): ",i,j); // path_print_short (path); path_add (path, curedge); bmap_set (bitmap_n, curnode->arr_idx, node_to->arr_idx); // printf ("after(%d,%d) : ",i,j); // path_print_short (path); int path_found = bmap_check_full (bitmap_n) && path_check_valid (path); GraphPath *hpath = NULL; if (path_found == 0){ //try to check solution in hash table hpath = bmap_hash_path_search_optimal (bitmap_n); if (hpath == NULL){ if (path->num_edges <= _depth ) path_found = find_shortest_path (bitmap_n, &path); }else { #ifdef DEBUG _stat_found_hash++; #endif if (hpath != BMAP_HASH_PATH_EMPTY ){ hpath = path_clone (hpath); //rearrange path ensure_order_paths (path, hpath, cur_path_size); path_free (path); path = hpath; path_found = 1; }else{ path_found = 0; } } } if (path_found == 1 && (found_path == NULL || path->total_weight < found_path->total_weight)) { path_free (found_path); found_path = path_clone (path); if (hpath == NULL && found_path->num_edges - cur_path_size > 1) bmap_hash_path_add_optimal (bitmap_n, found_path); }else{ if (hpath == NULL && cur_path_size < num_nodes + 2) bmap_hash_path_add_optimal (bitmap_n, NULL); } path_shrink_to_size (path, cur_path_size); bmap_free (bitmap_n); } } if(two_pass_mode && status && cur_path_size < num_nodes){ status = 0; goto _loop_enter; } _loop_exit: if (found_path != NULL){ _update_path = found_path->num_edges; // printf ("FOUND: "); // path_print_short (found_path); path_free (path); if (found_path->total_weight < _found_min){ _stop_cnt = 0; #ifdef DEBUG printf (" update max: %lu -> %lu (weight:%lu, presence:%lu, eval:%lu, hash:%lu)\n", _found_min, found_path->total_weight, _stat_cut_by_weight, _stat_cut_by_presence, _stat_evaluated, _stat_found_hash); #endif _found_min = found_path->total_weight; } *path_r = found_path; return 1; } return 0; }
static void* pthread_main (void *arg) { int* arr = (int*)arg; int thrn = *(arr); arr++; int num_elem = *(arr);arr++; #ifdef DEBUG printf ("starting thread %d num elem %d\n", thrn, num_elem); #endif int i; _depth = num_nodes + 1; for (i = 0; i < num_elem; i++){ #ifdef DEBUG printf ("iterating thread %d elem #%d\n", thrn, arr[i]); #endif _update_path = num_nodes; bmap_init_static (num_nodes); _node_to_start = arr[i]; _stop_cnt = 0; _found_min = (_global_found_min == ULONG_MAX ? ULONG_MAX: _global_found_min + 1); #ifdef DEBUG _stat_cut_by_weight = _stat_cut_by_presence = _stat_evaluated = _stat_found_hash = 0; #endif GraphPath *path = path_new (); Bitmap *bitmap = bmap_new (); int res = find_shortest_path (bitmap, &path); #ifdef DEBUG printf ("MAX: %lu -> %lu (weight:%lu, presence:%lu, eval:%lu, hash:%lu)\n", _found_min, path->total_weight, _stat_cut_by_weight, _stat_cut_by_presence, _stat_evaluated, _stat_found_hash); bmap_print_hash (); #endif if (res){ /* begin critical section */ pthread_mutex_lock (&_mutex); if (path->total_weight < _global_found_min){ match_cnt = 0; if (best_found_path) path_free (best_found_path); best_found_path = path_clone (path); _global_found_min = path->total_weight; } if (path->total_weight == _global_found_min){ match_cnt++; } if (match_cnt >= MINIMUM_NUMBER_MATCHES_RESULTS){ print_solution (best_found_path); exit(0); } pthread_mutex_unlock (&_mutex); /* end critical section */ } path_free (path); bmap_free (bitmap); _depth += 2; } bmap_free_static (); return 0; }
/* Deallocate the block BLK from DEV. */ bool free_block(struct fs_device *dev, blkno blk) { return bmap_free(dev, dev->sup.data_bitmap, blk - dev->sup.data); }