Test(msg_ack, clone_ack) { AckRecord *t = ack_record_new(); t->init(t); LogMessage *cloned = create_clone(t->original, &t->path_options); log_msg_drop(cloned, &t->path_options, AT_PROCESSED); cr_assert_not(t->acked); t->deinit(t); cr_assert(t->acked); ack_record_free(t); }
bool ProcessTwoBreakAndClone<graph_pack_t>::run(graph_pack_t & graph_pack) { bool isChanged = false; size_t number_rear = 0; // number of rearrangements do { number_rear = 0; for (vertex_t const & x : graph_pack.graph) { mularcs_t const & mularcs = graph_pack.get_all_adjacent_multiedges(x); if (graph_pack.is_duplication_vertex(x) || (mularcs.begin()->second == graph_pack.multicolors.get_complete_color())) { continue; } bool found = false; for (auto im = mularcs.cbegin(); (im != mularcs.cend()) && !found; ++im) { vertex_t const & y = im->first; // Q == im->second - color of central edge if (y == Infty || graph_pack.is_duplication_vertex(y)) { continue; } if (!graph_pack.is_mobility_edge(x, y)) { mularcs_t mularcs_x = graph_pack.get_all_adjacent_multiedges_with_info(x); mularcs_x.erase(y); mularcs_t mularcs_y = graph_pack.get_all_adjacent_multiedges_with_info(y); mularcs_y.erase(x); /*SPLIT ALL EDGES ON MOBILE AND NON MOBILE*/ set_arc_t mobile_edges_x; set_arc_t non_mobile_edges_x; split_by_mobile_property(graph_pack, x, mularcs_x, mobile_edges_x, non_mobile_edges_x); set_arc_t mobile_edges_y; set_arc_t non_mobile_edges_y; split_by_mobile_property(graph_pack, y, mularcs_y, mobile_edges_y, non_mobile_edges_y); /*CREATE POSSIBLE MOBILE CLONES AND TWOBREAKS*/ std::map<ind_arcs_t, std::set<ind_arcs_t> > classes = split_by_colors(mularcs_x, mularcs_y); std::vector<twobreak_t> possible_twobreaks; std::vector<clone_t> possible_clones; bool is_all_good = true; for (auto const & color_set : classes) { mularcs_t mularcs_left; mularcs_t mularcs_right; for (auto const & color : color_set.second) { if (color.second == 0) { mularcs_left.insert(color.first.first, color.first.second); } else { mularcs_right.insert(color.first.first, color.first.second); } } if (mularcs_left.size() == 1 && mularcs_right.size() == 1 && mularcs_left.cbegin()->second == mularcs_right.cbegin()->second) { mcolor_t const & color = mularcs_left.cbegin()->second; if (mobile_edges_x.count(*mularcs_left.cbegin()) != 0 && mobile_edges_y.count(*mularcs_right.cbegin()) != 0 && graph_pack.multicolors.is_vec_T_consistent_color(color)) { vertex_t const & u = mularcs_left.cbegin()->first; vertex_t const & v = mularcs_right.cbegin()->first; twobreak_t twobreak(x, u, y, v, color); possible_twobreaks.push_back(twobreak); } else { is_all_good = false; } } else if (mularcs_left.size() == 1 && mularcs_left.cbegin()->second == mularcs_right.union_multicolors()) { auto result = create_clone(graph_pack, mularcs_left, x, y, mularcs_right, mobile_edges_x, mobile_edges_y); if (result.first) { possible_clones.push_back(result.second); } else { is_all_good = false; } } else if (mularcs_right.size() == 1 && mularcs_right.cbegin()->second == mularcs_left.union_multicolors()) { auto result = create_clone(graph_pack, mularcs_right, y, x, mularcs_left, mobile_edges_y, mobile_edges_x); if (result.first) { possible_clones.push_back(result.second); } else { is_all_good = false; } } else { is_all_good = false; } } /*START TO WORK WITH MAIN ALGORITHM*/ /*CASE 1: Create complete edge*/ if (is_all_good) { std::set<mcolor_t> actions = get_worked_colors(possible_twobreaks); std::set<mcolor_t> clone_action = get_worked_colors(possible_clones); actions.insert(clone_action.begin(), clone_action.end()); if (is_good_actions(graph_pack, actions)) { //std::cerr << "Do cloning and two-break in first case" << std::endl; for (auto const & twobreak : possible_twobreaks) { //std::cerr << twobreak.get_vertex(0) << " " << twobreak.get_vertex(1) << " " << twobreak.get_vertex(2) << " " << twobreak.get_vertex(3) << " " << genome_match::mcolor_to_name(twobreak.get_mcolor()) << std::endl; graph_pack.apply(twobreak); found = true; ++number_rear; } for (auto const & clone : possible_clones) { graph_pack.apply(clone); found = true; ++number_rear; } if (found) { assert(graph_pack.get_all_multicolor_edge(x, y).empty() || graph_pack.get_all_multicolor_edge(x, y) == graph_pack.multicolors.get_complete_color()); } } } /*CASE 2: Create min T-consistent color*/ if (!found) { mcolor_t additional_color = graph_pack.multicolors.get_min_addit_color_for_tc(graph_pack.get_all_multicolor_edge(x, y)); if (!additional_color.empty() && additional_color != graph_pack.multicolors.get_complete_color()) { std::vector<twobreak_t> included_twobreaks; std::vector<clone_t> included_clones; for (auto twobreak = possible_twobreaks.cbegin(); (twobreak != possible_twobreaks.cend()) && !additional_color.empty(); ++twobreak) { mcolor_t action_color = twobreak->get_mcolor(); if (additional_color.includes(action_color) && graph_pack.multicolors.is_vec_T_consistent_color(action_color)) { included_twobreaks.push_back(*twobreak); additional_color = mcolor_t(additional_color, action_color, mcolor_t::Difference); } } for (auto clone = possible_clones.cbegin(); (clone != possible_clones.cend()) && !additional_color.empty(); ++clone) { mcolor_t action_color = clone->get_mcolor(); if (additional_color.includes(action_color) && graph_pack.multicolors.is_vec_T_consistent_color(action_color)) { included_clones.push_back(*clone); additional_color = mcolor_t(additional_color, action_color, mcolor_t::Difference); } } if (additional_color.empty()) { std::set<mcolor_t> actions = get_worked_colors(included_twobreaks); std::set<mcolor_t> clone_action = get_worked_colors(included_clones); actions.insert(clone_action.begin(), clone_action.end()); if (is_good_actions(graph_pack, actions)) { for (auto const & twobreak : included_twobreaks) { graph_pack.apply(twobreak); found = true; ++number_rear; } for (auto const & clone : included_clones) { graph_pack.apply(clone); found = true; ++number_rear; } if (found) { assert(graph_pack.get_all_multicolor_edge(x, y).empty() || graph_pack.multicolors.is_T_consistent_color(graph_pack.get_all_multicolor_edge(x, y))); } } } } } } } } if (number_rear != 0) { isChanged = true; } } while (number_rear > 0); return isChanged; }
void APITests::testBasicOperations(int width, int height) { const PixelFormat format = PF_R8G8B8A8; const int bpp = 4; auto_ptr<Image> image(CreateImage(width, height, format)); CPPUNIT_ASSERT(image->getWidth() == width); CPPUNIT_ASSERT(image->getHeight() == height); CPPUNIT_ASSERT(image->getFormat() == format); // verify that the image is black byte* pixels = (byte*)image->getPixels(); for (int i = 0; i < width * height * bpp; ++i) { CPPUNIT_ASSERT(pixels[i] == 0); } // fill the image with random pixels for (int i = 0; i < width * height * bpp; ++i) { pixels[i] = rand() % 256; } auto_ptr<Image> create_clone( CreateImage(image->getWidth(), image->getHeight(), image->getFormat(), image->getPixels())); CPPUNIT_ASSERT(create_clone.get() != 0); CPPUNIT_ASSERT(image->getWidth() == create_clone->getWidth()); CPPUNIT_ASSERT(image->getHeight() == create_clone->getHeight()); CPPUNIT_ASSERT(image->getFormat() == create_clone->getFormat()); CPPUNIT_ASSERT(memcmp(image->getPixels(), create_clone->getPixels(), width * height * bpp) == 0); // clone the image (use same pixel format) auto_ptr<Image> identical_clone(CloneImage(image.get())); CPPUNIT_ASSERT(image->getWidth() == identical_clone->getWidth()); CPPUNIT_ASSERT(image->getHeight() == identical_clone->getHeight()); CPPUNIT_ASSERT(image->getFormat() == identical_clone->getFormat()); CPPUNIT_ASSERT(memcmp(image->getPixels(), identical_clone->getPixels(), width * height * bpp) == 0); // clone the image, removing the alpha channel auto_ptr<Image> other_clone(CloneImage(identical_clone.get(), PF_R8G8B8)); CPPUNIT_ASSERT(image->getWidth() == other_clone->getWidth()); CPPUNIT_ASSERT(image->getHeight() == other_clone->getHeight()); CPPUNIT_ASSERT(other_clone->getFormat() == PF_R8G8B8); byte* image_p = (byte*)image->getPixels(); byte* other_p = (byte*)other_clone->getPixels(); for (int i = 0; i < width * height; ++i) { CPPUNIT_ASSERT(*image_p++ == *other_p++); CPPUNIT_ASSERT(*image_p++ == *other_p++); CPPUNIT_ASSERT(*image_p++ == *other_p++); ++image_p; // skip alpha } // flip the image // clone source first, since flip frees the original auto_ptr<Image> flip_none(FlipImage(CloneImage(image.get()), 0)); auto_ptr<Image> flip_x (FlipImage(CloneImage(image.get()), CA_X)); auto_ptr<Image> flip_y (FlipImage(CloneImage(image.get()), CA_Y)); auto_ptr<Image> flip_xy (FlipImage(CloneImage(image.get()), CA_X | CA_Y)); AssertImagesEqual("No flipping", flip_none.get(), image.get()); CPPUNIT_ASSERT(flip_x.get() != 0); CPPUNIT_ASSERT(width == flip_x->getWidth()); CPPUNIT_ASSERT(height == flip_x->getHeight()); CPPUNIT_ASSERT(format == flip_x->getFormat()); CPPUNIT_ASSERT(flip_y.get() != 0); CPPUNIT_ASSERT(width == flip_y->getWidth()); CPPUNIT_ASSERT(height == flip_y->getHeight()); CPPUNIT_ASSERT(format == flip_y->getFormat()); CPPUNIT_ASSERT(flip_xy.get() != 0); CPPUNIT_ASSERT(width == flip_xy->getWidth()); CPPUNIT_ASSERT(height == flip_xy->getHeight()); CPPUNIT_ASSERT(format == flip_xy->getFormat()); const byte* flip_x_pixels = (const byte*)flip_x->getPixels(); const byte* flip_y_pixels = (const byte*)flip_y->getPixels(); const byte* flip_xy_pixels = (const byte*)flip_xy->getPixels(); for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { const int image_index = (h * width + w) * bpp; const int opp_w = width - 1 - w; const int opp_h = height - 1 - h; const int flip_x_index = (opp_h * width + w) * bpp; const int flip_y_index = (h * width + opp_w) * bpp; const int flip_xy_index = (opp_h * width + opp_w) * bpp; for (int p = 0; p < bpp; p++) { CPPUNIT_ASSERT(pixels[image_index] == flip_x_pixels [flip_x_index]); CPPUNIT_ASSERT(pixels[image_index] == flip_y_pixels [flip_y_index]); CPPUNIT_ASSERT(pixels[image_index] == flip_xy_pixels[flip_xy_index]); } } } }