/* Check if a intersects b.
Return false if a intersects b, otherwise true. */ #define INTERSECT_CMP(amin, amax, bmin, bmax) \
(((amin) > (bmax)) || ((bmin) > (amax)))
/* Check if b contains a.
Return false if b contains a, otherwise true. */ #define CONTAIN_CMP(amin, amax, bmin, bmax) \
(((bmin) > (amin)) || ((bmax) < (amax)))
/* Check if b is within a.
Return false if b is within a, otherwise true. */ #define WITHIN_CMP(amin, amax, bmin, bmax) \
(((amin) > (bmin)) || ((amax) < (bmax)))
/* Check if a disjoints b.
Return false if a disjoints b, otherwise true. */ #define DISJOINT_CMP(amin, amax, bmin, bmax) \
(((amin) <= (bmax)) && ((bmin) <= (amax)))
/* Check if a equals b.
Return false if equal, otherwise true. */ #define EQUAL_CMP(amin, amax, bmin, bmax) \
(((amin) != (bmin)) || ((amax) != (bmax)))
/**************************************************************** Functionsforgeneratingmbr
****************************************************************/ /*************************************************************//**
Add one point stored in wkb to a given mbr.
@return0if the point in wkb is valid, otherwise -1. */ static int
rtree_add_point_to_mbr( /*===================*/ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ double* mbr) /*!< in/out: mbr, which
must be of length n_dims * 2. */
{ double ord; double* mbr_end = mbr + n_dims * 2;
while (mbr < mbr_end) { if ((*wkb) + sizeof(double) > end) { return(-1);
}
ord = mach_double_read(*wkb);
(*wkb) += sizeof(double);
if (ord < *mbr) {
*mbr = ord;
}
mbr++;
if (ord > *mbr) {
*mbr = ord;
}
mbr++;
}
return(0);
}
/*************************************************************//**
Get mbr of point stored in wkb.
@return0if ok, otherwise -1. */ static int
rtree_get_point_mbr( /*================*/ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ double* mbr) /*!< in/out: mbr,
must be of length n_dims * 2. */
{ return rtree_add_point_to_mbr(wkb, end, n_dims, mbr);
}
/*************************************************************//**
Get mbr of linestring stored in wkb.
@return0if the linestring is valid, otherwise -1. */ static int
rtree_get_linestring_mbr( /*=====================*/ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ double* mbr) /*!< in/out: mbr,
must be of length n_dims * 2. */
{
uint n_points;
n_points = uint4korr(*wkb);
(*wkb) += 4;
for (; n_points > 0; --n_points) { /* Add next point to mbr */ if (rtree_add_point_to_mbr(wkb, end, n_dims, mbr)) { return(-1);
}
}
return(0);
}
/*************************************************************//**
Get mbr of polygon stored in wkb.
@return0if the polygon is valid, otherwise -1. */ static int
rtree_get_polygon_mbr( /*==================*/ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ double* mbr) /*!< in/out: mbr,
must be of length n_dims * 2. */
{
uint n_linear_rings;
uint n_points;
for (; n_points > 0; --n_points) { /* Add next point to mbr */ if (rtree_add_point_to_mbr(wkb, end, n_dims, mbr)) { return(-1);
}
}
}
return(0);
}
/*************************************************************//**
Get mbr of geometry stored in wkb.
@return0if the geometry is valid, otherwise -1. */ static int
rtree_get_geometry_mbr( /*===================*/ const uchar** wkb, /*!< in: pointer to wkb,
where point is stored. */ const uchar* end, /*!< in: end of wkb. */
uint n_dims, /*!< in: dimensions. */ double* mbr, /*!< in/out: mbr. */ int top) /*!< in: if it is the top, whichmeansit'snotcalled
by itself. */
{ int res;
uint wkb_type = 0;
uint n_items;
/* byte_order = *(*wkb); */
++(*wkb);
wkb_type = uint4korr((*wkb));
(*wkb) += 4;
switch ((enum wkbType) wkb_type) { case wkbPoint:
res = rtree_get_point_mbr(wkb, end, n_dims, mbr); break; case wkbLineString:
res = rtree_get_linestring_mbr(wkb, end, n_dims, mbr); break; case wkbPolygon:
res = rtree_get_polygon_mbr(wkb, end, n_dims, mbr); break; case wkbMultiPoint:
n_items = uint4korr((*wkb));
(*wkb) += 4; for (; n_items > 0; --n_items) { /* byte_order = *(*wkb); */
++(*wkb);
(*wkb) += 4; if (rtree_get_point_mbr(wkb, end, n_dims, mbr)) { return(-1);
}
}
res = 0; break; case wkbMultiLineString:
n_items = uint4korr((*wkb));
(*wkb) += 4; for (; n_items > 0; --n_items) { /* byte_order = *(*wkb); */
++(*wkb);
(*wkb) += 4; if (rtree_get_linestring_mbr(wkb, end, n_dims, mbr)) { return(-1);
}
}
res = 0; break; case wkbMultiPolygon:
n_items = uint4korr((*wkb));
(*wkb) += 4; for (; n_items > 0; --n_items) { /* byte_order = *(*wkb); */
++(*wkb);
(*wkb) += 4; if (rtree_get_polygon_mbr(wkb, end, n_dims, mbr)) { return(-1);
}
}
res = 0; break; case wkbGeometryCollection: if (!top) { return(-1);
}
n_items = uint4korr((*wkb));
(*wkb) += 4; for (; n_items > 0; --n_items) { if (rtree_get_geometry_mbr(wkb, end, n_dims,
mbr, 0)) { return(-1);
}
}
res = 0; break; default:
res = -1;
}
return(res);
}
/*************************************************************//**
Calculate Minimal Bounding Rectangle (MBR) of the spatial object
stored in "well-known binary representation" (wkb) format.
@return0if ok. */ int
rtree_mbr_from_wkb( /*===============*/ const uchar* wkb, /*!< in: wkb */
uint size, /*!< in: size of wkb. */
uint n_dims, /*!< in: dimensions. */ double* mbr) /*!< in/out: mbr, which must
be of length n_dim2 * 2. */
{ for (uint i = 0; i < n_dims; ++i) {
mbr[i * 2] = DBL_MAX;
mbr[i * 2 + 1] = -DBL_MAX;
}
/**************************************************************** FunctionsforRtreesplit
****************************************************************/ /*************************************************************//**
Join 2 mbrs of dimensions n_dim. */ static void
mbr_join( /*=====*/ double* a, /*!< in/out: the first mbr,
where the joined result will be. */ constdouble* b, /*!< in: the second mbr. */ int n_dim) /*!< in: dimensions. */
{ double* end = a + n_dim * 2;
do { if (a[0] > b[0]) {
a[0] = b[0];
}
if (a[1] < b[1]) {
a[1] = b[1];
}
a += 2;
b += 2;
} while (a != end);
}
/*************************************************************//**
Counts the square of mbr which is the join of a and b. Both a and b
are of dimensions n_dim. */ static double
mbr_join_square( /*============*/ constdouble* a, /*!< in: the first mbr. */ constdouble* b, /*!< in: the second mbr. */ int n_dim) /*!< in: dimensions. */
{ constdouble* end = a + n_dim * 2; double square = 1.0;
do {
square *= std::max(a[1], b[1]) - std::min(a[0], b[0]);
a += 2;
b += 2;
} while (a != end);
/* Check if finite (not infinity or NaN),
so we don't get NaN in calculations */ if (!std::isfinite(square)) { return DBL_MAX;
}
return square;
}
/*************************************************************//**
Counts the square of mbr of dimension n_dim. */ static double
count_square( /*=========*/ constdouble* a, /*!< in: the mbr. */ int n_dim) /*!< in: dimensions. */
{ constdouble* end = a + n_dim * 2; double square = 1.0;
do {
square *= a[1] - a[0];
a += 2;
} while (a != end);
/* Introduce some randomness if the record
is identical */ if (diff == 0) {
diff = static_cast<double>(ut_rnd_gen() & 1);
}
*n_group = 1 + (diff > 0);
*choice = cur;
}
}
}
/*************************************************************//**
Mark not-in-group entries as n_group. */ static void
mark_all_entries( /*=============*/
rtr_split_node_t* node, /*!< in/out: split nodes. */ int n_entries, /*!< in: entries number. */
uint16_t n_group) /*!< in: 1 or 2 */
{
rtr_split_node_t* cur = node;
rtr_split_node_t* end = node + n_entries; for (; cur < end; ++cur) { if (cur->n_node != 0) { continue;
}
cur->n_node = n_group;
}
}
/*************************************************************//**
Split rtree node. Return which group the first rec is in. */ int
split_rtree_node( /*=============*/
rtr_split_node_t* node, /*!< in: split nodes. */ int n_entries, /*!< in: entries number. */ int all_size, /*!< in: total key's size. */ int key_size, /*!< in: key's size. */ int min_size, /*!< in: minimal group size. */ int size1, /*!< in: size of group. */ int size2, /*!< in: initial group sizes */ double** d_buffer, /*!< in/out: buffer. */ int n_dim, /*!< in: dimensions. */
uchar* first_rec) /*!< in: the first rec. */
{
rtr_split_node_t* cur;
rtr_split_node_t* a = NULL;
rtr_split_node_t* b = NULL; double* g1 = reserve_coords(d_buffer, n_dim); double* g2 = reserve_coords(d_buffer, n_dim);
rtr_split_node_t* next = NULL;
uint16_t next_node = 0; int i; int first_rec_group = 1;
rtr_split_node_t* end = node + n_entries;
if (all_size < min_size * 2) { return1;
}
cur = node; for (; cur < end; ++cur) {
cur->square = count_square(cur->coords, n_dim);
cur->n_node = 0;
}
/* Find out where the first rec (of the page) will be at,
and inform the caller */ if (first_rec && first_rec == next->key) {
first_rec_group = next_node;
}
}
return(first_rec_group);
}
/** Compare two minimum bounding rectangles. @parammodecomparisonoperator MBR_INTERSECT(a,b)aoverlapsb MBR_CONTAIN(a,b)acontainsb MBR_DISJOINT(a,b)adisjointb MBR_WITHIN(a,b)awithinb MBR_EQUAL(a,b)AllcoordinatesofMBRsareequal MBR_DATA(a,b)Datareferenceisthesame @parambfirstMBR @paramasecondMBR @retval0ifthepredicateholds
@retval 1 if the precidate does not hold */ int rtree_key_cmp(page_cur_mode_t mode, constvoid *b, constvoid *a)
{ const byte *b_= static_cast<const byte*>(b); const byte *a_= static_cast<const byte*>(a);
switch (mode) { case PAGE_CUR_INTERSECT: if (INTERSECT_CMP(amin, amax, bmin, bmax)) return1; continue; case PAGE_CUR_CONTAIN: if (CONTAIN_CMP(amin, amax, bmin, bmax)) return1; continue; case PAGE_CUR_WITHIN: if (WITHIN_CMP(amin, amax, bmin, bmax)) return1; continue; case PAGE_CUR_MBR_EQUAL: if (EQUAL_CMP(amin, amax, bmin, bmax)) return1; continue; case PAGE_CUR_DISJOINT: if (!DISJOINT_CMP(amin, amax, bmin, bmax)) return0; if (!i) return1; continue; case PAGE_CUR_UNSUPP: case PAGE_CUR_G: case PAGE_CUR_GE: case PAGE_CUR_L: case PAGE_CUR_LE: case PAGE_CUR_RTREE_LOCATE: case PAGE_CUR_RTREE_GET_FATHER: case PAGE_CUR_RTREE_INSERT: break;
}
ut_ad("unknown comparison operator" == 0);
}
return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.