16 #include "myisamdef.h"
18 #ifdef HAVE_RTREE_KEYS
23 #define INTERSECT_CMP(amin, amax, bmin, bmax) ((amin > bmax) || (bmin > amax))
24 #define CONTAIN_CMP(amin, amax, bmin, bmax) ((bmin > amin) || (bmax < amax))
25 #define WITHIN_CMP(amin, amax, bmin, bmax) ((amin > bmin) || (amax < bmax))
26 #define DISJOINT_CMP(amin, amax, bmin, bmax) ((amin <= bmax) && (bmin <= amax))
27 #define EQUAL_CMP(amin, amax, bmin, bmax) ((amin != bmin) || (amax != bmax))
29 #define FCMP(A, B) ((int)(A) - (int)(B))
30 #define p_inc(A, B, X) {A += X; B += X;}
32 #define RT_CMP(nextflag) \
33 if (nextflag & MBR_INTERSECT) \
35 if (INTERSECT_CMP(amin, amax, bmin, bmax)) \
38 else if (nextflag & MBR_CONTAIN) \
40 if (CONTAIN_CMP(amin, amax, bmin, bmax)) \
43 else if (nextflag & MBR_WITHIN) \
45 if (WITHIN_CMP(amin, amax, bmin, bmax)) \
48 else if (nextflag & MBR_EQUAL) \
50 if (EQUAL_CMP(amin, amax, bmin, bmax)) \
53 else if (nextflag & MBR_DISJOINT) \
55 if (DISJOINT_CMP(amin, amax, bmin, bmax)) \
63 #define RT_CMP_KORR(type, korr_func, len, nextflag) \
65 type amin, amax, bmin, bmax; \
66 amin = korr_func(a); \
67 bmin = korr_func(b); \
68 amax = korr_func(a+len); \
69 bmax = korr_func(b+len); \
73 #define RT_CMP_GET(type, get_func, len, nextflag) \
75 type amin, amax, bmin, bmax; \
78 get_func(amax, a+len); \
79 get_func(bmax, b+len); \
94 int rtree_key_cmp(
HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length,
97 for (; (int) key_length > 0; keyseg += 2 )
100 switch ((
enum ha_base_keytype) keyseg->type) {
101 case HA_KEYTYPE_INT8:
102 RT_CMP_KORR(int8, mi_sint1korr, 1, nextflag);
104 case HA_KEYTYPE_BINARY:
105 RT_CMP_KORR(uint8, mi_uint1korr, 1, nextflag);
107 case HA_KEYTYPE_SHORT_INT:
108 RT_CMP_KORR(int16, mi_sint2korr, 2, nextflag);
110 case HA_KEYTYPE_USHORT_INT:
111 RT_CMP_KORR(uint16, mi_uint2korr, 2, nextflag);
113 case HA_KEYTYPE_INT24:
114 RT_CMP_KORR(int32, mi_sint3korr, 3, nextflag);
116 case HA_KEYTYPE_UINT24:
117 RT_CMP_KORR(uint32, mi_uint3korr, 3, nextflag);
119 case HA_KEYTYPE_LONG_INT:
120 RT_CMP_KORR(int32, mi_sint4korr, 4, nextflag);
122 case HA_KEYTYPE_ULONG_INT:
123 RT_CMP_KORR(uint32, mi_uint4korr, 4, nextflag);
125 #ifdef HAVE_LONG_LONG
126 case HA_KEYTYPE_LONGLONG:
127 RT_CMP_KORR(longlong, mi_sint8korr, 8, nextflag)
129 case HA_KEYTYPE_ULONGLONG:
130 RT_CMP_KORR(ulonglong, mi_uint8korr, 8, nextflag)
133 case HA_KEYTYPE_FLOAT:
135 RT_CMP_GET(
float, mi_float4get, 4, nextflag);
137 case HA_KEYTYPE_DOUBLE:
138 RT_CMP_GET(
double, mi_float8get, 8, nextflag);
145 keyseg_length= keyseg->length * 2;
146 key_length-= keyseg_length;
152 if (nextflag & MBR_DATA)
154 uchar *end = a + keyseg->length;
158 return FCMP(a[-1], b[-1]);
164 #define RT_VOL_KORR(type, korr_func, len, cast) \
167 amin = korr_func(a); \
168 amax = korr_func(a+len); \
169 res *= (cast(amax) - cast(amin)); \
172 #define RT_VOL_GET(type, get_func, len, cast) \
176 get_func(amax, a+len); \
177 res *= (cast(amax) - cast(amin)); \
183 double rtree_rect_volume(
HA_KEYSEG *keyseg, uchar *a, uint key_length)
186 for (; (int)key_length > 0; keyseg += 2)
188 uint32 keyseg_length;
189 switch ((
enum ha_base_keytype) keyseg->type) {
190 case HA_KEYTYPE_INT8:
191 RT_VOL_KORR(int8, mi_sint1korr, 1, (
double));
193 case HA_KEYTYPE_BINARY:
194 RT_VOL_KORR(uint8, mi_uint1korr, 1, (
double));
196 case HA_KEYTYPE_SHORT_INT:
197 RT_VOL_KORR(int16, mi_sint2korr, 2, (
double));
199 case HA_KEYTYPE_USHORT_INT:
200 RT_VOL_KORR(uint16, mi_uint2korr, 2, (
double));
202 case HA_KEYTYPE_INT24:
203 RT_VOL_KORR(int32, mi_sint3korr, 3, (
double));
205 case HA_KEYTYPE_UINT24:
206 RT_VOL_KORR(uint32, mi_uint3korr, 3, (
double));
208 case HA_KEYTYPE_LONG_INT:
209 RT_VOL_KORR(int32, mi_sint4korr, 4, (
double));
211 case HA_KEYTYPE_ULONG_INT:
212 RT_VOL_KORR(uint32, mi_uint4korr, 4, (
double));
214 #ifdef HAVE_LONG_LONG
215 case HA_KEYTYPE_LONGLONG:
216 RT_VOL_KORR(longlong, mi_sint8korr, 8, (
double));
218 case HA_KEYTYPE_ULONGLONG:
219 RT_VOL_KORR(longlong, mi_sint8korr, 8, ulonglong2double);
222 case HA_KEYTYPE_FLOAT:
223 RT_VOL_GET(
float, mi_float4get, 4, (
double));
225 case HA_KEYTYPE_DOUBLE:
226 RT_VOL_GET(
double, mi_float8get, 8, (
double));
234 keyseg_length= keyseg->length * 2;
235 key_length-= keyseg_length;
241 #define RT_D_MBR_KORR(type, korr_func, len, cast) \
244 amin = korr_func(a); \
245 amax = korr_func(a+len); \
246 *res++ = cast(amin); \
247 *res++ = cast(amax); \
250 #define RT_D_MBR_GET(type, get_func, len, cast) \
254 get_func(amax, a+len); \
255 *res++ = cast(amin); \
256 *res++ = cast(amax); \
264 int rtree_d_mbr(
HA_KEYSEG *keyseg, uchar *a, uint key_length,
double *res)
266 for (; (int)key_length > 0; keyseg += 2)
268 uint32 keyseg_length;
269 switch ((
enum ha_base_keytype) keyseg->type) {
270 case HA_KEYTYPE_INT8:
271 RT_D_MBR_KORR(int8, mi_sint1korr, 1, (
double));
273 case HA_KEYTYPE_BINARY:
274 RT_D_MBR_KORR(uint8, mi_uint1korr, 1, (
double));
276 case HA_KEYTYPE_SHORT_INT:
277 RT_D_MBR_KORR(int16, mi_sint2korr, 2, (
double));
279 case HA_KEYTYPE_USHORT_INT:
280 RT_D_MBR_KORR(uint16, mi_uint2korr, 2, (
double));
282 case HA_KEYTYPE_INT24:
283 RT_D_MBR_KORR(int32, mi_sint3korr, 3, (
double));
285 case HA_KEYTYPE_UINT24:
286 RT_D_MBR_KORR(uint32, mi_uint3korr, 3, (
double));
288 case HA_KEYTYPE_LONG_INT:
289 RT_D_MBR_KORR(int32, mi_sint4korr, 4, (
double));
291 case HA_KEYTYPE_ULONG_INT:
292 RT_D_MBR_KORR(uint32, mi_uint4korr, 4, (
double));
294 #ifdef HAVE_LONG_LONG
295 case HA_KEYTYPE_LONGLONG:
296 RT_D_MBR_KORR(longlong, mi_sint8korr, 8, (
double));
298 case HA_KEYTYPE_ULONGLONG:
299 RT_D_MBR_KORR(longlong, mi_sint8korr, 8, ulonglong2double);
302 case HA_KEYTYPE_FLOAT:
303 RT_D_MBR_GET(
float, mi_float4get, 4, (
double));
305 case HA_KEYTYPE_DOUBLE:
306 RT_D_MBR_GET(
double, mi_float8get, 8, (
double));
314 keyseg_length= keyseg->length * 2;
315 key_length-= keyseg_length;
321 #define RT_COMB_KORR(type, korr_func, store_func, len) \
323 type amin, amax, bmin, bmax; \
324 amin = korr_func(a); \
325 bmin = korr_func(b); \
326 amax = korr_func(a+len); \
327 bmax = korr_func(b+len); \
328 amin = MY_MIN(amin, bmin); \
329 amax = MY_MAX(amax, bmax); \
330 store_func(c, amin); \
331 store_func(c+len, amax); \
334 #define RT_COMB_GET(type, get_func, store_func, len) \
336 type amin, amax, bmin, bmax; \
339 get_func(amax, a+len); \
340 get_func(bmax, b+len); \
341 amin = MY_MIN(amin, bmin); \
342 amax = MY_MAX(amax, bmax); \
343 store_func(c, amin); \
344 store_func(c+len, amax); \
353 int rtree_combine_rect(
HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
356 for ( ; (int) key_length > 0 ; keyseg += 2)
358 uint32 keyseg_length;
359 switch ((
enum ha_base_keytype) keyseg->type) {
360 case HA_KEYTYPE_INT8:
361 RT_COMB_KORR(int8, mi_sint1korr, mi_int1store, 1);
363 case HA_KEYTYPE_BINARY:
364 RT_COMB_KORR(uint8, mi_uint1korr, mi_int1store, 1);
366 case HA_KEYTYPE_SHORT_INT:
367 RT_COMB_KORR(int16, mi_sint2korr, mi_int2store, 2);
369 case HA_KEYTYPE_USHORT_INT:
370 RT_COMB_KORR(uint16, mi_uint2korr, mi_int2store, 2);
372 case HA_KEYTYPE_INT24:
373 RT_COMB_KORR(int32, mi_sint3korr, mi_int3store, 3);
375 case HA_KEYTYPE_UINT24:
376 RT_COMB_KORR(uint32, mi_uint3korr, mi_int3store, 3);
378 case HA_KEYTYPE_LONG_INT:
379 RT_COMB_KORR(int32, mi_sint4korr, mi_int4store, 4);
381 case HA_KEYTYPE_ULONG_INT:
382 RT_COMB_KORR(uint32, mi_uint4korr, mi_int4store, 4);
384 #ifdef HAVE_LONG_LONG
385 case HA_KEYTYPE_LONGLONG:
386 RT_COMB_KORR(longlong, mi_sint8korr, mi_int8store, 8);
388 case HA_KEYTYPE_ULONGLONG:
389 RT_COMB_KORR(ulonglong, mi_uint8korr, mi_int8store, 8);
392 case HA_KEYTYPE_FLOAT:
393 RT_COMB_GET(
float, mi_float4get, mi_float4store, 4);
395 case HA_KEYTYPE_DOUBLE:
396 RT_COMB_GET(
double, mi_float8get, mi_float8store, 8);
403 keyseg_length= keyseg->length * 2;
404 key_length-= keyseg_length;
413 #define RT_OVL_AREA_KORR(type, korr_func, len) \
415 type amin, amax, bmin, bmax; \
416 amin = korr_func(a); \
417 bmin = korr_func(b); \
418 amax = korr_func(a+len); \
419 bmax = korr_func(b+len); \
420 amin = MY_MAX(amin, bmin); \
421 amax = MY_MIN(amax, bmax); \
424 res *= amax - amin; \
427 #define RT_OVL_AREA_GET(type, get_func, len) \
429 type amin, amax, bmin, bmax; \
432 get_func(amax, a+len); \
433 get_func(bmax, b+len); \
434 amin = MY_MAX(amin, bmin); \
435 amax = MY_MIN(amax, bmax); \
438 res *= amax - amin; \
444 double rtree_overlapping_area(
HA_KEYSEG *keyseg, uchar* a, uchar* b,
448 for (; (int) key_length > 0 ; keyseg += 2)
450 uint32 keyseg_length;
451 switch ((
enum ha_base_keytype) keyseg->type) {
452 case HA_KEYTYPE_INT8:
453 RT_OVL_AREA_KORR(int8, mi_sint1korr, 1);
455 case HA_KEYTYPE_BINARY:
456 RT_OVL_AREA_KORR(uint8, mi_uint1korr, 1);
458 case HA_KEYTYPE_SHORT_INT:
459 RT_OVL_AREA_KORR(int16, mi_sint2korr, 2);
461 case HA_KEYTYPE_USHORT_INT:
462 RT_OVL_AREA_KORR(uint16, mi_uint2korr, 2);
464 case HA_KEYTYPE_INT24:
465 RT_OVL_AREA_KORR(int32, mi_sint3korr, 3);
467 case HA_KEYTYPE_UINT24:
468 RT_OVL_AREA_KORR(uint32, mi_uint3korr, 3);
470 case HA_KEYTYPE_LONG_INT:
471 RT_OVL_AREA_KORR(int32, mi_sint4korr, 4);
473 case HA_KEYTYPE_ULONG_INT:
474 RT_OVL_AREA_KORR(uint32, mi_uint4korr, 4);
476 #ifdef HAVE_LONG_LONG
477 case HA_KEYTYPE_LONGLONG:
478 RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8);
480 case HA_KEYTYPE_ULONGLONG:
481 RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8);
484 case HA_KEYTYPE_FLOAT:
485 RT_OVL_AREA_GET(
float, mi_float4get, 4);
487 case HA_KEYTYPE_DOUBLE:
488 RT_OVL_AREA_GET(
double, mi_float8get, 8);
495 keyseg_length= keyseg->length * 2;
496 key_length-= keyseg_length;
503 #define RT_AREA_INC_KORR(type, korr_func, len) \
505 type amin, amax, bmin, bmax; \
506 amin = korr_func(a); \
507 bmin = korr_func(b); \
508 amax = korr_func(a+len); \
509 bmax = korr_func(b+len); \
510 a_area *= (((double)amax) - ((double)amin)); \
511 loc_ab_area *= ((double)MY_MAX(amax, bmax) - (double)MY_MIN(amin, bmin)); \
514 #define RT_AREA_INC_GET(type, get_func, len)\
516 type amin, amax, bmin, bmax; \
519 get_func(amax, a+len); \
520 get_func(bmax, b+len); \
521 a_area *= (((double)amax) - ((double)amin)); \
522 loc_ab_area *= ((double)MY_MAX(amax, bmax) - (double)MY_MIN(amin, bmin)); \
531 double rtree_area_increase(
HA_KEYSEG *keyseg, uchar* a, uchar* b,
532 uint key_length,
double *ab_area)
535 double loc_ab_area= 1.0;
538 for (; (int)key_length > 0; keyseg += 2)
540 uint32 keyseg_length;
542 if (keyseg->null_bit)
545 switch ((
enum ha_base_keytype) keyseg->type) {
546 case HA_KEYTYPE_INT8:
547 RT_AREA_INC_KORR(int8, mi_sint1korr, 1);
549 case HA_KEYTYPE_BINARY:
550 RT_AREA_INC_KORR(uint8, mi_uint1korr, 1);
552 case HA_KEYTYPE_SHORT_INT:
553 RT_AREA_INC_KORR(int16, mi_sint2korr, 2);
555 case HA_KEYTYPE_USHORT_INT:
556 RT_AREA_INC_KORR(uint16, mi_uint2korr, 2);
558 case HA_KEYTYPE_INT24:
559 RT_AREA_INC_KORR(int32, mi_sint3korr, 3);
561 case HA_KEYTYPE_UINT24:
562 RT_AREA_INC_KORR(int32, mi_uint3korr, 3);
564 case HA_KEYTYPE_LONG_INT:
565 RT_AREA_INC_KORR(int32, mi_sint4korr, 4);
567 case HA_KEYTYPE_ULONG_INT:
568 RT_AREA_INC_KORR(uint32, mi_uint4korr, 4);
570 #ifdef HAVE_LONG_LONG
571 case HA_KEYTYPE_LONGLONG:
572 RT_AREA_INC_KORR(longlong, mi_sint8korr, 8);
574 case HA_KEYTYPE_ULONGLONG:
575 RT_AREA_INC_KORR(longlong, mi_sint8korr, 8);
578 case HA_KEYTYPE_FLOAT:
579 RT_AREA_INC_GET(
float, mi_float4get, 4);
581 case HA_KEYTYPE_DOUBLE:
582 RT_AREA_INC_GET(
double, mi_float8get, 8);
589 keyseg_length= keyseg->length * 2;
590 key_length-= keyseg_length;
595 *ab_area= loc_ab_area;
596 return loc_ab_area - a_area;
599 #define RT_PERIM_INC_KORR(type, korr_func, len) \
601 type amin, amax, bmin, bmax; \
602 amin = korr_func(a); \
603 bmin = korr_func(b); \
604 amax = korr_func(a+len); \
605 bmax = korr_func(b+len); \
606 a_perim+= (((double)amax) - ((double)amin)); \
607 *ab_perim+= ((double)MY_MAX(amax, bmax) - (double)MY_MIN(amin, bmin)); \
610 #define RT_PERIM_INC_GET(type, get_func, len)\
612 type amin, amax, bmin, bmax; \
615 get_func(amax, a+len); \
616 get_func(bmax, b+len); \
617 a_perim+= (((double)amax) - ((double)amin)); \
618 *ab_perim+= ((double)MY_MAX(amax, bmax) - (double)MY_MIN(amin, bmin)); \
624 double rtree_perimeter_increase(
HA_KEYSEG *keyseg, uchar* a, uchar* b,
625 uint key_length,
double *ab_perim)
627 double a_perim = 0.0;
630 for (; (int)key_length > 0; keyseg += 2)
632 uint32 keyseg_length;
634 if (keyseg->null_bit)
637 switch ((
enum ha_base_keytype) keyseg->type) {
638 case HA_KEYTYPE_INT8:
639 RT_PERIM_INC_KORR(int8, mi_sint1korr, 1);
641 case HA_KEYTYPE_BINARY:
642 RT_PERIM_INC_KORR(uint8, mi_uint1korr, 1);
644 case HA_KEYTYPE_SHORT_INT:
645 RT_PERIM_INC_KORR(int16, mi_sint2korr, 2);
647 case HA_KEYTYPE_USHORT_INT:
648 RT_PERIM_INC_KORR(uint16, mi_uint2korr, 2);
650 case HA_KEYTYPE_INT24:
651 RT_PERIM_INC_KORR(int32, mi_sint3korr, 3);
653 case HA_KEYTYPE_UINT24:
654 RT_PERIM_INC_KORR(int32, mi_uint3korr, 3);
656 case HA_KEYTYPE_LONG_INT:
657 RT_PERIM_INC_KORR(int32, mi_sint4korr, 4);
659 case HA_KEYTYPE_ULONG_INT:
660 RT_PERIM_INC_KORR(uint32, mi_uint4korr, 4);
662 #ifdef HAVE_LONG_LONG
663 case HA_KEYTYPE_LONGLONG:
664 RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8);
666 case HA_KEYTYPE_ULONGLONG:
667 RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8);
670 case HA_KEYTYPE_FLOAT:
671 RT_PERIM_INC_GET(
float, mi_float4get, 4);
673 case HA_KEYTYPE_DOUBLE:
674 RT_PERIM_INC_GET(
double, mi_float8get, 8);
677 return *ab_perim - a_perim;
681 keyseg_length= keyseg->length * 2;
682 key_length-= keyseg_length;
686 return *ab_perim - a_perim;
690 #define RT_PAGE_MBR_KORR(type, korr_func, store_func, len) \
692 type amin, amax, bmin, bmax; \
693 amin = korr_func(k + inc); \
694 amax = korr_func(k + inc + len); \
695 k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \
696 for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \
698 bmin = korr_func(k + inc); \
699 bmax = korr_func(k + inc + len); \
705 store_func(c, amin); \
707 store_func(c, amax); \
712 #define RT_PAGE_MBR_GET(type, get_func, store_func, len) \
714 type amin, amax, bmin, bmax; \
715 get_func(amin, k + inc); \
716 get_func(amax, k + inc + len); \
717 k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \
718 for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \
720 get_func(bmin, k + inc); \
721 get_func(bmax, k + inc + len); \
727 store_func(c, amin); \
729 store_func(c, amax); \
738 uchar *c, uint key_length)
741 uint k_len = key_length;
742 uint nod_flag = mi_test_if_nod(page_buf);
744 uchar *last = rt_PAGE_END(page_buf);
746 for (; (int)key_length > 0; keyseg += 2)
748 key_length -= keyseg->length * 2;
751 if (keyseg->null_bit)
756 k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
758 switch ((
enum ha_base_keytype) keyseg->type) {
759 case HA_KEYTYPE_INT8:
760 RT_PAGE_MBR_KORR(int8, mi_sint1korr, mi_int1store, 1);
762 case HA_KEYTYPE_BINARY:
763 RT_PAGE_MBR_KORR(uint8, mi_uint1korr, mi_int1store, 1);
765 case HA_KEYTYPE_SHORT_INT:
766 RT_PAGE_MBR_KORR(int16, mi_sint2korr, mi_int2store, 2);
768 case HA_KEYTYPE_USHORT_INT:
769 RT_PAGE_MBR_KORR(uint16, mi_uint2korr, mi_int2store, 2);
771 case HA_KEYTYPE_INT24:
772 RT_PAGE_MBR_KORR(int32, mi_sint3korr, mi_int3store, 3);
774 case HA_KEYTYPE_UINT24:
775 RT_PAGE_MBR_KORR(uint32, mi_uint3korr, mi_int3store, 3);
777 case HA_KEYTYPE_LONG_INT:
778 RT_PAGE_MBR_KORR(int32, mi_sint4korr, mi_int4store, 4);
780 case HA_KEYTYPE_ULONG_INT:
781 RT_PAGE_MBR_KORR(uint32, mi_uint4korr, mi_int4store, 4);
783 #ifdef HAVE_LONG_LONG
784 case HA_KEYTYPE_LONGLONG:
785 RT_PAGE_MBR_KORR(longlong, mi_sint8korr, mi_int8store, 8);
787 case HA_KEYTYPE_ULONGLONG:
788 RT_PAGE_MBR_KORR(ulonglong, mi_uint8korr, mi_int8store, 8);
791 case HA_KEYTYPE_FLOAT:
792 RT_PAGE_MBR_GET(
float, mi_float4get, mi_float4store, 4);
794 case HA_KEYTYPE_DOUBLE:
795 RT_PAGE_MBR_GET(
double, mi_float8get, mi_float8store, 8);