diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2011-09-21 00:04:41 +0500 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2011-09-21 00:04:41 +0500 |
commit | 0249413a6ae4a5900b51f434b361b9efa6133ad1 (patch) | |
tree | ce34c73e2d9ad3d7b9d08612c35b65141b55821a /sql/gcalc_tools.cc | |
parent | 5a04ac7bf0ee359fb36f4ebc00f0aebc142d36b7 (diff) | |
download | mariadb-git-0249413a6ae4a5900b51f434b361b9efa6133ad1.tar.gz |
several bugs fixed here.
849789 Second assertion `m_poly_borders->next' failed in Gcalc_operation_reducer::count_slice in maria-5.3-gis
849791 Fourth assertion `n > 0 && n < SINUSES_CALCULATED*2+1' in get_n_sincos
849789 Second assertion `m_poly_borders->next' failed in Gcalc_operation_reducer::count_slice in maria-5.3-gis
848901 Assertion `fabs(cur_isc->x-m_cur_intersection->x) + fabs(cur_isc->y-m_cur_intersection->y) < 0.000000000001' failed in Gcalc_scan_iterator::intersection_scan() in maria-5.3-gis
per-file comments:
mysql-test/r/gis-precise.result
test result updated.
mysql-test/r/gis.result
test result updated.
sql/gcalc_slicescan.cc
bugfixes.
sql/gcalc_slicescan.h
bugfixes.
sql/gcalc_tools.cc
bugfixes.
sql/gcalc_tools.h
bugfixes.
sql/item_geofunc.cc
bugfixes.
sql/spatial.cc
bugfixes.
Diffstat (limited to 'sql/gcalc_tools.cc')
-rw-r--r-- | sql/gcalc_tools.cc | 293 |
1 files changed, 189 insertions, 104 deletions
diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc index baff6278444..90c39f08d0b 100644 --- a/sql/gcalc_tools.cc +++ b/sql/gcalc_tools.cc @@ -347,6 +347,10 @@ int Gcalc_result_receiver::add_point(double x, double y) buffer.q_append(prev_y); prev_x= x; prev_y= y; +#ifndef NO_TESTING + if (n_points == 53) + printf("xxx\n"); +#endif /*NO_TESTING*/ return 0; } @@ -488,6 +492,9 @@ int Gcalc_result_receiver::move_hole(uint32 dest_position, uint32 source_positio Gcalc_operation_reducer::Gcalc_operation_reducer(size_t blk_size) : Gcalc_dyn_list(blk_size, sizeof(res_point)), +#ifndef DBUG_OFF + n_res_points(0), +#endif /*DBUG_OFF*/ m_res_hook((Gcalc_dyn_list::Item **)&m_result), m_first_active_thread(NULL) {} @@ -514,9 +521,73 @@ Gcalc_operation_reducer(Gcalc_function *fn, modes mode, size_t blk_size) : } -inline int Gcalc_operation_reducer::continue_range(active_thread *t, - const Gcalc_heap::Info *p, - int horiz_dir, double dx_dy) +void Gcalc_operation_reducer::res_point::set(const Gcalc_scan_iterator *si) +{ + if ((intersection_point= si->intersection_step())) + ii= si->get_cur_ii(); + else + pi= si->get_cur_pi(); +} + +#ifndef NO_TESTING +void call_checkpoint(int d) +{ + printf("%d\n", d); +} +#endif /*NO_TESTING*/ + +Gcalc_operation_reducer::res_point * + Gcalc_operation_reducer::add_res_point(Gcalc_function::shape_type type) +{ + res_point *result= (res_point *)new_item(); + *m_res_hook= result; + result->prev_hook= m_res_hook; + m_res_hook= &result->next; + result->type= type; +#ifndef DBUG_OFF + result->point_n= n_res_points++; +#endif /*DBUG_OFF*/ +#ifndef NO_TESTING + if (result->point_n == 74) + call_checkpoint(74); +#endif /*NO_TESTING*/ + return result; +} + +int Gcalc_operation_reducer::add_line(int incoming, active_thread *t, + const Gcalc_scan_iterator::point *p) +{ + line *l= new_line(); + if (!l) + return 1; + l->incoming= incoming; + l->t= t; + l->p= p; + *m_lines_hook= l; + m_lines_hook= &l->next; + return 0; +} + + +int Gcalc_operation_reducer::add_poly_border(int incoming, + active_thread *t, int prev_state, const Gcalc_scan_iterator::point *p) +{ + poly_border *b= new_poly_border(); + if (!b) + return 1; + b->incoming= incoming; + b->t= t; + b->prev_state= prev_state; + b->p= p; + *m_poly_borders_hook= b; + m_poly_borders_hook= &b->next; + return 0; +} + + +int Gcalc_operation_reducer::continue_range(active_thread *t, + const Gcalc_heap::Info *p, + const Gcalc_heap::Info *p_next) { res_point *rp= add_res_point(t->rp->type); if (!rp) @@ -527,15 +598,14 @@ inline int Gcalc_operation_reducer::continue_range(active_thread *t, rp->intersection_point= false; rp->pi= p; t->rp= rp; - t->horiz_dir= horiz_dir; - t->dx_dy= dx_dy; + t->p1= p; + t->p2= p_next; return 0; } inline int Gcalc_operation_reducer::continue_i_range(active_thread *t, - double x, double y, - int horiz_dir, double dx_dy) + const Gcalc_heap::Intersection_info *ii) { res_point *rp= add_res_point(t->rp->type); if (!rp) @@ -544,11 +614,8 @@ inline int Gcalc_operation_reducer::continue_i_range(active_thread *t, rp->down= t->rp; t->rp->up= rp; rp->intersection_point= true; - rp->x= x; - rp->y= y; + rp->ii= ii; t->rp= rp; - t->horiz_dir= horiz_dir; - t->dx_dy= dx_dy; return 0; } @@ -573,6 +640,9 @@ int Gcalc_operation_reducer::end_couple(active_thread *t0, active_thread *t1, } +#ifndef NO_TESTING +int ca_counter= 0; +#endif /*NO_TESTING*/ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) { Gcalc_point_iterator pi(si); @@ -587,8 +657,16 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) active_thread *bottom_threads= NULL; active_thread *eq_thread, *point_thread;; +#ifndef NO_TESTING + if (ca_counter == 11522) + call_checkpoint(89); +#endif /*NO_TESTING*/ m_fn->clear_state(); /* Walk to the event, remembering what is needed. */ +#ifndef NO_TESTING + if (si->get_event_position() == pi.point()) + printf("yyy\n"); +#endif /*NO_TESTING*/ for (; pi.point() != si->get_event_position(); ++pi, cur_t_hook= (active_thread **) &(*cur_t_hook)->next) { @@ -612,13 +690,13 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) case scev_point: { if (cur_t->enabled() && - continue_range(cur_t, events->pi, events->horiz_dir, events->dx_dy)) + continue_range(cur_t, events->pi, events->next_pi)) return 1; break; } case scev_end: { - if (cur_t->enabled() && end_line(cur_t, events->pi, si)) + if (cur_t->enabled() && end_line(cur_t, si)) return 1; *cur_t_hook= cur_t->get_next(); free_item(cur_t); @@ -635,8 +713,7 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) else if (cur_t->enabled() || cur_t->get_next()->enabled()) { /* Rare case when edges of a polygon coincide */ - if (end_line(cur_t->enabled() ? cur_t : cur_t->get_next(), - events->pi, si)) + if (end_line(cur_t->enabled() ? cur_t : cur_t->get_next(), si)) return 1; } *cur_t_hook= cur_t->get_next()->get_next(); @@ -647,6 +724,9 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) default: DBUG_ASSERT(0); } +#ifndef NO_TESTING + goto testing; +#endif /*NO_TESTING*/ return 0; } @@ -773,7 +853,7 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) for (events= si->get_events(); events; events= events->get_next()) m_fn->set_on_state(events->get_shape()); - return m_fn->count() ? add_single_point(event_point, si) : 0; + return m_fn->count() ? add_single_point(si) : 0; } if (m_poly_borders) @@ -783,6 +863,10 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) { poly_border *pb1, *pb2; pb1= m_poly_borders; +#ifndef NO_TESTING + if (!m_poly_borders->next) + call_checkpoint(3); +#endif /*NO_TESTING*/ DBUG_ASSERT(m_poly_borders->next); pb2= get_pair_border(pb1); @@ -790,8 +874,7 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) m_poly_borders= pb1->get_next(); if (connect_threads(pb1->incoming, pb2->incoming, pb1->t, pb2->t, pb1->p, pb2->p, - prev_range, event_point, si, - Gcalc_function::shape_polygon)) + prev_range, si, Gcalc_function::shape_polygon)) return 1; free_item(pb1); @@ -809,8 +892,8 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) { if (connect_threads(m_lines->incoming, m_lines->get_next()->incoming, m_lines->t, m_lines->get_next()->t, - m_lines->p, m_lines->get_next()->p, NULL, - event_point, si, Gcalc_function::shape_line)) + m_lines->p, m_lines->get_next()->p, + NULL, si, Gcalc_function::shape_line)) return 1; } else @@ -819,11 +902,11 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) { if (cur_line->incoming) { - if (end_line(cur_line->t, event_point, si)) + if (end_line(cur_line->t, si)) return 1; } else - start_line(cur_line->t, cur_line->p, event_point, si); + start_line(cur_line->t, cur_line->p, si); } } free_list(m_lines); @@ -834,28 +917,56 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si) if (bottom_threads) free_list(bottom_threads); +#ifndef NO_TESTING +testing: + { + Gcalc_point_iterator x_pi(si); + active_thread **x_cur_t_hook= &m_first_active_thread; + int x_prev_state= 0; + m_fn->save_states(); + m_fn->clear_state(); + if (ca_counter == /*11552*/90) + call_checkpoint(10); + for (; x_pi.point(); ++x_pi) + { + active_thread *cur_t= *x_cur_t_hook; + if (cur_t->enabled() && + cur_t->rp->type == Gcalc_function::shape_polygon) + x_prev_state^= 1; + int ppb= m_fn->count(); + if (m_fn->get_shape_kind(x_pi.get_shape()) == Gcalc_function::shape_polygon) + m_fn->invert_state(x_pi.get_shape()); + int ppa= m_fn->count(); + if (ppa != x_prev_state) + { + if (x_pi.point()->cmp_dx_dy(x_pi.point()->get_next()) != 0) + call_checkpoint(21); + } + if (cur_t->enabled()) + { + if (m_fn->get_shape_kind(x_pi.get_shape()) == Gcalc_function::shape_polygon) + if (ppa == ppb) + call_checkpoint(22); + else + if (ppa != 0 && ppb != 0) + call_checkpoint(23); + } + x_cur_t_hook= (active_thread **) &(*x_cur_t_hook)->next; + } + m_fn->restore_states(); + } +#endif /*NO_TESTING*/ return 0; } -int Gcalc_operation_reducer::add_single_point(const Gcalc_heap::Info *p, - const Gcalc_scan_iterator *si) +int Gcalc_operation_reducer::add_single_point(const Gcalc_scan_iterator *si) { res_point *rp= add_res_point(Gcalc_function::shape_point); if (!rp) return 1; rp->glue= rp->up= rp->down= NULL; - if (p) - { - rp->intersection_point= false; - rp->pi= p; - } - else - { - rp->intersection_point= true; - rp->y= si->get_y(); - rp->x= si->get_events()->x; - } + rp->set(si); return 0; } @@ -912,7 +1023,7 @@ int Gcalc_operation_reducer::connect_threads( int incoming_a, int incoming_b, active_thread *ta, active_thread *tb, const Gcalc_scan_iterator::point *pa, const Gcalc_scan_iterator::point *pb, - active_thread *prev_range, const Gcalc_heap::Info *ev_p, + active_thread *prev_range, const Gcalc_scan_iterator *si, Gcalc_function::shape_type s_t) { if (incoming_a && incoming_b) @@ -929,18 +1040,8 @@ int Gcalc_operation_reducer::connect_threads( rpa->up= rpb->up= NULL; ta->rp->up= rpa; tb->rp->up= rpb; - if (ev_p) - { - rpa->intersection_point= rpb->intersection_point= false; - rpa->pi= rpb->pi= ev_p; - } - else - { - rpa->intersection_point= rpb->intersection_point= true; - rpa->x= rpb->x= si->get_events()->x; - rpa->y= rpb->y= si->get_y(); - } - + rpa->set(si); + rpb->set(si); ta->rp= tb->rp= NULL; return 0; } @@ -953,35 +1054,30 @@ int Gcalc_operation_reducer::connect_threads( return 1; rp0->glue= rp1; rp1->glue= rp0; - if (ev_p) - { - rp0->intersection_point= rp1->intersection_point= false; - rp0->pi= rp1->pi= ev_p; - } - else - { - rp0->intersection_point= rp1->intersection_point= true; - rp0->x= rp1->x= si->get_events()->x; - rp0->y= rp1->y= si->get_y(); - } + rp0->set(si); + rp1->set(si); rp0->down= rp1->down= NULL; ta->rp= rp0; tb->rp= rp1; - ta->horiz_dir= pa->horiz_dir; - ta->dx_dy= pa->dx_dy; + ta->p1= pa->pi; + ta->p2= pa->next_pi; - tb->horiz_dir= pb->horiz_dir; - tb->dx_dy= pb->dx_dy; + tb->p1= pb->pi; + tb->p2= pb->next_pi; if (prev_range) { rp0->outer_poly= prev_range->thread_start; tb->thread_start= prev_range->thread_start; + /* Chack if needed */ + ta->thread_start= prev_range->thread_start; } else { rp0->outer_poly= 0; ta->thread_start= rp0; + /* Chack if needed */ + tb->thread_start= rp0; } return 0; } @@ -991,20 +1087,18 @@ int Gcalc_operation_reducer::connect_threads( tb->rp= ta->rp; tb->thread_start= ta->thread_start; if (Gcalc_scan_iterator::point:: - compare_dx_dy(ta->horiz_dir, ta->dx_dy, - pb->horiz_dir, pb->dx_dy) != 0) + cmp_dx_dy(ta->p1, ta->p2, pb->pi, pb->next_pi) != 0) { - if (ev_p ? continue_range(tb, ev_p, pb->horiz_dir, pb->dx_dy): - continue_i_range(tb, - si->get_events()->x, si->get_y(), - pb->horiz_dir, pb->dx_dy)) + if (si->intersection_step() ? + continue_i_range(tb, si->get_cur_ii()) : + continue_range(tb, si->get_cur_pi(), pb->next_pi)) +#ifdef TMP_BLOCK + continue_range(tb, si->get_cur_pi()) +#endif /*TMP_BLOCK*/ return 1; } - else - { - tb->horiz_dir= pb->horiz_dir; - tb->dx_dy= pb->dx_dy; - } + tb->p1= pb->pi; + tb->p2= pb->next_pi; return 0; } @@ -1012,33 +1106,21 @@ int Gcalc_operation_reducer::connect_threads( int Gcalc_operation_reducer::start_line(active_thread *t, const Gcalc_scan_iterator::point *p, - const Gcalc_heap::Info *ev_p, const Gcalc_scan_iterator *si) { res_point *rp= add_res_point(Gcalc_function::shape_line); if (!rp) return 1; rp->glue= rp->down= NULL; - if (ev_p) - { - rp->intersection_point= false; - rp->pi= ev_p; - } - else - { - rp->intersection_point= true; - rp->x= si->get_events()->x; - rp->y= si->get_y(); - } + rp->set(si); t->rp= rp; - t->horiz_dir= p->horiz_dir; - t->dx_dy= p->dx_dy; + t->p1= p->pi; + t->p2= p->next_pi; return 0; } int Gcalc_operation_reducer::end_line(active_thread *t, - const Gcalc_heap::Info *ev_p, const Gcalc_scan_iterator *si) { DBUG_ASSERT(t->rp->type == Gcalc_function::shape_line); @@ -1047,17 +1129,7 @@ int Gcalc_operation_reducer::end_line(active_thread *t, return 1; rp->glue= rp->up= NULL; rp->down= t->rp; - if (ev_p) - { - rp->intersection_point= false; - rp->pi= ev_p; - } - else - { - rp->intersection_point= true; - rp->x= si->get_events()->x; - rp->y= si->get_y(); - } + rp->set(si); t->rp->up= rp; t->rp= NULL; @@ -1071,6 +1143,11 @@ int Gcalc_operation_reducer::count_all(Gcalc_heap *hp) si.init(hp); while (si.more_points()) { +#ifndef NO_TESTING + printf("Point %d\n", ++ca_counter); + if (ca_counter == 12) + call_checkpoint(10); +#endif /*NO_TESTING*/ if (si.step()) return 1; if (count_slice(&si)) @@ -1094,8 +1171,9 @@ inline int Gcalc_operation_reducer::get_single_result(res_point *res, { if (res->intersection_point) { - if (storage->single_point(float_to_coord(res->x), - float_to_coord(res->y))) + double x, y; + res->ii->calc_xy(&x, &y); + if (storage->single_point(x,y)) return 1; } else @@ -1105,6 +1183,9 @@ inline int Gcalc_operation_reducer::get_single_result(res_point *res, return 0; } +#ifndef NO_TESTING +int pc_counter= 0; +#endif /*NO_TESTING*/ int Gcalc_operation_reducer::get_result_thread(res_point *cur, Gcalc_result_receiver *storage, @@ -1116,12 +1197,16 @@ int Gcalc_operation_reducer::get_result_thread(res_point *cur, double x, y; while (cur) { +#ifndef NO_TESTING + ++pc_counter; + if (pc_counter == 79) + call_checkpoint(79); +#endif /*NO_TESTING*/ if (!glue_step) { if (cur->intersection_point) { - x= float_to_coord(cur->x); - y= float_to_coord(cur->y); + cur->ii->calc_xy(&x, &y); } else { |