Commit b8cf9f6a authored by hf@deer.(none)'s avatar hf@deer.(none)

Merging

parents 4cb62eb0 7cf1d259
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
better compression better compression
*/ */
/* these two are for uniformity */
#define mi_sint1korr(A) (int8)(*A)
#define mi_uint1korr(A) (uint8)(*A)
#define mi_sint2korr(A) (int16) (((int16) ((uchar) (A)[1])) +\ #define mi_sint2korr(A) (int16) (((int16) ((uchar) (A)[1])) +\
((int16) ((int16) (A)[0]) << 8)) ((int16) ((int16) (A)[0]) << 8))
#define mi_sint3korr(A) ((int32) ((((uchar) (A)[0]) & 128) ? \ #define mi_sint3korr(A) ((int32) ((((uchar) (A)[0]) & 128) ? \
...@@ -75,6 +79,9 @@ ...@@ -75,6 +79,9 @@
(((uint32) ((uchar) (A)[0])) << 24))) <<\ (((uint32) ((uchar) (A)[0])) << 24))) <<\
32)) 32))
/* This one is for uniformity */
#define mi_int1store(T,A) *((uchar*)(T))= (uchar) (A)
#define mi_int2store(T,A) { uint def_temp= (uint) (A) ;\ #define mi_int2store(T,A) { uint def_temp= (uint) (A) ;\
*((uchar*) ((T)+1))= (uchar)(def_temp); \ *((uchar*) ((T)+1))= (uchar)(def_temp); \
*((uchar*) ((T)+0))= (uchar)(def_temp >> 8); } *((uchar*) ((T)+0))= (uchar)(def_temp >> 8); }
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "rt_mbr.h" #include "rt_mbr.h"
#define REINSERT_BUFFER_INC 10 #define REINSERT_BUFFER_INC 10
#define PICK_BY_AREA
/*#define PICK_BY_PERIMETER*/
typedef struct st_page_level typedef struct st_page_level
{ {
...@@ -438,6 +440,84 @@ int rtree_get_next(MI_INFO *info, uint keynr, uint key_length) ...@@ -438,6 +440,84 @@ int rtree_get_next(MI_INFO *info, uint keynr, uint key_length)
} }
/*
Choose non-leaf better key for insertion
*/
#ifdef PICK_BY_PERIMETER
static uchar *rtree_pick_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, uchar *page_buf, uint nod_flag)
{
double increase;
double best_incr = DBL_MAX;
double perimeter;
double best_perimeter;
uchar *best_key;
uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
uchar *last = rt_PAGE_END(page_buf);
LINT_INIT(best_perimeter);
LINT_INIT(best_key);
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
{
if ((increase = rtree_perimeter_increase(keyinfo->seg, k, key, key_length,
&perimeter)) == -1)
return NULL;
if ((increase < best_incr)||
(increase == best_incr && perimeter < best_perimeter))
{
best_key = k;
best_perimeter= perimeter;
best_incr = increase;
}
}
return best_key;
}
#endif /*PICK_BY_PERIMETER*/
#ifdef PICK_BY_AREA
static uchar *rtree_pick_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, uchar *page_buf, uint nod_flag)
{
double increase;
double best_incr = DBL_MAX;
double area;
double best_area;
uchar *best_key;
uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
uchar *last = rt_PAGE_END(page_buf);
LINT_INIT(best_area);
LINT_INIT(best_key);
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
{
if ((increase = rtree_area_increase(keyinfo->seg, k, key, key_length,
&area)) == -1)
return NULL;
if (increase < best_incr)
{
best_key = k;
best_area = area;
best_incr = increase;
}
else
{
if ((increase == best_incr) && (area < best_area))
{
best_key = k;
best_area = area;
best_incr = increase;
}
}
}
return best_key;
}
#endif /*PICK_BY_AREA*/
/* /*
Go down and insert key into tree Go down and insert key into tree
...@@ -469,7 +549,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, ...@@ -469,7 +549,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */ if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */
(ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */ (ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */
{ {
if ((k = rtree_choose_key(info, keyinfo, key, key_length, page_buf, if ((k = rtree_pick_key(info, keyinfo, key, key_length, page_buf,
nod_flag)) == NULL) nod_flag)) == NULL)
goto err1; goto err1;
switch ((res = rtree_insert_req(info, keyinfo, key, key_length, switch ((res = rtree_insert_req(info, keyinfo, key, key_length,
...@@ -579,7 +659,7 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, ...@@ -579,7 +659,7 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
mi_putint(new_root_buf, 2, nod_flag); mi_putint(new_root_buf, 2, nod_flag);
if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
HA_OFFSET_ERROR) HA_OFFSET_ERROR)
goto err1; goto err1;
new_key = new_root_buf + keyinfo->block_length + nod_flag; new_key = new_root_buf + keyinfo->block_length + nod_flag;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
(nod_flag ? nod_flag : info->s->base.rec_reflength)) (nod_flag ? nod_flag : info->s->base.rec_reflength))
#define rt_PAGE_END(page) (page + mi_getint(page)) #define rt_PAGE_END(page) (page + mi_getint(page))
#define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length) / 2) #define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length) / 3)
int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length); int rtree_insert(MI_INFO *info, uint keynr, uchar *key, uint key_length);
int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length); int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length);
......
...@@ -36,7 +36,8 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, ...@@ -36,7 +36,8 @@ int rtree_add_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint page_size = mi_getint(page_buf); uint page_size = mi_getint(page_buf);
uint nod_flag = mi_test_if_nod(page_buf); uint nod_flag = mi_test_if_nod(page_buf);
if (page_size + key_length + nod_flag <= keyinfo->block_length) if (page_size + key_length + info->s->base.rec_reflength <=
keyinfo->block_length)
{ {
/* split won't be necessary */ /* split won't be necessary */
if (nod_flag) if (nod_flag)
...@@ -96,47 +97,4 @@ int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, ...@@ -96,47 +97,4 @@ int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length); return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length);
} }
/*
Choose non-leaf better key for insertion
*/
uchar *rtree_choose_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, uchar *page_buf, uint nod_flag)
{
double increase;
double best_incr = DBL_MAX;
double area;
double best_area;
uchar *best_key;
uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
uchar *last = rt_PAGE_END(page_buf);
LINT_INIT(best_area);
LINT_INIT(best_key);
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
{
if ((increase = rtree_area_increase(keyinfo->seg, key, k, key_length,
&area)) == -1)
return NULL;
if (increase < best_incr)
{
best_key = k;
best_area = area;
best_incr = increase;
}
else
{
if ((increase == best_incr) && (area < best_area))
{
best_key = k;
best_area = area;
best_incr = increase;
}
}
}
return best_key;
}
#endif /*HAVE_RTREE_KEYS*/ #endif /*HAVE_RTREE_KEYS*/
...@@ -28,7 +28,6 @@ int rtree_delete_key(MI_INFO *info, uchar *page, uchar *key, ...@@ -28,7 +28,6 @@ int rtree_delete_key(MI_INFO *info, uchar *page, uchar *key,
uint key_length, uint nod_flag); uint key_length, uint nod_flag);
int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, my_off_t child_page); uint key_length, my_off_t child_page);
uchar *rtree_choose_key(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, uchar *page_buf, uint nod_flag);
#endif /*HAVE_RTREE_KEYS*/ #endif /*HAVE_RTREE_KEYS*/
#endif /* _rt_key_h */ #endif /* _rt_key_h */
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define CONTAIN_CMP(amin, amax, bmin, bmax) ((bmin > amin) || (bmax < amax)) #define CONTAIN_CMP(amin, amax, bmin, bmax) ((bmin > amin) || (bmax < amax))
#define WITHIN_CMP(amin, amax, bmin, bmax) ((amin > bmin) || (amax < bmax)) #define WITHIN_CMP(amin, amax, bmin, bmax) ((amin > bmin) || (amax < bmax))
#define DISJOINT_CMP(amin, amax, bmin, bmax) ((amin <= bmax) && (bmin <= amax)) #define DISJOINT_CMP(amin, amax, bmin, bmax) ((amin <= bmax) && (bmin <= amax))
#define EQUAL_CMP(amix, amax, bmin, bmax) ((amix != bmin) || (amax != bmax)) #define EQUAL_CMP(amin, amax, bmin, bmax) ((amin != bmin) || (amax != bmax))
#define FCMP(A, B) ((int)(A) - (int)(B)) #define FCMP(A, B) ((int)(A) - (int)(B))
#define p_inc(A, B, X) {A += X; B += X;} #define p_inc(A, B, X) {A += X; B += X;}
...@@ -63,12 +63,9 @@ ...@@ -63,12 +63,9 @@
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
amin = korr_func(a); \ amin = korr_func(a); \
bmin = korr_func(b); \ bmin = korr_func(b); \
p_inc(a, b, len); \ amax = korr_func(a+len); \
amax = korr_func(a); \ bmax = korr_func(b+len); \
bmax = korr_func(b); \
RT_CMP(nextflag); \ RT_CMP(nextflag); \
p_inc(a, b, len); \
break; \
} }
#define RT_CMP_GET(type, get_func, len, nextflag) \ #define RT_CMP_GET(type, get_func, len, nextflag) \
...@@ -76,12 +73,9 @@ ...@@ -76,12 +73,9 @@
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
get_func(amin, a); \ get_func(amin, a); \
get_func(bmin, b); \ get_func(bmin, b); \
p_inc(a, b, len); \ get_func(amax, a+len); \
get_func(amax, a); \ get_func(bmax, b+len); \
get_func(bmax, b); \
RT_CMP(nextflag); \ RT_CMP(nextflag); \
p_inc(a, b, len); \
break; \
} }
/* /*
...@@ -100,54 +94,54 @@ int rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length, ...@@ -100,54 +94,54 @@ int rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length,
{ {
for (; (int) key_length > 0; keyseg += 2 ) for (; (int) key_length > 0; keyseg += 2 )
{ {
key_length -= keyseg->length * 2;
switch ((enum ha_base_keytype) keyseg->type) { switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_TEXT: case HA_KEYTYPE_INT8:
RT_CMP_KORR(int8, mi_sint1korr, 1, nextflag);
break;
case HA_KEYTYPE_BINARY: case HA_KEYTYPE_BINARY:
case HA_KEYTYPE_VARTEXT: RT_CMP_KORR(uint8, mi_uint1korr, 1, nextflag);
case HA_KEYTYPE_VARBINARY:
case HA_KEYTYPE_NUM:
default:
return 1;
break; break;
case HA_KEYTYPE_INT8:
{
int amin,amax,bmin,bmax;
amin = (int)*((signed char *)a);
bmin = (int)*((signed char *)b);
p_inc(a, b, 1);
amax = (int)*((signed char *)a);
bmax = (int)*((signed char *)b);
RT_CMP(nextflag);
p_inc(a, b, 1);
break;
}
case HA_KEYTYPE_SHORT_INT: case HA_KEYTYPE_SHORT_INT:
RT_CMP_KORR(int16, mi_sint2korr, 2, nextflag); RT_CMP_KORR(int16, mi_sint2korr, 2, nextflag);
break;
case HA_KEYTYPE_USHORT_INT: case HA_KEYTYPE_USHORT_INT:
RT_CMP_KORR(uint16, mi_uint2korr, 2, nextflag); RT_CMP_KORR(uint16, mi_uint2korr, 2, nextflag);
break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
RT_CMP_KORR(int32, mi_sint3korr, 3, nextflag); RT_CMP_KORR(int32, mi_sint3korr, 3, nextflag);
break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
RT_CMP_KORR(uint32, mi_uint3korr, 3, nextflag); RT_CMP_KORR(uint32, mi_uint3korr, 3, nextflag);
break;
case HA_KEYTYPE_LONG_INT: case HA_KEYTYPE_LONG_INT:
RT_CMP_KORR(int32, mi_sint4korr, 4, nextflag); RT_CMP_KORR(int32, mi_sint4korr, 4, nextflag);
break;
case HA_KEYTYPE_ULONG_INT: case HA_KEYTYPE_ULONG_INT:
RT_CMP_KORR(uint32, mi_uint4korr, 4, nextflag); RT_CMP_KORR(uint32, mi_uint4korr, 4, nextflag);
break;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case HA_KEYTYPE_LONGLONG: case HA_KEYTYPE_LONGLONG:
RT_CMP_KORR(longlong, mi_sint8korr, 8, nextflag) RT_CMP_KORR(longlong, mi_sint8korr, 8, nextflag)
break;
case HA_KEYTYPE_ULONGLONG: case HA_KEYTYPE_ULONGLONG:
RT_CMP_KORR(ulonglong, mi_uint8korr, 8, nextflag) RT_CMP_KORR(ulonglong, mi_uint8korr, 8, nextflag)
break;
#endif #endif
case HA_KEYTYPE_FLOAT: case HA_KEYTYPE_FLOAT:
RT_CMP_GET(float, mi_float4get, 4, nextflag); RT_CMP_GET(float, mi_float4get, 4, nextflag);
break;
case HA_KEYTYPE_DOUBLE: case HA_KEYTYPE_DOUBLE:
RT_CMP_GET(double, mi_float8get, 8, nextflag); RT_CMP_GET(double, mi_float8get, 8, nextflag);
break;
case HA_KEYTYPE_END: case HA_KEYTYPE_END:
goto end; goto end;
default:
return 1;
} }
uint32 keyseg_length= keyseg->length * 2;
key_length-= keyseg_length;
a+= keyseg_length;
b+= keyseg_length;
} }
end: end:
...@@ -167,22 +161,16 @@ end: ...@@ -167,22 +161,16 @@ end:
{ \ { \
type amin, amax; \ type amin, amax; \
amin = korr_func(a); \ amin = korr_func(a); \
a += len; \ amax = korr_func(a+len); \
amax = korr_func(a); \
a += len; \
res *= (cast(amax) - cast(amin)); \ res *= (cast(amax) - cast(amin)); \
break; \
} }
#define RT_VOL_GET(type, get_func, len, cast) \ #define RT_VOL_GET(type, get_func, len, cast) \
{ \ { \
type amin, amax; \ type amin, amax; \
get_func(amin, a); \ get_func(amin, a); \
a += len; \ get_func(amax, a+len); \
get_func(amax, a); \
a += len; \
res *= (cast(amax) - cast(amin)); \ res *= (cast(amax) - cast(amin)); \
break; \
} }
/* /*
...@@ -193,53 +181,54 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) ...@@ -193,53 +181,54 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
double res = 1; double res = 1;
for (; (int)key_length > 0; keyseg += 2) for (; (int)key_length > 0; keyseg += 2)
{ {
key_length -= keyseg->length * 2;
switch ((enum ha_base_keytype) keyseg->type) { switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_TEXT: case HA_KEYTYPE_INT8:
RT_VOL_KORR(int8, mi_sint1korr, 1, (double));
break;
case HA_KEYTYPE_BINARY: case HA_KEYTYPE_BINARY:
case HA_KEYTYPE_VARTEXT: RT_VOL_KORR(uint8, mi_uint1korr, 1, (double));
case HA_KEYTYPE_VARBINARY:
case HA_KEYTYPE_NUM:
default:
return 1;
break; break;
case HA_KEYTYPE_INT8:
{
int amin, amax;
amin = (int)*((signed char *)a);
a += 1;
amax = (int)*((signed char *)a);
a += 1;
res *= ((double)amax - (double)amin);
break;
}
case HA_KEYTYPE_SHORT_INT: case HA_KEYTYPE_SHORT_INT:
RT_VOL_KORR(int16, mi_sint2korr, 2, (double)); RT_VOL_KORR(int16, mi_sint2korr, 2, (double));
break;
case HA_KEYTYPE_USHORT_INT: case HA_KEYTYPE_USHORT_INT:
RT_VOL_KORR(uint16, mi_uint2korr, 2, (double)); RT_VOL_KORR(uint16, mi_uint2korr, 2, (double));
break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
RT_VOL_KORR(int32, mi_sint3korr, 3, (double)); RT_VOL_KORR(int32, mi_sint3korr, 3, (double));
break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
RT_VOL_KORR(uint32, mi_uint3korr, 3, (double)); RT_VOL_KORR(uint32, mi_uint3korr, 3, (double));
break;
case HA_KEYTYPE_LONG_INT: case HA_KEYTYPE_LONG_INT:
RT_VOL_KORR(int32, mi_sint4korr, 4, (double)); RT_VOL_KORR(int32, mi_sint4korr, 4, (double));
break;
case HA_KEYTYPE_ULONG_INT: case HA_KEYTYPE_ULONG_INT:
RT_VOL_KORR(uint32, mi_uint4korr, 4, (double)); RT_VOL_KORR(uint32, mi_uint4korr, 4, (double));
break;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case HA_KEYTYPE_LONGLONG: case HA_KEYTYPE_LONGLONG:
RT_VOL_KORR(longlong, mi_sint8korr, 8, (double)); RT_VOL_KORR(longlong, mi_sint8korr, 8, (double));
break;
case HA_KEYTYPE_ULONGLONG: case HA_KEYTYPE_ULONGLONG:
RT_VOL_KORR(longlong, mi_sint8korr, 8, ulonglong2double); RT_VOL_KORR(longlong, mi_sint8korr, 8, ulonglong2double);
break;
#endif #endif
case HA_KEYTYPE_FLOAT: case HA_KEYTYPE_FLOAT:
RT_VOL_GET(float, mi_float4get, 4, (double)); RT_VOL_GET(float, mi_float4get, 4, (double));
break;
case HA_KEYTYPE_DOUBLE: case HA_KEYTYPE_DOUBLE:
RT_VOL_GET(double, mi_float8get, 8, (double)); RT_VOL_GET(double, mi_float8get, 8, (double));
break;
case HA_KEYTYPE_END: case HA_KEYTYPE_END:
key_length = 0; key_length = 0;
break; break;
default:
return -1;
} }
uint32 keyseg_length= keyseg->length * 2;
key_length-= keyseg_length;
a+= keyseg_length;
} }
return res; return res;
} }
...@@ -248,24 +237,18 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length) ...@@ -248,24 +237,18 @@ double rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
{ \ { \
type amin, amax; \ type amin, amax; \
amin = korr_func(a); \ amin = korr_func(a); \
a += len; \ amax = korr_func(a+len); \
amax = korr_func(a); \
a += len; \
*res++ = cast(amin); \ *res++ = cast(amin); \
*res++ = cast(amax); \ *res++ = cast(amax); \
break; \
} }
#define RT_D_MBR_GET(type, get_func, len, cast) \ #define RT_D_MBR_GET(type, get_func, len, cast) \
{ \ { \
type amin, amax; \ type amin, amax; \
get_func(amin, a); \ get_func(amin, a); \
a += len; \ get_func(amax, a+len); \
get_func(amax, a); \
a += len; \
*res++ = cast(amin); \ *res++ = cast(amin); \
*res++ = cast(amax); \ *res++ = cast(amax); \
break; \
} }
/* /*
...@@ -275,54 +258,54 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) ...@@ -275,54 +258,54 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
{ {
for (; (int)key_length > 0; keyseg += 2) for (; (int)key_length > 0; keyseg += 2)
{ {
key_length -= keyseg->length * 2;
switch ((enum ha_base_keytype) keyseg->type) { switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_TEXT: case HA_KEYTYPE_INT8:
RT_D_MBR_KORR(int8, mi_sint1korr, 1, (double));
break;
case HA_KEYTYPE_BINARY: case HA_KEYTYPE_BINARY:
case HA_KEYTYPE_VARTEXT: RT_D_MBR_KORR(uint8, mi_uint1korr, 1, (double));
case HA_KEYTYPE_VARBINARY:
case HA_KEYTYPE_NUM:
default:
return 1;
break; break;
case HA_KEYTYPE_INT8:
{
int amin, amax;
amin = (int)*((signed char *)a);
a += 1;
amax = (int)*((signed char *)a);
a += 1;
*res++ = (double)amin;
*res++ = (double)amax;
break;
}
case HA_KEYTYPE_SHORT_INT: case HA_KEYTYPE_SHORT_INT:
RT_D_MBR_KORR(int16, mi_sint2korr, 2, (double)); RT_D_MBR_KORR(int16, mi_sint2korr, 2, (double));
break;
case HA_KEYTYPE_USHORT_INT: case HA_KEYTYPE_USHORT_INT:
RT_D_MBR_KORR(uint16, mi_uint2korr, 2, (double)); RT_D_MBR_KORR(uint16, mi_uint2korr, 2, (double));
break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
RT_D_MBR_KORR(int32, mi_sint3korr, 3, (double)); RT_D_MBR_KORR(int32, mi_sint3korr, 3, (double));
break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
RT_D_MBR_KORR(uint32, mi_uint3korr, 3, (double)); RT_D_MBR_KORR(uint32, mi_uint3korr, 3, (double));
break;
case HA_KEYTYPE_LONG_INT: case HA_KEYTYPE_LONG_INT:
RT_D_MBR_KORR(int32, mi_sint4korr, 4, (double)); RT_D_MBR_KORR(int32, mi_sint4korr, 4, (double));
break;
case HA_KEYTYPE_ULONG_INT: case HA_KEYTYPE_ULONG_INT:
RT_D_MBR_KORR(uint32, mi_uint4korr, 4, (double)); RT_D_MBR_KORR(uint32, mi_uint4korr, 4, (double));
break;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case HA_KEYTYPE_LONGLONG: case HA_KEYTYPE_LONGLONG:
RT_D_MBR_KORR(longlong, mi_sint8korr, 8, (double)); RT_D_MBR_KORR(longlong, mi_sint8korr, 8, (double));
break;
case HA_KEYTYPE_ULONGLONG: case HA_KEYTYPE_ULONGLONG:
RT_D_MBR_KORR(longlong, mi_sint8korr, 8, ulonglong2double); RT_D_MBR_KORR(longlong, mi_sint8korr, 8, ulonglong2double);
break;
#endif #endif
case HA_KEYTYPE_FLOAT: case HA_KEYTYPE_FLOAT:
RT_D_MBR_GET(float, mi_float4get, 4, (double)); RT_D_MBR_GET(float, mi_float4get, 4, (double));
break;
case HA_KEYTYPE_DOUBLE: case HA_KEYTYPE_DOUBLE:
RT_D_MBR_GET(double, mi_float8get, 8, (double)); RT_D_MBR_GET(double, mi_float8get, 8, (double));
break;
case HA_KEYTYPE_END: case HA_KEYTYPE_END:
key_length = 0; key_length = 0;
break; break;
default:
return 1;
} }
uint32 keyseg_length= keyseg->length * 2;
key_length-= keyseg_length;
a+= keyseg_length;
} }
return 0; return 0;
} }
...@@ -332,17 +315,12 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) ...@@ -332,17 +315,12 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
amin = korr_func(a); \ amin = korr_func(a); \
bmin = korr_func(b); \ bmin = korr_func(b); \
p_inc(a, b, len); \ amax = korr_func(a+len); \
amax = korr_func(a); \ bmax = korr_func(b+len); \
bmax = korr_func(b); \
p_inc(a, b, len); \
amin = min(amin, bmin); \ amin = min(amin, bmin); \
amax = max(amax, bmax); \ amax = max(amax, bmax); \
store_func(c, amin); \ store_func(c, amin); \
c += len; \ store_func(c+len, amax); \
store_func(c, amax); \
c += len; \
break; \
} }
#define RT_COMB_GET(type, get_func, store_func, len) \ #define RT_COMB_GET(type, get_func, store_func, len) \
...@@ -350,17 +328,12 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) ...@@ -350,17 +328,12 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
get_func(amin, a); \ get_func(amin, a); \
get_func(bmin, b); \ get_func(bmin, b); \
p_inc(a, b, len); \ get_func(amax, a+len); \
get_func(amax, a); \ get_func(bmax, b+len); \
get_func(bmax, b); \
p_inc(a, b, len); \
amin = min(amin, bmin); \ amin = min(amin, bmin); \
amax = max(amax, bmax); \ amax = max(amax, bmax); \
store_func(c, amin); \ store_func(c, amin); \
c += len; \ store_func(c+len, amax); \
store_func(c, amax); \
c += len; \
break; \
} }
/* /*
...@@ -372,62 +345,57 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res) ...@@ -372,62 +345,57 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
uint key_length) uint key_length)
{ {
for ( ; (int) key_length > 0 ; keyseg += 2) for ( ; (int) key_length > 0 ; keyseg += 2)
{ {
key_length -= keyseg->length * 2;
switch ((enum ha_base_keytype) keyseg->type) { switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_TEXT: case HA_KEYTYPE_INT8:
RT_COMB_KORR(int8, mi_sint1korr, mi_int1store, 1);
break;
case HA_KEYTYPE_BINARY: case HA_KEYTYPE_BINARY:
case HA_KEYTYPE_VARTEXT: RT_COMB_KORR(uint8, mi_uint1korr, mi_int1store, 1);
case HA_KEYTYPE_VARBINARY:
case HA_KEYTYPE_NUM:
default:
return 1;
break; break;
case HA_KEYTYPE_INT8:
{
int amin, amax, bmin, bmax;
amin = (int)*((signed char *)a);
bmin = (int)*((signed char *)b);
p_inc(a, b, 1);
amax = (int)*((signed char *)a);
bmax = (int)*((signed char *)b);
p_inc(a, b, 1);
amin = min(amin, bmin);
amax = max(amax, bmax);
*((signed char*)c) = amin;
c += 1;
*((signed char*)c) = amax;
c += 1;
break;
}
case HA_KEYTYPE_SHORT_INT: case HA_KEYTYPE_SHORT_INT:
RT_COMB_KORR(int16, mi_sint2korr, mi_int2store, 2); RT_COMB_KORR(int16, mi_sint2korr, mi_int2store, 2);
break;
case HA_KEYTYPE_USHORT_INT: case HA_KEYTYPE_USHORT_INT:
RT_COMB_KORR(uint16, mi_uint2korr, mi_int2store, 2); RT_COMB_KORR(uint16, mi_uint2korr, mi_int2store, 2);
break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
RT_COMB_KORR(int32, mi_sint3korr, mi_int3store, 3); RT_COMB_KORR(int32, mi_sint3korr, mi_int3store, 3);
break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
RT_COMB_KORR(uint32, mi_uint3korr, mi_int3store, 3); RT_COMB_KORR(uint32, mi_uint3korr, mi_int3store, 3);
break;
case HA_KEYTYPE_LONG_INT: case HA_KEYTYPE_LONG_INT:
RT_COMB_KORR(int32, mi_sint4korr, mi_int4store, 4); RT_COMB_KORR(int32, mi_sint4korr, mi_int4store, 4);
break;
case HA_KEYTYPE_ULONG_INT: case HA_KEYTYPE_ULONG_INT:
RT_COMB_KORR(uint32, mi_uint4korr, mi_int4store, 4); RT_COMB_KORR(uint32, mi_uint4korr, mi_int4store, 4);
break;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case HA_KEYTYPE_LONGLONG: case HA_KEYTYPE_LONGLONG:
RT_COMB_KORR(longlong, mi_sint8korr, mi_int8store, 8); RT_COMB_KORR(longlong, mi_sint8korr, mi_int8store, 8);
break;
case HA_KEYTYPE_ULONGLONG: case HA_KEYTYPE_ULONGLONG:
RT_COMB_KORR(ulonglong, mi_uint8korr, mi_int8store, 8); RT_COMB_KORR(ulonglong, mi_uint8korr, mi_int8store, 8);
break;
#endif #endif
case HA_KEYTYPE_FLOAT: case HA_KEYTYPE_FLOAT:
RT_COMB_GET(float, mi_float4get, mi_float4store, 4); RT_COMB_GET(float, mi_float4get, mi_float4store, 4);
break;
case HA_KEYTYPE_DOUBLE: case HA_KEYTYPE_DOUBLE:
RT_COMB_GET(double, mi_float8get, mi_float8store, 8); RT_COMB_GET(double, mi_float8get, mi_float8store, 8);
break;
case HA_KEYTYPE_END: case HA_KEYTYPE_END:
return 0; return 0;
default:
return 1;
} }
uint32 keyseg_length= keyseg->length * 2;
key_length-= keyseg_length;
a+= keyseg_length;
b+= keyseg_length;
c+= keyseg_length;
} }
return 0; return 0;
} }
...@@ -437,16 +405,13 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, ...@@ -437,16 +405,13 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
amin = korr_func(a); \ amin = korr_func(a); \
bmin = korr_func(b); \ bmin = korr_func(b); \
p_inc(a, b, len); \ amax = korr_func(a+len); \
amax = korr_func(a); \ bmax = korr_func(b+len); \
bmax = korr_func(b); \
p_inc(a, b, len); \
amin = max(amin, bmin); \ amin = max(amin, bmin); \
amax = min(amax, bmax); \ amax = min(amax, bmax); \
if (amin >= amax) \ if (amin >= amax) \
return 0; \ return 0; \
res *= amax - amin; \ res *= amax - amin; \
break; \
} }
#define RT_OVL_AREA_GET(type, get_func, len) \ #define RT_OVL_AREA_GET(type, get_func, len) \
...@@ -454,16 +419,13 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c, ...@@ -454,16 +419,13 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
get_func(amin, a); \ get_func(amin, a); \
get_func(bmin, b); \ get_func(bmin, b); \
p_inc(a, b, len); \ get_func(amax, a+len); \
get_func(amax, a); \ get_func(bmax, b+len); \
get_func(bmax, b); \
p_inc(a, b, len); \
amin = max(amin, bmin); \ amin = max(amin, bmin); \
amax = min(amax, bmax); \ amax = min(amax, bmax); \
if (amin >= amax) \ if (amin >= amax) \
return 0; \ return 0; \
res *= amax - amin; \ res *= amax - amin; \
break; \
} }
/* /*
...@@ -475,58 +437,54 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, ...@@ -475,58 +437,54 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
double res = 1; double res = 1;
for (; (int) key_length > 0 ; keyseg += 2) for (; (int) key_length > 0 ; keyseg += 2)
{ {
key_length -= keyseg->length * 2;
switch ((enum ha_base_keytype) keyseg->type) { switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_TEXT: case HA_KEYTYPE_INT8:
RT_OVL_AREA_KORR(int8, mi_sint1korr, 1);
break;
case HA_KEYTYPE_BINARY: case HA_KEYTYPE_BINARY:
case HA_KEYTYPE_VARTEXT: RT_OVL_AREA_KORR(uint8, mi_uint1korr, 1);
case HA_KEYTYPE_VARBINARY:
case HA_KEYTYPE_NUM:
default:
return -1;
break; break;
case HA_KEYTYPE_INT8:
{
int amin, amax, bmin, bmax;
amin = (int)*((signed char *)a);
bmin = (int)*((signed char *)b);
p_inc(a, b, 1);
amax = (int)*((signed char *)a);
bmax = (int)*((signed char *)b);
p_inc(a, b, 1);
amin = max(amin, bmin);
amax = min(amax, bmax);
if (amin >= amax)
return 0;
res *= amax - amin;
break;
}
case HA_KEYTYPE_SHORT_INT: case HA_KEYTYPE_SHORT_INT:
RT_OVL_AREA_KORR(int16, mi_sint2korr, 2); RT_OVL_AREA_KORR(int16, mi_sint2korr, 2);
break;
case HA_KEYTYPE_USHORT_INT: case HA_KEYTYPE_USHORT_INT:
RT_OVL_AREA_KORR(uint16, mi_uint2korr, 2); RT_OVL_AREA_KORR(uint16, mi_uint2korr, 2);
break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
RT_OVL_AREA_KORR(int32, mi_sint3korr, 3); RT_OVL_AREA_KORR(int32, mi_sint3korr, 3);
break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
RT_OVL_AREA_KORR(uint32, mi_uint3korr, 3); RT_OVL_AREA_KORR(uint32, mi_uint3korr, 3);
break;
case HA_KEYTYPE_LONG_INT: case HA_KEYTYPE_LONG_INT:
RT_OVL_AREA_KORR(int32, mi_sint4korr, 4); RT_OVL_AREA_KORR(int32, mi_sint4korr, 4);
break;
case HA_KEYTYPE_ULONG_INT: case HA_KEYTYPE_ULONG_INT:
RT_OVL_AREA_KORR(uint32, mi_uint4korr, 4); RT_OVL_AREA_KORR(uint32, mi_uint4korr, 4);
break;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case HA_KEYTYPE_LONGLONG: case HA_KEYTYPE_LONGLONG:
RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8); RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8);
break;
case HA_KEYTYPE_ULONGLONG: case HA_KEYTYPE_ULONGLONG:
RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8); RT_OVL_AREA_KORR(longlong, mi_sint8korr, 8);
break;
#endif #endif
case HA_KEYTYPE_FLOAT: case HA_KEYTYPE_FLOAT:
RT_OVL_AREA_GET(float, mi_float4get, 4); RT_OVL_AREA_GET(float, mi_float4get, 4);
break;
case HA_KEYTYPE_DOUBLE: case HA_KEYTYPE_DOUBLE:
RT_OVL_AREA_GET(double, mi_float8get, 8); RT_OVL_AREA_GET(double, mi_float8get, 8);
break;
case HA_KEYTYPE_END: case HA_KEYTYPE_END:
return res; return res;
default:
return -1;
} }
uint32 keyseg_length= keyseg->length * 2;
key_length-= keyseg_length;
a+= keyseg_length;
b+= keyseg_length;
} }
return res; return res;
} }
...@@ -536,13 +494,10 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, ...@@ -536,13 +494,10 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
amin = korr_func(a); \ amin = korr_func(a); \
bmin = korr_func(b); \ bmin = korr_func(b); \
p_inc(a, b, len); \ amax = korr_func(a+len); \
amax = korr_func(a); \ bmax = korr_func(b+len); \
bmax = korr_func(b); \
p_inc(a, b, len); \
a_area *= (((double)amax) - ((double)amin)); \ a_area *= (((double)amax) - ((double)amin)); \
*ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ *ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
break; \
} }
#define RT_AREA_INC_GET(type, get_func, len)\ #define RT_AREA_INC_GET(type, get_func, len)\
...@@ -550,13 +505,10 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b, ...@@ -550,13 +505,10 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
get_func(amin, a); \ get_func(amin, a); \
get_func(bmin, b); \ get_func(bmin, b); \
p_inc(a, b, len); \ get_func(amax, a+len); \
get_func(amax, a); \ get_func(bmax, b+len); \
get_func(bmax, b); \
p_inc(a, b, len); \
a_area *= (((double)amax) - ((double)amin)); \ a_area *= (((double)amax) - ((double)amin)); \
*ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \ *ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
break; \
} }
/* /*
...@@ -565,13 +517,11 @@ Calculates MBR_AREA(a+b) - MBR_AREA(a) ...@@ -565,13 +517,11 @@ Calculates MBR_AREA(a+b) - MBR_AREA(a)
double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
uint key_length, double *ab_area) uint key_length, double *ab_area)
{ {
double a_area = 1; double a_area= 1.0;
*ab_area = 1; *ab_area= 1.0;
for (; (int)key_length > 0; keyseg += 2) for (; (int)key_length > 0; keyseg += 2)
{ {
key_length -= keyseg->length * 2;
/* Handle NULL part */ /* Handle NULL part */
if (keyseg->null_bit) if (keyseg->null_bit)
{ {
...@@ -579,56 +529,149 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, ...@@ -579,56 +529,149 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
} }
switch ((enum ha_base_keytype) keyseg->type) { switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_TEXT: case HA_KEYTYPE_INT8:
RT_AREA_INC_KORR(int8, mi_sint1korr, 1);
break;
case HA_KEYTYPE_BINARY: case HA_KEYTYPE_BINARY:
case HA_KEYTYPE_VARTEXT: RT_AREA_INC_KORR(uint8, mi_uint1korr, 1);
case HA_KEYTYPE_VARBINARY:
case HA_KEYTYPE_NUM:
default:
return 1;
break; break;
case HA_KEYTYPE_INT8:
{
int amin, amax, bmin, bmax;
amin = (int)*((signed char *)a);
bmin = (int)*((signed char *)b);
p_inc(a, b, 1);
amax = (int)*((signed char *)a);
bmax = (int)*((signed char *)b);
p_inc(a, b, 1);
a_area *= (((double)amax) - ((double)amin));
*ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin));
break;
}
case HA_KEYTYPE_SHORT_INT: case HA_KEYTYPE_SHORT_INT:
RT_AREA_INC_KORR(int16, mi_sint2korr, 2); RT_AREA_INC_KORR(int16, mi_sint2korr, 2);
break;
case HA_KEYTYPE_USHORT_INT: case HA_KEYTYPE_USHORT_INT:
RT_AREA_INC_KORR(uint16, mi_uint2korr, 2); RT_AREA_INC_KORR(uint16, mi_uint2korr, 2);
break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
RT_AREA_INC_KORR(int32, mi_sint3korr, 3); RT_AREA_INC_KORR(int32, mi_sint3korr, 3);
break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
RT_AREA_INC_KORR(int32, mi_uint3korr, 3); RT_AREA_INC_KORR(int32, mi_uint3korr, 3);
break;
case HA_KEYTYPE_LONG_INT: case HA_KEYTYPE_LONG_INT:
RT_AREA_INC_KORR(int32, mi_sint4korr, 4); RT_AREA_INC_KORR(int32, mi_sint4korr, 4);
break;
case HA_KEYTYPE_ULONG_INT: case HA_KEYTYPE_ULONG_INT:
RT_AREA_INC_KORR(uint32, mi_uint4korr, 4); RT_AREA_INC_KORR(uint32, mi_uint4korr, 4);
break;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case HA_KEYTYPE_LONGLONG: case HA_KEYTYPE_LONGLONG:
RT_AREA_INC_KORR(longlong, mi_sint8korr, 8); RT_AREA_INC_KORR(longlong, mi_sint8korr, 8);
break;
case HA_KEYTYPE_ULONGLONG: case HA_KEYTYPE_ULONGLONG:
RT_AREA_INC_KORR(longlong, mi_sint8korr, 8); RT_AREA_INC_KORR(longlong, mi_sint8korr, 8);
break;
#endif #endif
case HA_KEYTYPE_FLOAT: case HA_KEYTYPE_FLOAT:
RT_AREA_INC_GET(float, mi_float4get, 4); RT_AREA_INC_GET(float, mi_float4get, 4);
break;
case HA_KEYTYPE_DOUBLE: case HA_KEYTYPE_DOUBLE:
RT_AREA_INC_GET(double, mi_float8get, 8); RT_AREA_INC_GET(double, mi_float8get, 8);
break;
case HA_KEYTYPE_END: case HA_KEYTYPE_END:
return *ab_area - a_area; return *ab_area - a_area;
default:
return -1;
} }
uint32 keyseg_length= keyseg->length * 2;
key_length-= keyseg_length;
a+= keyseg_length;
b+= keyseg_length;
} }
return *ab_area - a_area; return *ab_area - a_area;
} }
#define RT_PERIM_INC_KORR(type, korr_func, len) \
{ \
type amin, amax, bmin, bmax; \
amin = korr_func(a); \
bmin = korr_func(b); \
amax = korr_func(a+len); \
bmax = korr_func(b+len); \
a_perim+= (((double)amax) - ((double)amin)); \
*ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
}
#define RT_PERIM_INC_GET(type, get_func, len)\
{\
type amin, amax, bmin, bmax; \
get_func(amin, a); \
get_func(bmin, b); \
get_func(amax, a+len); \
get_func(bmax, b+len); \
a_perim+= (((double)amax) - ((double)amin)); \
*ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
}
/*
Calculates MBR_PERIMETER(a+b) - MBR_PERIMETER(a)
*/
double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
uint key_length, double *ab_perim)
{
double a_perim = 0.0;
*ab_perim= 0.0;
for (; (int)key_length > 0; keyseg += 2)
{
/* Handle NULL part */
if (keyseg->null_bit)
{
return -1;
}
switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_INT8:
RT_PERIM_INC_KORR(int8, mi_sint1korr, 1);
break;
case HA_KEYTYPE_BINARY:
RT_PERIM_INC_KORR(uint8, mi_uint1korr, 1);
break;
case HA_KEYTYPE_SHORT_INT:
RT_PERIM_INC_KORR(int16, mi_sint2korr, 2);
break;
case HA_KEYTYPE_USHORT_INT:
RT_PERIM_INC_KORR(uint16, mi_uint2korr, 2);
break;
case HA_KEYTYPE_INT24:
RT_PERIM_INC_KORR(int32, mi_sint3korr, 3);
break;
case HA_KEYTYPE_UINT24:
RT_PERIM_INC_KORR(int32, mi_uint3korr, 3);
break;
case HA_KEYTYPE_LONG_INT:
RT_PERIM_INC_KORR(int32, mi_sint4korr, 4);
break;
case HA_KEYTYPE_ULONG_INT:
RT_PERIM_INC_KORR(uint32, mi_uint4korr, 4);
break;
#ifdef HAVE_LONG_LONG
case HA_KEYTYPE_LONGLONG:
RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8);
break;
case HA_KEYTYPE_ULONGLONG:
RT_PERIM_INC_KORR(longlong, mi_sint8korr, 8);
break;
#endif
case HA_KEYTYPE_FLOAT:
RT_PERIM_INC_GET(float, mi_float4get, 4);
break;
case HA_KEYTYPE_DOUBLE:
RT_PERIM_INC_GET(double, mi_float8get, 8);
break;
case HA_KEYTYPE_END:
return *ab_perim - a_perim;
default:
return -1;
}
uint32 keyseg_length= keyseg->length * 2;
key_length-= keyseg_length;
a+= keyseg_length;
b+= keyseg_length;
}
return *ab_perim - a_perim;
}
#define RT_PAGE_MBR_KORR(type, korr_func, store_func, len) \ #define RT_PAGE_MBR_KORR(type, korr_func, store_func, len) \
{ \ { \
type amin, amax, bmin, bmax; \ type amin, amax, bmin, bmax; \
...@@ -649,7 +692,6 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, ...@@ -649,7 +692,6 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
store_func(c, amax); \ store_func(c, amax); \
c += len; \ c += len; \
inc += 2 * len; \ inc += 2 * len; \
break; \
} }
#define RT_PAGE_MBR_GET(type, get_func, store_func, len) \ #define RT_PAGE_MBR_GET(type, get_func, store_func, len) \
...@@ -672,7 +714,6 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b, ...@@ -672,7 +714,6 @@ double rtree_area_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
store_func(c, amax); \ store_func(c, amax); \
c += len; \ c += len; \
inc += 2 * len; \ inc += 2 * len; \
break; \
} }
/* /*
...@@ -700,61 +741,48 @@ int rtree_page_mbr(MI_INFO *info, HA_KEYSEG *keyseg, uchar *page_buf, ...@@ -700,61 +741,48 @@ int rtree_page_mbr(MI_INFO *info, HA_KEYSEG *keyseg, uchar *page_buf,
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag); k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
switch ((enum ha_base_keytype) keyseg->type) { switch ((enum ha_base_keytype) keyseg->type) {
case HA_KEYTYPE_TEXT: case HA_KEYTYPE_INT8:
RT_PAGE_MBR_KORR(int8, mi_sint1korr, mi_int1store, 1);
break;
case HA_KEYTYPE_BINARY: case HA_KEYTYPE_BINARY:
case HA_KEYTYPE_VARTEXT: RT_PAGE_MBR_KORR(uint8, mi_uint1korr, mi_int1store, 1);
case HA_KEYTYPE_VARBINARY:
case HA_KEYTYPE_NUM:
default:
return 1;
break; break;
case HA_KEYTYPE_INT8:
{
int amin, amax, bmin, bmax;
amin = (int)*((signed char *)(k + inc));
amax = (int)*((signed char *)(k + inc + 1));
k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag))
{
bmin = (int)*((signed char *)(k + inc));
bmax = (int)*((signed char *)(k + inc + 1));
if (amin > bmin)
amin = bmin;
if (amax < bmax)
amax = bmax;
}
*((signed char*)c) = amin;
c += 1;
*((signed char*)c) = amax;
c += 1;
inc += 1 * 2;
break;
}
case HA_KEYTYPE_SHORT_INT: case HA_KEYTYPE_SHORT_INT:
RT_PAGE_MBR_KORR(int16, mi_sint2korr, mi_int2store, 2); RT_PAGE_MBR_KORR(int16, mi_sint2korr, mi_int2store, 2);
break;
case HA_KEYTYPE_USHORT_INT: case HA_KEYTYPE_USHORT_INT:
RT_PAGE_MBR_KORR(uint16, mi_uint2korr, mi_int2store, 2); RT_PAGE_MBR_KORR(uint16, mi_uint2korr, mi_int2store, 2);
break;
case HA_KEYTYPE_INT24: case HA_KEYTYPE_INT24:
RT_PAGE_MBR_KORR(int32, mi_sint3korr, mi_int3store, 3); RT_PAGE_MBR_KORR(int32, mi_sint3korr, mi_int3store, 3);
break;
case HA_KEYTYPE_UINT24: case HA_KEYTYPE_UINT24:
RT_PAGE_MBR_KORR(uint32, mi_uint3korr, mi_int3store, 3); RT_PAGE_MBR_KORR(uint32, mi_uint3korr, mi_int3store, 3);
break;
case HA_KEYTYPE_LONG_INT: case HA_KEYTYPE_LONG_INT:
RT_PAGE_MBR_KORR(int32, mi_sint4korr, mi_int4store, 4); RT_PAGE_MBR_KORR(int32, mi_sint4korr, mi_int4store, 4);
break;
case HA_KEYTYPE_ULONG_INT: case HA_KEYTYPE_ULONG_INT:
RT_PAGE_MBR_KORR(uint32, mi_uint4korr, mi_int4store, 4); RT_PAGE_MBR_KORR(uint32, mi_uint4korr, mi_int4store, 4);
break;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case HA_KEYTYPE_LONGLONG: case HA_KEYTYPE_LONGLONG:
RT_PAGE_MBR_KORR(longlong, mi_sint8korr, mi_int8store, 8); RT_PAGE_MBR_KORR(longlong, mi_sint8korr, mi_int8store, 8);
break;
case HA_KEYTYPE_ULONGLONG: case HA_KEYTYPE_ULONGLONG:
RT_PAGE_MBR_KORR(ulonglong, mi_uint8korr, mi_int8store, 8); RT_PAGE_MBR_KORR(ulonglong, mi_uint8korr, mi_int8store, 8);
break;
#endif #endif
case HA_KEYTYPE_FLOAT: case HA_KEYTYPE_FLOAT:
RT_PAGE_MBR_GET(float, mi_float4get, mi_float4store, 4); RT_PAGE_MBR_GET(float, mi_float4get, mi_float4store, 4);
break;
case HA_KEYTYPE_DOUBLE: case HA_KEYTYPE_DOUBLE:
RT_PAGE_MBR_GET(double, mi_float8get, mi_float8store, 8); RT_PAGE_MBR_GET(double, mi_float8get, mi_float8store, 8);
break;
case HA_KEYTYPE_END: case HA_KEYTYPE_END:
return 0; return 0;
default:
return 1;
} }
} }
return 0; return 0;
......
...@@ -30,6 +30,8 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar *a, uchar *b, ...@@ -30,6 +30,8 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar *a, uchar *b,
uint key_length); uint key_length);
double rtree_area_increase(HA_KEYSEG *keyseg, uchar *a, uchar *b, double rtree_area_increase(HA_KEYSEG *keyseg, uchar *a, uchar *b,
uint key_length, double *ab_area); uint key_length, double *ab_area);
double rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
uint key_length, double *ab_perim);
int rtree_page_mbr(MI_INFO *info, HA_KEYSEG *keyseg, uchar *page_buf, int rtree_page_mbr(MI_INFO *info, HA_KEYSEG *keyseg, uchar *page_buf,
uchar* c, uint key_length); uchar* c, uint key_length);
#endif /*HAVE_RTREE_KEYS*/ #endif /*HAVE_RTREE_KEYS*/
......
...@@ -267,12 +267,12 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, ...@@ -267,12 +267,12 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
n_dim = keyinfo->keysegs / 2; n_dim = keyinfo->keysegs / 2;
if (!my_multi_malloc(MYF(0), if (!(coord_buf= my_alloca(n_dim * 2 * sizeof(double) * (max_keys + 1 + 4) +
&coord_buf, n_dim * 2 * sizeof(double) * (max_keys + 1 + 4), sizeof(SplitStruct) * (max_keys + 1))))
&task, sizeof(SplitStruct) * (max_keys + 1),
NullS))
return -1; return -1;
task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4));
next_coord = coord_buf; next_coord = coord_buf;
stop = task + max_keys; stop = task + max_keys;
...@@ -345,7 +345,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, ...@@ -345,7 +345,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
my_afree((byte*)new_page); my_afree((byte*)new_page);
split_err: split_err:
my_free((gptr) coord_buf, MYF(0)); my_afree((byte*) coord_buf);
return err_code; return err_code;
} }
......
...@@ -34,6 +34,51 @@ static void create_record1(char *record,uint rownr); ...@@ -34,6 +34,51 @@ static void create_record1(char *record,uint rownr);
static void print_record(char * record,my_off_t offs,const char * tail); static void print_record(char * record,my_off_t offs,const char * tail);
static int run_test(const char *filename); static int run_test(const char *filename);
static double rt_data[]=
{
/*1*/ 0,10,0,10,
/*2*/ 5,15,0,10,
/*3*/ 0,10,5,15,
/*4*/ 10,20,10,20,
/*5*/ 0,10,0,10,
/*6*/ 5,15,0,10,
/*7*/ 0,10,5,15,
/*8*/ 10,20,10,20,
/*9*/ 0,10,0,10,
/*10*/ 5,15,0,10,
/*11*/ 0,10,5,15,
/*12*/ 10,20,10,20,
/*13*/ 0,10,0,10,
/*14*/ 5,15,0,10,
/*15*/ 0,10,5,15,
/*16*/ 10,20,10,20,
/*17*/ 5,15,0,10,
/*18*/ 0,10,5,15,
/*19*/ 10,20,10,20,
/*20*/ 0,10,0,10,
/*1*/ 100,110,0,10,
/*2*/ 105,115,0,10,
/*3*/ 100,110,5,15,
/*4*/ 110,120,10,20,
/*5*/ 100,110,0,10,
/*6*/ 105,115,0,10,
/*7*/ 100,110,5,15,
/*8*/ 110,120,10,20,
/*9*/ 100,110,0,10,
/*10*/ 105,115,0,10,
/*11*/ 100,110,5,15,
/*12*/ 110,120,10,20,
/*13*/ 100,110,0,10,
/*14*/ 105,115,0,10,
/*15*/ 100,110,5,15,
/*16*/ 110,120,10,20,
/*17*/ 105,115,0,10,
/*18*/ 100,110,5,15,
/*19*/ 110,120,10,20,
/*20*/ 100,110,0,10,
-1
};
int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
{ {
...@@ -58,7 +103,7 @@ static int run_test(const char *filename) ...@@ -58,7 +103,7 @@ static int run_test(const char *filename)
int key_type=HA_KEYTYPE_DOUBLE; int key_type=HA_KEYTYPE_DOUBLE;
int key_length=8; int key_length=8;
int null_fields=0; int null_fields=0;
int nrecords=300; int nrecords=sizeof(rt_data)/(sizeof(double)*4);/* 3000;*/
int rec_length=0; int rec_length=0;
int uniques=0; int uniques=0;
int i; int i;
...@@ -381,7 +426,7 @@ static void create_record1(char *record,uint rownr) ...@@ -381,7 +426,7 @@ static void create_record1(char *record,uint rownr)
} }
static void create_record(char *record,uint rownr) static void create_record0(char *record,uint rownr)
{ {
int i; int i;
char * pos; char * pos;
...@@ -402,6 +447,19 @@ static void create_record(char *record,uint rownr) ...@@ -402,6 +447,19 @@ static void create_record(char *record,uint rownr)
} }
} }
static void create_record(char *record,uint rownr)
{
int i;
char *pos;
double *data= rt_data+rownr*4;
record[0]=0x01; /* DEL marker */
for ( pos=record+1, i=0; i<ndims*2; i++)
{
float8store(pos,data[i]);
pos+=8;
}
}
#else #else
int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
{ {
......
...@@ -167,12 +167,10 @@ count(*) ...@@ -167,12 +167,10 @@ count(*)
150 150
EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')); EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range g g 32 NULL 4 Using where 1 SIMPLE t1 range g g 32 NULL 7 Using where
SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')); SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
fid AsText(g) fid AsText(g)
1 LINESTRING(150 150,150 150) 1 LINESTRING(150 150,150 150)
11 LINESTRING(140 140,160 160)
2 LINESTRING(149 149,151 151)
3 LINESTRING(148 148,152 152) 3 LINESTRING(148 148,152 152)
4 LINESTRING(147 147,153 153) 4 LINESTRING(147 147,153 153)
5 LINESTRING(146 146,154 154) 5 LINESTRING(146 146,154 154)
...@@ -181,6 +179,8 @@ fid AsText(g) ...@@ -181,6 +179,8 @@ fid AsText(g)
8 LINESTRING(143 143,157 157) 8 LINESTRING(143 143,157 157)
9 LINESTRING(142 142,158 158) 9 LINESTRING(142 142,158 158)
10 LINESTRING(141 141,159 159) 10 LINESTRING(141 141,159 159)
11 LINESTRING(140 140,160 160)
2 LINESTRING(149 149,151 151)
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t2 ( CREATE TABLE t2 (
fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY, fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
...@@ -305,10 +305,10 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -305,10 +305,10 @@ id select_type table type possible_keys key key_len ref rows Extra
SELECT fid, AsText(g) FROM t2 WHERE Within(g, SELECT fid, AsText(g) FROM t2 WHERE Within(g,
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))')); GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
fid AsText(g) fid AsText(g)
46 LINESTRING(51 41,60 50)
56 LINESTRING(41 41,50 50)
45 LINESTRING(51 51,60 60) 45 LINESTRING(51 51,60 60)
55 LINESTRING(41 51,50 60) 55 LINESTRING(41 51,50 60)
56 LINESTRING(41 41,50 50)
46 LINESTRING(51 41,60 50)
DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))))); DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))));
SELECT count(*) FROM t2; SELECT count(*) FROM t2;
count(*) count(*)
......
...@@ -398,7 +398,7 @@ bool Gis_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb) ...@@ -398,7 +398,7 @@ bool Gis_line_string::init_from_wkt(Gis_read_stream *trs, String *wkb)
if (trs->skip_char(',')) // Didn't find ',' if (trs->skip_char(',')) // Didn't find ','
break; break;
} }
if (n_points < 2) if (n_points < 1)
{ {
trs->set_error_msg("Too few points in LINESTRING"); trs->set_error_msg("Too few points in LINESTRING");
return 1; return 1;
...@@ -487,6 +487,11 @@ int Gis_line_string::is_closed(int *closed) const ...@@ -487,6 +487,11 @@ int Gis_line_string::is_closed(int *closed) const
if (no_data(data, 4)) if (no_data(data, 4))
return 1; return 1;
n_points= uint4korr(data); n_points= uint4korr(data);
if (n_points == 1)
{
*closed=1;
return 0;
}
data+= 4; data+= 4;
if (no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) if (no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points))
return 1; return 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment