size_t dedup_methods_helper( const Scope& scope, const std::vector<DexMethod*>& to_dedup, std::vector<DexMethod*>& replacements, boost::optional<std::unordered_map<DexMethod*, MethodOrderedSet>>& new_to_old) { if (to_dedup.size() <= 1) { replacements = to_dedup; return 0; } size_t dedup_count = 0; auto grouped_methods = group_identical_methods(to_dedup); std::unordered_map<DexMethod*, DexMethod*> duplicates_to_replacement; for (auto& group : grouped_methods) { auto replacement = *group.begin(); for (auto m : group) { duplicates_to_replacement[m] = replacement; // Update dedup map if (new_to_old == boost::none) { continue; } if (new_to_old->count(m) > 0) { auto orig_old_list = new_to_old->at(m); new_to_old->erase(m); for (auto orig_old : orig_old_list) { new_to_old.get()[replacement].insert(orig_old); } } new_to_old.get()[replacement].insert(m); } if (new_to_old != boost::none) { new_to_old.get()[replacement].insert(replacement); } replacements.push_back(replacement); if (group.size() > 1) { dedup_count += group.size() - 1; TRACE(METH_DEDUP, 9, "dedup: group %d replacement %s\n", group.size(), SHOW(replacement)); } } method_reference::update_call_refs_simple(scope, duplicates_to_replacement); return dedup_count; }
vector<CubicBezierControlPoints> RRTPlanner::generateCubicBezierPath( const vector<Geometry2d::Point>& points, const MotionConstraints& motionConstraints, Geometry2d::Point vi, Geometry2d::Point vf, const boost::optional<vector<float>>& times) { size_t length = points.size(); size_t curvesNum = length - 1; vector<double> pointsX(length); vector<double> pointsY(length); vector<double> ks(length - 1); vector<double> ks2(length - 1); for (int i = 0; i < length; i++) { pointsX[i] = points[i].x; pointsY[i] = points[i].y; } const float startSpeed = vi.mag(); const float endSpeed = vf.mag(); if (times) { assert(times->size() == points.size()); for (int i = 0; i < curvesNum; i++) { ks[i] = 1.0 / (times->at(i + 1) - times->at(i)); ks2[i] = ks[i] * ks[i]; if (std::isnan(ks[i])) { debugThrow( "Something went wrong. Points are too close to each other " "probably"); return vector<CubicBezierControlPoints>(); } } } else { for (int i = 0; i < curvesNum; i++) { ks[i] = 1.0 / (getTime(points, i + 1, motionConstraints, startSpeed, endSpeed) - getTime(points, i, motionConstraints, startSpeed, endSpeed)); ks2[i] = ks[i] * ks[i]; if (std::isnan(ks[i])) { debugThrow( "Something went wrong. Points are too close to each other " "probably"); return vector<CubicBezierControlPoints>(); } } } VectorXd solutionX = RRTPlanner::cubicBezierCalc(vi.x, vf.x, pointsX, ks, ks2); VectorXd solutionY = RRTPlanner::cubicBezierCalc(vi.y, vf.y, pointsY, ks, ks2); vector<CubicBezierControlPoints> path; for (int i = 0; i < curvesNum; i++) { Point p0 = points[i]; Point p1 = Geometry2d::Point(solutionX(i * 2), solutionY(i * 2)); Point p2 = Geometry2d::Point(solutionX(i * 2 + 1), solutionY(i * 2 + 1)); Point p3 = points[i + 1]; path.emplace_back(p0, p1, p2, p3); } return path; }