Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull to formatt a diff of uncompressed #1

Open
wants to merge 5 commits into
base: cubefetch
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions contrib/cube/Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# contrib/cube/Makefile

MODULE_big = cube
OBJS= cube.o cubeparse.o $(WIN32RES)
OBJS= cube.o spatialjoin.o joinnode.o cubeparse.o $(WIN32RES)


CUSTOM_COPT = -O3
#-msse4.2 -funroll-loops -ftree-vectorize -mavx

EXTENSION = cube
DATA = cube--1.2.sql cube--1.1--1.2.sql cube--1.0--1.1.sql \
DATA = cube--1.2--1.3.sql cube--1.2.sql cube--1.1--1.2.sql cube--1.0--1.1.sql \
cube--unpackaged--1.0.sql
PGFILEDESC = "cube - multidimensional cube data type"

Expand Down
8 changes: 8 additions & 0 deletions contrib/cube/cube--1.2--1.3.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* contrib/cube/cube--1.2--1.3.sql */

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.5'" to load this file. \quit


ALTER OPERATOR FAMILY gist_cube_ops USING gist ADD
FUNCTION 9 (cube, cube) g_cube_decompress (internal) ;
160 changes: 137 additions & 23 deletions contrib/cube/cube.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,19 @@ PG_FUNCTION_INFO_V1(cube_enlarge);
/*
** For internal use only
*/
int32 cube_cmp_v0(NDBOX *a, NDBOX *b);
bool cube_contains_v0(NDBOX *a, NDBOX *b);
bool cube_overlap_v0(NDBOX *a, NDBOX *b);
NDBOX *cube_union_v0(NDBOX *a, NDBOX *b);
void rt_cube_size(NDBOX *a, double *sz);
NDBOX *g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep);
bool g_cube_leaf_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy);
bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy);
static int32 cube_cmp_v0(NDBOX *a, NDBOX *b);
static bool cube_contains_v0(NDBOX *a, NDBOX *b);
static NDBOX *cube_union_v0(NDBOX *a, NDBOX *b);
static void rt_cube_size(NDBOX *a, double *sz);
static NDBOX *g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep);
static bool g_cube_leaf_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy);
static bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy);

/*
** Auxiliary funxtions
*/
static double distance_1D(double a1, double a2, double b1, double b2);
static bool cube_is_point_internal(NDBOX *cube);



/*****************************************************************************
Expand Down Expand Up @@ -402,6 +401,37 @@ g_cube_decompress(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(entry);
}

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;
}

static void
rt_cube_edge(NDBOX *a, double *size)
{
int i;
double result = 0;

if (a != (NDBOX *) NULL)
{
for (i = 0; i < DIM(a); i++)
result += Abs(UR_COORD(a, i) - LL_COORD(a, i));
}
*size = result;
return;
}


/*
** The GiST Penalty method for boxes
Expand All @@ -423,6 +453,26 @@ g_cube_penalty(PG_FUNCTION_ARGS)
rt_cube_size(DatumGetNDBOX(origentry->key), &tmp2);
*result = (float) (tmp1 - tmp2);

if( *result == 0 )
{
rt_cube_edge(ud, &tmp1);
rt_cube_edge(DatumGetNDBOX(origentry->key), &tmp2);
*result = (float) (tmp1 - tmp2);
if( *result == 0 )
{
*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);
}

Expand Down Expand Up @@ -481,10 +531,10 @@ g_cube_picksplit(PG_FUNCTION_ARGS)
/* compute the wasted space by unioning these guys */
/* size_waste = size_union - size_inter; */
union_d = cube_union_v0(datum_alpha, datum_beta);
rt_cube_size(union_d, &size_union);
rt_cube_edge(union_d, &size_union);
inter_d = DatumGetNDBOX(DirectFunctionCall2(cube_inter,
entryvec->vector[i].key, entryvec->vector[j].key));
rt_cube_size(inter_d, &size_inter);
rt_cube_edge(inter_d, &size_inter);
size_waste = size_union - size_inter;

/*
Expand All @@ -508,10 +558,10 @@ g_cube_picksplit(PG_FUNCTION_ARGS)

datum_alpha = DatumGetNDBOX(entryvec->vector[seed_1].key);
datum_l = cube_union_v0(datum_alpha, datum_alpha);
rt_cube_size(datum_l, &size_l);
rt_cube_edge(datum_l, &size_l);
datum_beta = DatumGetNDBOX(entryvec->vector[seed_2].key);
datum_r = cube_union_v0(datum_beta, datum_beta);
rt_cube_size(datum_r, &size_r);
rt_cube_edge(datum_r, &size_r);

/*
* Now split up the regions between the two seeds. An important property
Expand Down Expand Up @@ -551,8 +601,8 @@ g_cube_picksplit(PG_FUNCTION_ARGS)
datum_alpha = DatumGetNDBOX(entryvec->vector[i].key);
union_dl = cube_union_v0(datum_l, datum_alpha);
union_dr = cube_union_v0(datum_r, datum_alpha);
rt_cube_size(union_dl, &size_alpha);
rt_cube_size(union_dr, &size_beta);
rt_cube_edge(union_dl, &size_alpha);
rt_cube_edge(union_dr, &size_beta);

/* pick which page to add it to */
if (size_alpha - size_l < size_beta - size_r)
Expand Down Expand Up @@ -599,7 +649,7 @@ g_cube_same(PG_FUNCTION_ARGS)
/*
** SUPPORT ROUTINES
*/
bool
static bool
g_cube_leaf_consistent(NDBOX *key,
NDBOX *query,
StrategyNumber strategy)
Expand Down Expand Up @@ -628,7 +678,7 @@ g_cube_leaf_consistent(NDBOX *key,
return (retval);
}

bool
static bool
g_cube_internal_consistent(NDBOX *key,
NDBOX *query,
StrategyNumber strategy)
Expand All @@ -655,7 +705,7 @@ g_cube_internal_consistent(NDBOX *key,
return (retval);
}

NDBOX *
static NDBOX *
g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep)
{
NDBOX *retval;
Expand All @@ -668,7 +718,7 @@ g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep)


/* cube_union_v0 */
NDBOX *
static NDBOX *
cube_union_v0(NDBOX *a, NDBOX *b)
{
int i;
Expand Down Expand Up @@ -838,7 +888,7 @@ cube_size(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(result);
}

void
static void
rt_cube_size(NDBOX *a, double *size)
{
double result;
Expand All @@ -865,7 +915,7 @@ rt_cube_size(NDBOX *a, double *size)

/* 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
static int32
cube_cmp_v0(NDBOX *a, NDBOX *b)
{
int i;
Expand Down Expand Up @@ -1052,7 +1102,7 @@ cube_ge(PG_FUNCTION_ARGS)

/* Contains */
/* Box(A) CONTAINS Box(B) IFF pt(A) < pt(B) */
bool
static bool
cube_contains_v0(NDBOX *a, NDBOX *b)
{
int i;
Expand Down Expand Up @@ -1400,7 +1450,7 @@ cube_is_point(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(result);
}

static bool
bool
cube_is_point_internal(NDBOX *cube)
{
int i;
Expand Down Expand Up @@ -1725,3 +1775,67 @@ cube_c_f8_f8(PG_FUNCTION_ARGS)
PG_FREE_IF_COPY(cube, 0);
PG_RETURN_NDBOX(result);
}

NDBOX *
cube_intersect_v0(NDBOX *a, NDBOX *b)
{
int i;
NDBOX *result;
int dim;
int size;

/* trivial case */
if (a == b)
return a;

/* swap the arguments if needed, so that 'a' is always larger than 'b' */
if (DIM(a) < DIM(b))
{
NDBOX *tmp = b;

b = a;
a = tmp;
}
dim = DIM(a);

size = CUBE_SIZE(dim);
result = palloc0(size);
SET_VARSIZE(result, size);
SET_DIM(result, dim);

/* First compute the union of the dimensions present in both args */
for (i = 0; i < DIM(b); i++)
{
result->x[i] = Max(
Min(LL_COORD(a, i), UR_COORD(a, i)),
Min(LL_COORD(b, i), UR_COORD(b, i))
);
result->x[i + DIM(a)] = Min(
Max(LL_COORD(a, i), UR_COORD(a, i)),
Max(LL_COORD(b, i), UR_COORD(b, i))
);
}
/* continue on the higher dimensions only present in 'a' */
for (; i < DIM(a); i++)
{
result->x[i] = Max(0,
Min(LL_COORD(a, i), UR_COORD(a, i))
);
result->x[i + dim] = Min(0,
Max(LL_COORD(a, i), UR_COORD(a, i))
);
}

/*
* Check if the result was in fact a point, and set the flag in the datum
* accordingly. (we don't bother to repalloc it smaller)
*/
if (cube_is_point_internal(result))
{
size = POINT_SIZE(dim);
SET_VARSIZE(result, size);
SET_POINT_BIT(result);
}

return (result);
}
2 changes: 1 addition & 1 deletion contrib/cube/cube.control
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# cube extension
comment = 'data type for multidimensional cubes'
default_version = '1.2'
default_version = '1.3'
module_pathname = '$libdir/cube'
relocatable = true
5 changes: 5 additions & 0 deletions contrib/cube/cubedata.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,8 @@ extern void cube_scanner_finish(void);

/* in cubeparse.y */
extern int cube_yyparse(NDBOX **result);

extern bool cube_overlap_v0(NDBOX *a, NDBOX *b);

extern NDBOX *cube_intersect_v0(NDBOX *a, NDBOX *b);
extern bool cube_is_point_internal(NDBOX *cube);
19 changes: 19 additions & 0 deletions contrib/cube/expected/cube.out
Original file line number Diff line number Diff line change
Expand Up @@ -1701,6 +1701,25 @@ SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordi
(46151, 49848),(46058, 49830)
(15 rows)

-- Test Index Only Scans
SET ENABLE_BITMAPSCAN = FALSE;
EXPLAIN (COSTS OFF) SELECT c FROM test_cube WHERE c <@ '(3000,1000),(0,0)';
QUERY PLAN
--------------------------------------------------
Index Only Scan using test_cube_ix on test_cube
Index Cond: (c <@ '(3000, 1000),(0, 0)'::cube)
(2 rows)

SELECT c FROM test_cube WHERE c <@ '(3000,1000),(0,0)';
c
-------------------------
(2424, 160),(2424, 81)
(759, 187),(662, 163)
(1444, 403),(1346, 344)
(337, 455),(240, 359)
(4 rows)

SET ENABLE_BITMAPSCAN = TRUE;
-- same thing for index with points
CREATE TABLE test_point(c cube);
INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
Expand Down
Loading