17 #include "my_global.h"
21 #include "sql_string.h"
22 #include "gcalc_tools.h"
25 #include "sql_class.h"
27 #define float_to_coord(d) ((double) d)
35 gcalc_shape_info Gcalc_function::add_new_shape(uint32 shape_id,
36 shape_type shape_kind)
38 shapes_buffer.q_append((uint32) shape_kind);
49 void Gcalc_function::add_operation(op_type operation, uint32 n_operands)
51 uint32 op_code= (uint32 ) operation + n_operands;
52 function_buffer.q_append(op_code);
63 uint32 op_code= uint4korr(function_buffer.ptr() + operation_pos) + n_operands;
64 function_buffer.write_at_position(operation_pos, op_code);
70 uint32 op_code= (uint4korr(function_buffer.ptr() + operation_pos) & op_any) +
72 function_buffer.write_at_position(operation_pos, op_code);
81 void Gcalc_function::add_not_operation(op_type operation, uint32 n_operands)
83 uint32 op_code= ((uint32) op_not | (uint32 ) operation) + n_operands;
84 function_buffer.q_append(op_code);
88 int Gcalc_function::single_shape_op(shape_type shape_kind, gcalc_shape_info *si)
90 if (reserve_shape_buffer(1) || reserve_op_buffer(1))
92 *si= add_new_shape(0, shape_kind);
93 add_operation(op_shape, *si);
102 int Gcalc_function::reserve_shape_buffer(uint n_shapes)
104 return shapes_buffer.reserve(n_shapes * shape_buffer_item_size, 512);
112 int Gcalc_function::reserve_op_buffer(uint n_ops)
114 return function_buffer.reserve(n_ops * function_buffer_item_size, 512);
118 int Gcalc_function::alloc_states()
120 if (function_buffer.reserve((n_shapes+1) *
sizeof(
int)))
122 i_states= (
int *) (function_buffer.ptr() + ALIGN_SIZE(function_buffer.length()));
134 enum op_type
type= (
enum op_type) code;
137 case op_shape:
return "op_shape";
138 case op_not:
return "op_not";
139 case op_union:
return "op_union";
140 case op_intersection:
return "op_intersection";
141 case op_symdifference:
return "op_symdifference";
142 case op_difference:
return "op_difference";
143 case op_backdifference:
return "op_backdifference";
144 case op_any:
return "op_any";
154 case shape_point:
return "shape_point";
155 case shape_line:
return "shape_line";
156 case shape_polygon:
return "shape_polygon";
157 case shape_hole:
return "shape_hole";
159 return "shape_unknown";
169 int i, nelements= function_buffer.length() / function_buffer_item_size;
170 THD *thd= current_thd;
171 DBUG_PRINT(
"info", (
"nelements=%d", nelements));
172 for (i= 0; i < nelements; i++)
174 int c_op= uint4korr(function_buffer.ptr() + function_buffer_item_size *
i);
175 int func= (c_op & op_any);
176 int mask= (c_op & op_not) ? 1 : 0;
177 int n_ops= c_op & ~op_any;
178 const char *c_op_name=
op_name(func);
179 const char *s_name= (func == op_shape) ?
181 shape_buffer_item_size * n_ops)) :
"";
182 DBUG_PRINT(
"info", (
"[%d]=%d c_op=%d (%s) mask=%d n_ops=%d",
183 i, c_op, func, c_op_name, mask, n_ops));
184 if (thd->get_gis_debug())
185 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
186 ER_UNKNOWN_ERROR,
"[%d] %s[%d]%s",
187 i, c_op_name, n_ops, s_name);
193 int Gcalc_function::count_internal()
195 int c_op= uint4korr(cur_func);
196 op_type next_func= (op_type) (c_op & op_any);
197 int mask= (c_op & op_not) ? 1:0;
198 int n_ops= c_op & ~op_any;
201 cur_func+= function_buffer_item_size;
202 if (next_func == op_shape)
203 return i_states[c_op & ~(op_any | op_not)] ^ mask;
205 result= count_internal();
209 int next_res= count_internal();
213 result= result | next_res;
215 case op_intersection:
216 result= result & next_res;
218 case op_symdifference:
219 result= result ^ next_res;
222 result= result & !next_res;
224 case op_backdifference:
225 result= !result & next_res;
232 return result ^ mask;
240 void Gcalc_function::reset()
243 shapes_buffer.length(0);
244 function_buffer.length(0);
250 while (scan_it.more_points())
254 Gcalc_scan_events ev= scan_it.get_event();
256 if (ev & (scev_point | scev_end | scev_two_ends))
262 gcalc_shape_info si= pit.point()->get_shape();
263 if ((get_shape_kind(si) == Gcalc_function::shape_polygon))
266 invert_state(evpos->get_shape());
268 if (ev == scev_intersection)
271 if ((get_shape_kind(evpos->get_shape()) !=
272 Gcalc_function::shape_polygon) ||
273 (get_shape_kind(evnext->get_shape()) !=
274 Gcalc_function::shape_polygon))
275 invert_state(evnext->get_shape());
288 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::single_point: %g %g", x, y));
290 return m_fn->single_shape_op(Gcalc_function::shape_point, &si) ||
291 int_single_point(si, x, y);
297 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::start_line"));
299 return m_fn->single_shape_op(Gcalc_function::shape_line, &m_si);
305 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::complete_line"));
313 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::start_poly"));
315 return m_fn->single_shape_op(Gcalc_function::shape_polygon, &m_si);
321 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::complete_poly"));
329 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::start_ring"));
337 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::complete_ring"));
346 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::add_point %g %g", x, y));
347 return int_add_point(m_si, x, y);
354 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::start_collection"));
355 if (m_fn->reserve_shape_buffer(n_objects) || m_fn->reserve_op_buffer(1))
357 m_fn->add_operation(Gcalc_function::op_union, n_objects);
364 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::complete_collection"));
374 DBUG_PRINT(
"info", (
"Gcalc_operation_transporter::collection_add_item"));
379 int Gcalc_result_receiver::start_shape(Gcalc_function::shape_type shape)
381 DBUG_ENTER(
"Gcalc_result_receiver::start_shape");
383 if (buffer.reserve(4*2, 512))
386 shape_pos= buffer.length();
387 buffer.length(shape_pos + ((shape == Gcalc_function::shape_point) ? 4:8));
395 int Gcalc_result_receiver::add_point(
double x,
double y)
397 DBUG_ENTER(
"Gcalc_result_receiver::add_point");
398 DBUG_PRINT(
"info", (
"xy=(%g,%g)", x, y));
399 if (n_points && x == prev_x && y == prev_y)
409 shape_area+= prev_x*y - prev_y*x;
411 if (buffer.reserve(8*2, 512))
413 buffer.q_append(prev_x);
414 buffer.q_append(prev_y);
421 int Gcalc_result_receiver::complete_shape()
423 DBUG_ENTER(
"Gcalc_result_receiver::complete_shape");
424 DBUG_PRINT(
"info", (
"n_points=%u", (uint) n_points));
427 buffer.length(shape_pos);
432 if (cur_shape == Gcalc_function::shape_hole ||
433 cur_shape == Gcalc_function::shape_polygon)
439 buffer.length(shape_pos);
442 if (cur_shape != Gcalc_function::shape_point)
444 cur_shape= Gcalc_function::shape_point;
445 buffer.length(buffer.length()-4);
450 DBUG_ASSERT(cur_shape != Gcalc_function::shape_point);
451 if (cur_shape == Gcalc_function::shape_hole ||
452 cur_shape == Gcalc_function::shape_polygon)
454 shape_area+= prev_x*first_y - prev_y*first_x;
456 if (fabs(shape_area) < 1e-8)
458 buffer.length(shape_pos);
461 if (prev_x == first_x && prev_y == first_y)
464 buffer.write_at_position(shape_pos + 4, n_points);
468 buffer.write_at_position(shape_pos+4, n_points);
471 if (buffer.reserve(8*2, 512))
473 buffer.q_append(prev_x);
474 buffer.q_append(prev_y);
477 buffer.write_at_position(shape_pos, (uint32) cur_shape);
481 DBUG_ASSERT(cur_shape != Gcalc_function::shape_hole);
482 common_shapetype= cur_shape;
484 else if (cur_shape == Gcalc_function::shape_hole)
488 else if (!collection_result && (cur_shape != common_shapetype))
490 collection_result=
true;
493 (
"n_shapes=%u cur_shape=%s common_shapetype=%s",
500 int Gcalc_result_receiver::single_point(
double x,
double y)
502 DBUG_PRINT(
"info", (
"single_point xy=(%g,%g)", x, y));
503 return start_shape(Gcalc_function::shape_point) ||
509 int Gcalc_result_receiver::done()
511 DBUG_ENTER(
"Gcalc_result_receiver::done");
516 void Gcalc_result_receiver::reset()
518 DBUG_ENTER(
"Gcalc_result_receiver::reset");
520 collection_result= FALSE;
521 n_shapes= n_holes= 0;
526 int Gcalc_result_receiver::get_result_typeid()
528 DBUG_ENTER(
"Gcalc_result_receiver::get_result_typeid");
532 if (collection_result)
533 DBUG_RETURN(Geometry::wkb_geometrycollection);
534 switch (common_shapetype)
536 case Gcalc_function::shape_polygon:
537 DBUG_RETURN((n_shapes - n_holes == 1) ? Geometry::wkb_polygon :
538 Geometry::wkb_multipolygon);
539 case Gcalc_function::shape_point:
540 DBUG_RETURN((n_shapes == 1) ? Geometry::wkb_point :
541 Geometry::wkb_multipoint);
542 case Gcalc_function::shape_line:
543 DBUG_RETURN((n_shapes == 1) ? Geometry::wkb_linestring :
544 Geometry::wkb_multilinestring);
552 Gcalc_operation_reducer::Gcalc_operation_reducer(
size_t blk_size) :
555 m_first_active_thread(NULL)
558 DBUG_ASSERT(
sizeof(res_point) >=
sizeof(active_thread));
564 DBUG_ENTER(
"Gcalc_result_receiver::init");
567 m_first_active_thread= NULL;
572 Gcalc_operation_reducer::
577 DBUG_ENTER(
"Gcalc_operation_reducer::Gcalc_operation_reducer");
583 inline int Gcalc_operation_reducer::continue_range(active_thread *t,
586 DBUG_ENTER(
"Gcalc_operation_reducer::continue_range");
587 DBUG_ASSERT(t->result_range);
588 res_point *rp= add_res_point(p);
599 inline int Gcalc_operation_reducer::continue_i_range(active_thread *t,
603 DBUG_ENTER(
"Gcalc_operation_reducer::continue_i_range");
604 DBUG_ASSERT(t->result_range);
605 res_point *rp= add_res_i_point(p, x, y);
615 inline int Gcalc_operation_reducer::start_range(active_thread *t,
618 DBUG_ENTER(
"Gcalc_operation_reducer::start_range");
619 res_point *rp= add_res_point(p);
622 rp->glue= rp->down= NULL;
628 inline int Gcalc_operation_reducer::start_i_range(active_thread *t,
632 DBUG_ENTER(
"Gcalc_operation_reducer::start_i_range");
633 res_point *rp= add_res_i_point(p, x, y);
636 rp->glue= rp->down= NULL;
642 inline int Gcalc_operation_reducer::end_range(active_thread *t,
645 DBUG_ENTER(
"Gcalc_operation_reducer::end_range");
646 res_point *rp= add_res_point(p);
649 rp->glue= rp->up= NULL;
656 inline int Gcalc_operation_reducer::end_i_range(active_thread *t,
660 DBUG_ENTER(
"Gcalc_operation_reducer::end_i_range");
661 res_point *rp= add_res_i_point(p, x, y);
664 rp->glue= rp->up= NULL;
671 int Gcalc_operation_reducer::start_couple(active_thread *t0, active_thread *t1,
673 const active_thread *prev_range)
675 DBUG_ENTER(
"Gcalc_operation_reducer::start_couple");
676 res_point *rp0, *rp1;
677 if (!(rp0= add_res_point(p)) || !(rp1= add_res_point(p)))
681 rp0->down= rp1->down= NULL;
686 rp0->set_outer_poly(prev_range->thread_start());
687 t1->set_thread_start(prev_range->thread_start());
691 rp0->set_outer_poly(NULL);
692 t0->set_thread_start(rp0);
697 int Gcalc_operation_reducer::start_i_couple(active_thread *t0, active_thread *t1,
701 const active_thread *prev_range)
703 DBUG_ENTER(
"Gcalc_operation_reducer::start_i_couple");
704 res_point *rp0, *rp1;
705 if (!(rp0= add_res_i_point(p0, x, y)) || !(rp1= add_res_i_point(p1, x, y)))
709 rp0->down= rp1->down= NULL;
710 t0->result_range= t1->result_range= 1;
715 rp0->set_outer_poly(prev_range->thread_start());
716 t1->set_thread_start(prev_range->thread_start());
720 rp0->set_outer_poly(NULL);
721 t0->set_thread_start(rp0);
726 int Gcalc_operation_reducer::end_couple(active_thread *t0, active_thread *t1,
729 DBUG_ENTER(
"Gcalc_operation_reducer::end_couple");
730 res_point *rp0, *rp1;
731 DBUG_ASSERT(t1->result_range);
732 if (!(rp0= add_res_point(p)) || !(rp1= add_res_point(p)))
738 rp0->up= rp1->up= NULL;
741 t0->result_range= t1->result_range= 0;
745 int Gcalc_operation_reducer::end_i_couple(active_thread *t0, active_thread *t1,
750 DBUG_ENTER(
"Gcalc_operation_reducer::end_i_couple");
751 res_point *rp0, *rp1;
752 if (!(rp0= add_res_i_point(p0, x, y)) || !(rp1= add_res_i_point(p1, x, y)))
758 rp0->up= rp1->up= NULL;
759 t0->result_range= t1->result_range= 0;
767 DBUG_ENTER(
"Gcalc_operation_reducer::add_single_point");
768 res_point *rp= add_res_single_point(p);
771 rp->glue= rp->up= rp->down= NULL;
778 DBUG_ENTER(
"Gcalc_operation_reducer::add_i_single_point");
779 res_point *rp= add_res_i_point(p, x, y);
782 rp->glue= rp->up= rp->down= NULL;
786 int Gcalc_operation_reducer::
787 handle_lines_intersection(active_thread *t0, active_thread *t1,
791 DBUG_ENTER(
"Gcalc_operation_reducer::handle_lines_intersection");
792 DBUG_PRINT(
"info", (
"p=(%g,%g,#%u) p1=(%g,%g,#%u) xy=(%g,%g)",
793 p0->x, p0->y, p0->shape, p1->x, p1->y, p1->shape, x, y));
794 m_fn->invert_state(p0->shape);
795 m_fn->invert_state(p1->shape);
796 int intersection_state= m_fn->count();
797 if ((t0->result_range | t1->result_range) == intersection_state)
800 if (t0->result_range &&
801 (end_i_range(t0, p1, x, y) || start_i_range(t0, p1, x, y)))
804 if (t1->result_range &&
805 (end_i_range(t1, p0, x, y) || start_i_range(t1, p0, x, y)))
808 if (intersection_state &&
809 add_i_single_point(p0, x, y))
815 inline int Gcalc_operation_reducer::
816 handle_line_polygon_intersection(active_thread *l,
const Gcalc_heap::Info *pl,
817 int line_state,
int poly_state,
820 DBUG_ENTER(
"Gcalc_operation_reducer::handle_line_polygon_intersection");
821 DBUG_PRINT(
"info", (
"p=(%g,%g,#%u) xy=(%g,%g)",
822 pl->x, pl->y, pl->shape, x, y));
823 int range_after= ~poly_state & line_state;
824 if (l->result_range == range_after)
826 DBUG_RETURN(range_after ? start_i_range(l, pl, x, y) :
827 end_i_range(l, pl, x, y));
839 inline int Gcalc_operation_reducer::
840 handle_polygons_intersection(active_thread *t0, active_thread *t1,
844 int prev_state,
double x,
double y,
845 const active_thread *prev_range)
847 DBUG_ENTER(
"Gcalc_operation_reducer::handle_polygons_intersection");
848 DBUG_PRINT(
"info", (
"p0=(%g,%g,#%u) p1=(%g,%g,#%u) xy=(%g,%g)",
849 p0->x, p0->y, p0->shape, p1->x, p1->y, p1->shape, x, y));
850 m_fn->invert_state(p0->shape);
851 int state_11= m_fn->count();
852 m_fn->invert_state(p1->shape);
853 int state_2= m_fn->count();
854 int state_01= prev_state ^ t0->result_range;
855 if ((prev_state == state_01) && (prev_state == state_2))
857 if (state_11 == prev_state)
859 switch_athreads(t0, t1, t_hook);
862 DBUG_RETURN(start_i_couple(t0, t1, p0, p1, x, y, prev_range));
864 if (prev_state == state_2)
866 if (state_01 == state_11)
868 if (m_mode & polygon_selfintersections_allowed)
870 switch_athreads(t0, t1, t_hook);
873 if (prev_state != (m_mode & prefer_big_with_holes))
874 DBUG_RETURN(continue_i_range(t0, p0, x, y) ||
875 continue_i_range(t1, p1, x, y));
876 DBUG_RETURN(end_i_couple(t0, t1, p0, p1, x, y) ||
877 start_i_couple(t0, t1, p0, p1, x, y, prev_range));
880 DBUG_RETURN(end_i_couple(t0, t1, p0, p1, x, y));
882 if (state_01 ^ state_11)
884 switch_athreads(t0, t1, t_hook);
888 active_thread *thread_to_continue;
890 if (prev_state == state_01)
892 thread_to_continue= t1;
897 thread_to_continue= t0;
900 DBUG_RETURN(continue_i_range(thread_to_continue, way_to_go, x, y));
905 DBUG_ENTER(
"Gcalc_operation_reducer::count_slice");
907 active_thread *cur_t= m_first_active_thread;
909 const active_thread *prev_range;
912 if (si->get_event() & (scev_point | scev_end | scev_two_ends))
914 for (; pi.point() != si->get_event_position(); ++pi, cur_t= cur_t->get_next())
915 at_hook= &cur_t->next;
921 DBUG_PRINT(
"Gcalc_operation_reducer", (
"event=scev_point"));
922 if (cur_t->result_range &&
923 continue_range(cur_t, pi.get_pi()))
929 DBUG_PRINT(
"Gcalc_operation_reducer", (
"event=scev_end"));
930 if (cur_t->result_range &&
931 end_range(cur_t, pi.get_pi()))
933 *at_hook= cur_t->next;
939 DBUG_PRINT(
"Gcalc_operation_reducer", (
"event=scev_two_ends"));
940 active_thread *cur_t1= cur_t->get_next();
941 if (cur_t->result_range &&
942 end_couple(cur_t, cur_t1, pi.get_pi()))
945 *at_hook= cur_t1->next;
946 free_list(cur_t, &cur_t1->next);
959 for (; pi.point() != si->get_event_position(); ++pi, cur_t= cur_t->get_next())
961 if (m_fn->get_shape_kind(pi.get_shape()) == Gcalc_function::shape_polygon)
963 m_fn->invert_state(pi.get_shape());
964 prev_state^= cur_t->result_range;
966 at_hook= &cur_t->next;
967 if (cur_t->result_range)
968 prev_range= prev_state ? cur_t : 0;
971 switch (si->get_event())
975 DBUG_PRINT(
"info", (
"event=scev_thread"));
976 active_thread *new_t= new_active_thread();
979 m_fn->invert_state(pi.get_shape());
980 new_t->result_range= prev_state ^ m_fn->count();
981 new_t->next= *at_hook;
983 if (new_t->result_range &&
984 start_range(new_t, pi.get_pi()))
988 case scev_two_threads:
990 DBUG_PRINT(
"info", (
"event=scev_two_threads"));
991 active_thread *new_t0, *new_t1;
993 if (!(new_t0= new_active_thread()) || !(new_t1= new_active_thread()))
996 m_fn->invert_state(pi.get_shape());
997 fn_result= m_fn->count();
998 new_t0->result_range= new_t1->result_range= prev_state ^ fn_result;
999 new_t1->next= *at_hook;
1000 new_t0->next= new_t1;
1002 if (new_t0->result_range &&
1003 start_couple(new_t0, new_t1, pi.get_pi(), prev_range))
1007 case scev_intersection:
1009 DBUG_PRINT(
"info", (
"event=scev_intersection"));
1010 active_thread *cur_t1= cur_t->get_next();
1015 bool line0= m_fn->get_shape_kind(p0->shape) == Gcalc_function::shape_line;
1016 bool line1= m_fn->get_shape_kind(p1->shape) == Gcalc_function::shape_line;
1018 if (!line0 && !line1)
1020 if (handle_polygons_intersection(cur_t, cur_t1, at_hook, p0, p1,
1021 prev_state, pi.get_x(), si->get_y(),
1025 else if (line0 && line1)
1028 handle_lines_intersection(cur_t, cur_t1,
1029 p0, p1, pi.get_x(), si->get_y()))
1031 switch_athreads(cur_t, cur_t1, at_hook);
1038 active_thread *line_t;
1039 m_fn->invert_state(p0->shape);
1042 line_state= m_fn->count();
1043 poly_state= prev_state;
1049 poly_state= m_fn->count();
1050 m_fn->invert_state(p1->shape);
1051 line_state= m_fn->count();
1055 if (handle_line_polygon_intersection(line_t, line,
1056 line_state, poly_state,
1057 pi.get_x(), si->get_y()))
1059 switch_athreads(cur_t, cur_t1, at_hook);
1063 case scev_single_point:
1065 DBUG_PRINT(
"info", (
"event=scev_single_point"));
1066 m_fn->invert_state(pi.get_shape());
1067 if ((prev_state ^ m_fn->count()) &&
1068 add_single_point(pi.get_pi()))
1079 int Gcalc_operation_reducer::count_all(
Gcalc_heap *hp)
1081 DBUG_ENTER(
"Gcalc_operation_reducer::count_all");
1084 while (si.more_points())
1088 if (count_slice(&si))
1094 inline void Gcalc_operation_reducer::free_result(res_point *res)
1096 DBUG_ENTER(
"Gcalc_result_receiver::free_result");
1097 if ((*res->prev_hook= res->next))
1099 res->get_next()->prev_hook= res->prev_hook;
1106 inline int Gcalc_operation_reducer::get_single_result(res_point *res,
1109 DBUG_ENTER(
"Gcalc_operation_reducer::get_single_result");
1110 if (res->intersection_point)
1112 if (storage->single_point(float_to_coord(res->x),
1113 float_to_coord(res->y)))
1117 if (storage->single_point(res->x, res->y))
1124 int Gcalc_operation_reducer::get_result_thread(res_point *cur,
1128 DBUG_ENTER(
"Gcalc_operation_reducer::get_result_thread");
1130 bool glue_step=
false;
1131 res_point *first_poly_node= cur;
1137 if (cur->intersection_point)
1139 x= float_to_coord(cur->x);
1140 y= float_to_coord(cur->y);
1147 if (storage->add_point(x, y))
1151 next= move_upward ? cur->up : cur->down;
1152 if (!next && !glue_step)
1163 cur->first_poly_node= first_poly_node;
1171 int Gcalc_operation_reducer::get_polygon_result(res_point *cur,
1174 DBUG_ENTER(
"Gcalc_operation_reducer::get_polygon_result");
1175 res_point *glue= cur->glue;
1176 glue->up->down= NULL;
1178 DBUG_RETURN(get_result_thread(cur, storage, 1) ||
1179 storage->complete_shape());
1183 int Gcalc_operation_reducer::get_line_result(res_point *cur,
1186 DBUG_ENTER(
"Gcalc_operation_reducer::get_line_result");
1197 next= move_upward ? next->up : next->down;
1206 DBUG_RETURN(get_result_thread(cur, storage, move_upward) ||
1207 storage->complete_shape());
1214 if (a1->first_point != a2->first_point)
1215 return a1->first_point < a2->first_point ? -1 : 1;
1216 if (a1->is_poly_hole != a2->is_poly_hole)
1217 return a1->is_poly_hole < a2->is_poly_hole ? -1 : 1;
1218 return (
int) a1->order - (int) a2->order;
1223 void Gcalc_result_receiver::chunk_info::dbug_print()
const
1225 DBUG_PRINT(
"info", (
"first_point=%p order=%d position=%d length=%d",
1226 first_point, (
int) order, (
int) position, (
int) length));
1234 int Gcalc_result_receiver::reorder_chunks(chunk_info *chunks,
int nchunks)
1236 DBUG_ENTER(
"Gcalc_result_receiver::sort_polygon_rings");
1239 uint32 reserve_length= buffer.length();
1240 if (tmp.reserve(reserve_length, MY_ALIGN(reserve_length, 512)))
1244 for (chunk_info *chunk= chunks, *end= chunks + nchunks; chunk < end; chunk++)
1247 chunk->dbug_print();
1249 tmp.append(buffer.ptr() + chunk->position, (size_t) chunk->length);
1252 DBUG_ASSERT(tmp.length() == buffer.length());
1261 DBUG_ENTER(
"Gcalc_operation_reducer::get_result");
1263 bool polygons_found=
false;
1268 Gcalc_function::shape_type shape;
1271 chunk.first_point= m_result;
1272 chunk.order= chunks.elements();
1273 chunk.position= storage->position();
1274 chunk.is_poly_hole=
false;
1278 if (get_single_result(m_result, storage))
1283 shape= m_fn->get_shape_kind(m_result->pi->shape);
1284 if (shape == Gcalc_function::shape_polygon)
1286 polygons_found=
true;
1287 if (m_result->get_outer_poly())
1289 chunk.first_point= m_result->get_outer_poly();
1290 chunk.is_poly_hole=
true;
1291 shape= Gcalc_function::shape_hole;
1293 storage->start_shape(shape);
1294 if (get_polygon_result(m_result, storage))
1296 chunk.first_point= ((res_point*) chunk.first_point)->first_poly_node;
1300 storage->start_shape(shape);
1301 if (get_line_result(m_result, storage))
1306 chunk.length= storage->position() - chunk.position;
1314 if (polygons_found && chunks.elements() > 1)
1316 chunks.sort(chunk_info_cmp);
1317 if (storage->reorder_chunks(chunks.
front(), chunks.elements()))
1327 void Gcalc_operation_reducer::reset()
1329 DBUG_ENTER(
"Gcalc_operation_reducer::reset");
1330 free_list(m_result, m_res_hook);
1332 free_list(m_first_active_thread);