From 9a42d7c7879499ec1a9d4a0dd9e7286fec26bbfa Mon Sep 17 00:00:00 2001 From: fantomancer <36892384+fantomancer@users.noreply.github.com> Date: Tue, 1 May 2018 02:08:41 +0500 Subject: [PATCH 1/3] Update cube.c --- contrib/cube/cube.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c index d96ca1ec1fda1..bf4cd19b0ff91 100644 --- a/contrib/cube/cube.c +++ b/contrib/cube/cube.c @@ -419,8 +419,8 @@ g_cube_penalty(PG_FUNCTION_ARGS) ud = cube_union_v0(DatumGetNDBOXP(origentry->key), DatumGetNDBOXP(newentry->key)); - rt_cube_size(ud, &tmp1); - rt_cube_size(DatumGetNDBOXP(origentry->key), &tmp2); + rt_cube_perimeter(ud, &tmp1); + rt_cube_perimeter(DatumGetNDBOXP(origentry->key), &tmp2); *result = (float) (tmp1 - tmp2); PG_RETURN_FLOAT8(*result); @@ -840,30 +840,22 @@ cube_size(PG_FUNCTION_ARGS) } void -rt_cube_size(NDBOX *a, double *size) +rt_cube_perimeter(NDBOX *a, double *size) { - double result; int i; if (a == (NDBOX *) NULL) - { - /* special case for GiST */ - result = 0.0; - } - else if (IS_POINT(a) || DIM(a) == 0) - { - /* necessarily has zero size */ - result = 0.0; - } + *size = 0.0; else { - result = 1.0; + *size = 0.0; for (i = 0; i < DIM(a); i++) - result *= Abs(UR_COORD(a, i) - LL_COORD(a, i)); + *size = (*size) + Abs(UR_COORD(a, i) - LL_COORD(a, i)); } - *size = result; + return; } + /* make up a metric in which one box will be 'lower' than the other -- this can be useful for sorting and to determine uniqueness */ int32 From 14317b89302ad076f7237c691bfc44cdd0d09f86 Mon Sep 17 00:00:00 2001 From: fantomancer <36892384+fantomancer@users.noreply.github.com> Date: Tue, 1 May 2018 02:26:47 +0500 Subject: [PATCH 2/3] Update cube.c --- contrib/cube/cube.c | 55 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c index bf4cd19b0ff91..5217c9e364c95 100644 --- a/contrib/cube/cube.c +++ b/contrib/cube/cube.c @@ -419,9 +419,43 @@ g_cube_penalty(PG_FUNCTION_ARGS) ud = cube_union_v0(DatumGetNDBOXP(origentry->key), DatumGetNDBOXP(newentry->key)); - rt_cube_perimeter(ud, &tmp1); - rt_cube_perimeter(DatumGetNDBOXP(origentry->key), &tmp2); + rt_cube_size(ud, &tmp1); + rt_cube_size(DatumGetNDBOXP(origentry->key), &tmp2); *result = (float) (tmp1 - tmp2); + /* Realm tricks are used only in case of IEEE754 support(IEC 60559) */ + + /* REALM 0: No extension is required, volume is zero, return edge */ + /* REALM 1: No extension is required, return nonzero volume */ + /* REALM 2: Volume extension is zero, return nonzero edge extension */ + /* REALM 3: Volume extension is nonzero, return it */ + + if( *result == 0 ) + { + double tmp3 = tmp1; /* remember entry volume */ + rt_cube_perimeter(ud, &tmp1); + rt_cube_perimeter(DatumGetNDBOX(origentry->key), &tmp2); + *result = (float) (tmp1 - tmp2); + if( *result == 0 ) + { + if( tmp3 != 0 ) + { + *result = pack_float(tmp3, 1); /* REALM 1 */ + } + else + { + *result = pack_float(tmp1, 0); /* REALM 0 */ + } + } + else + { + *result = pack_float(*result, 2); /* REALM 2 */ + } + } + else + { + *result = pack_float(*result, 3); /* REALM 3 */ + } + PG_RETURN_FLOAT8(*result); } @@ -1438,6 +1472,23 @@ distance_1D(double a1, double a2, double b1, double b2) return 0.0; } +static float +pack_float(const float value, const int realm) +{ + union { + float f; + struct { unsigned value:31, sign:1; } vbits; + struct { unsigned value:29, realm:2, sign:1; } rbits; + } a; + + a.f = value; + a.rbits.value = a.vbits.value >> 2; + a.rbits.realm = realm; + + return a.f; +} + + /* Test if a box is also a point */ Datum cube_is_point(PG_FUNCTION_ARGS) From 6349798b980f6e0baad066a8b430ef627c75a3f3 Mon Sep 17 00:00:00 2001 From: fantomancer <36892384+fantomancer@users.noreply.github.com> Date: Tue, 1 May 2018 02:35:49 +0500 Subject: [PATCH 3/3] Update cube.c --- contrib/cube/cube.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c index 5217c9e364c95..057c0e9b013d7 100644 --- a/contrib/cube/cube.c +++ b/contrib/cube/cube.c @@ -874,19 +874,28 @@ cube_size(PG_FUNCTION_ARGS) } void -rt_cube_perimeter(NDBOX *a, double *size) +rt_cube_size(NDBOX *a, double *size) { + double result; int i; if (a == (NDBOX *) NULL) - *size = 0.0; + { + /* special case for GiST */ + result = 0.0; + } + else if (IS_POINT(a) || DIM(a) == 0) + { + /* necessarily has zero size */ + result = 0.0; + } else { - *size = 0.0; + result = 1.0; for (i = 0; i < DIM(a); i++) - *size = (*size) + Abs(UR_COORD(a, i) - LL_COORD(a, i)); + result *= Abs(UR_COORD(a, i) - LL_COORD(a, i)); } - return; + *size = result; }