Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions | Variables

cube.c File Reference

#include "postgres.h"
#include <float.h>
#include <math.h>
#include "access/gist.h"
#include "access/skey.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "cubedata.h"
Include dependency graph for cube.c:

Go to the source code of this file.

Defines

#define ARRPTR(x)   ( (double *) ARR_DATA_PTR(x) )
#define ARRNELEMS(x)   ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))

Functions

int cube_yyparse ()
void cube_yyerror (const char *message)
void cube_scanner_init (const char *str)
void cube_scanner_finish (void)
 PG_FUNCTION_INFO_V1 (cube_in)
 PG_FUNCTION_INFO_V1 (cube_a_f8_f8)
 PG_FUNCTION_INFO_V1 (cube_a_f8)
 PG_FUNCTION_INFO_V1 (cube_out)
 PG_FUNCTION_INFO_V1 (cube_f8)
 PG_FUNCTION_INFO_V1 (cube_f8_f8)
 PG_FUNCTION_INFO_V1 (cube_c_f8)
 PG_FUNCTION_INFO_V1 (cube_c_f8_f8)
 PG_FUNCTION_INFO_V1 (cube_dim)
 PG_FUNCTION_INFO_V1 (cube_ll_coord)
 PG_FUNCTION_INFO_V1 (cube_ur_coord)
 PG_FUNCTION_INFO_V1 (cube_subset)
Datum cube_in (PG_FUNCTION_ARGS)
Datum cube_a_f8_f8 (PG_FUNCTION_ARGS)
Datum cube_a_f8 (PG_FUNCTION_ARGS)
Datum cube_out (PG_FUNCTION_ARGS)
Datum cube_f8 (PG_FUNCTION_ARGS)
Datum cube_f8_f8 (PG_FUNCTION_ARGS)
Datum cube_c_f8 (PG_FUNCTION_ARGS)
Datum cube_c_f8_f8 (PG_FUNCTION_ARGS)
Datum cube_dim (PG_FUNCTION_ARGS)
Datum cube_ll_coord (PG_FUNCTION_ARGS)
Datum cube_ur_coord (PG_FUNCTION_ARGS)
Datum cube_subset (PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1 (g_cube_consistent)
 PG_FUNCTION_INFO_V1 (g_cube_compress)
 PG_FUNCTION_INFO_V1 (g_cube_decompress)
 PG_FUNCTION_INFO_V1 (g_cube_penalty)
 PG_FUNCTION_INFO_V1 (g_cube_picksplit)
 PG_FUNCTION_INFO_V1 (g_cube_union)
 PG_FUNCTION_INFO_V1 (g_cube_same)
Datum g_cube_consistent (PG_FUNCTION_ARGS)
Datum g_cube_compress (PG_FUNCTION_ARGS)
Datum g_cube_decompress (PG_FUNCTION_ARGS)
Datum g_cube_penalty (PG_FUNCTION_ARGS)
Datum g_cube_picksplit (PG_FUNCTION_ARGS)
Datum g_cube_union (PG_FUNCTION_ARGS)
Datum g_cube_same (PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1 (cube_eq)
 PG_FUNCTION_INFO_V1 (cube_ne)
 PG_FUNCTION_INFO_V1 (cube_lt)
 PG_FUNCTION_INFO_V1 (cube_gt)
 PG_FUNCTION_INFO_V1 (cube_le)
 PG_FUNCTION_INFO_V1 (cube_ge)
 PG_FUNCTION_INFO_V1 (cube_cmp)
Datum cube_eq (PG_FUNCTION_ARGS)
Datum cube_ne (PG_FUNCTION_ARGS)
Datum cube_lt (PG_FUNCTION_ARGS)
Datum cube_gt (PG_FUNCTION_ARGS)
Datum cube_le (PG_FUNCTION_ARGS)
Datum cube_ge (PG_FUNCTION_ARGS)
Datum cube_cmp (PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1 (cube_contains)
 PG_FUNCTION_INFO_V1 (cube_contained)
 PG_FUNCTION_INFO_V1 (cube_overlap)
 PG_FUNCTION_INFO_V1 (cube_union)
 PG_FUNCTION_INFO_V1 (cube_inter)
 PG_FUNCTION_INFO_V1 (cube_size)
Datum cube_contains (PG_FUNCTION_ARGS)
Datum cube_contained (PG_FUNCTION_ARGS)
Datum cube_overlap (PG_FUNCTION_ARGS)
Datum cube_union (PG_FUNCTION_ARGS)
Datum cube_inter (PG_FUNCTION_ARGS)
Datum cube_size (PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1 (cube_distance)
 PG_FUNCTION_INFO_V1 (cube_is_point)
 PG_FUNCTION_INFO_V1 (cube_enlarge)
Datum cube_distance (PG_FUNCTION_ARGS)
Datum cube_is_point (PG_FUNCTION_ARGS)
Datum cube_enlarge (PG_FUNCTION_ARGS)
int32 cube_cmp_v0 (NDBOX *a, NDBOX *b)
bool cube_contains_v0 (NDBOX *a, NDBOX *b)
bool cube_overlap_v0 (NDBOX *a, NDBOX *b)
NDBOXcube_union_v0 (NDBOX *a, NDBOX *b)
void rt_cube_size (NDBOX *a, double *sz)
NDBOXg_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 double distance_1D (double a1, double a2, double b1, double b2)

Variables

 PG_MODULE_MAGIC

Define Documentation

#define ARRNELEMS (   x  )     ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
#define ARRPTR (   x  )     ( (double *) ARR_DATA_PTR(x) )

Function Documentation

Datum cube_a_f8 ( PG_FUNCTION_ARGS   ) 

Definition at line 219 of file cube.c.

References array_contains_nulls(), ARRNELEMS, ARRPTR, NDBOX::dim, ereport, errcode(), errmsg(), ERROR, i, offsetof, palloc0(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_NDBOX, SET_VARSIZE, and NDBOX::x.

{
    ArrayType  *ur = PG_GETARG_ARRAYTYPE_P(0);
    NDBOX      *result;
    int         i;
    int         dim;
    int         size;
    double     *dur;

    if (array_contains_nulls(ur))
        ereport(ERROR,
                (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
                 errmsg("cannot work with arrays containing NULLs")));

    dim = ARRNELEMS(ur);

    dur = ARRPTR(ur);

    size = offsetof(NDBOX, x[0]) +sizeof(double) * 2 * dim;
    result = (NDBOX *) palloc0(size);
    SET_VARSIZE(result, size);
    result->dim = dim;

    for (i = 0; i < dim; i++)
    {
        result->x[i] = dur[i];
        result->x[i + dim] = dur[i];
    }

    PG_RETURN_NDBOX(result);
}

Datum cube_a_f8_f8 ( PG_FUNCTION_ARGS   ) 

Definition at line 176 of file cube.c.

References array_contains_nulls(), ARRNELEMS, ARRPTR, NDBOX::dim, ereport, errcode(), errmsg(), ERROR, i, offsetof, palloc0(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_NDBOX, SET_VARSIZE, and NDBOX::x.

{
    ArrayType  *ur = PG_GETARG_ARRAYTYPE_P(0);
    ArrayType  *ll = PG_GETARG_ARRAYTYPE_P(1);
    NDBOX      *result;
    int         i;
    int         dim;
    int         size;
    double     *dur,
               *dll;

    if (array_contains_nulls(ur) || array_contains_nulls(ll))
        ereport(ERROR,
                (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
                 errmsg("cannot work with arrays containing NULLs")));

    dim = ARRNELEMS(ur);
    if (ARRNELEMS(ll) != dim)
        ereport(ERROR,
                (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
                 errmsg("UR and LL arrays must be of same length")));

    dur = ARRPTR(ur);
    dll = ARRPTR(ll);

    size = offsetof(NDBOX, x[0]) +sizeof(double) * 2 * dim;
    result = (NDBOX *) palloc0(size);
    SET_VARSIZE(result, size);
    result->dim = dim;

    for (i = 0; i < dim; i++)
    {
        result->x[i] = dur[i];
        result->x[i + dim] = dll[i];
    }

    PG_RETURN_NDBOX(result);
}

Datum cube_c_f8 ( PG_FUNCTION_ARGS   ) 

Definition at line 1447 of file cube.c.

References NDBOX::dim, i, offsetof, palloc0(), PG_FREE_IF_COPY, PG_GETARG_FLOAT8, PG_GETARG_NDBOX, PG_RETURN_NDBOX, SET_VARSIZE, and NDBOX::x.

{
    NDBOX      *c = PG_GETARG_NDBOX(0);
    double      x = PG_GETARG_FLOAT8(1);
    NDBOX      *result;
    int         size;
    int         i;

    size = offsetof(NDBOX, x[0]) +sizeof(double) * (c->dim + 1) *2;
    result = (NDBOX *) palloc0(size);
    SET_VARSIZE(result, size);
    result->dim = c->dim + 1;
    for (i = 0; i < c->dim; i++)
    {
        result->x[i] = c->x[i];
        result->x[result->dim + i] = c->x[c->dim + i];
    }
    result->x[result->dim - 1] = x;
    result->x[2 * result->dim - 1] = x;

    PG_FREE_IF_COPY(c, 0);
    PG_RETURN_NDBOX(result);
}

Datum cube_c_f8_f8 ( PG_FUNCTION_ARGS   ) 

Definition at line 1473 of file cube.c.

References NDBOX::dim, i, offsetof, palloc0(), PG_FREE_IF_COPY, PG_GETARG_FLOAT8, PG_GETARG_NDBOX, PG_RETURN_NDBOX, SET_VARSIZE, and NDBOX::x.

{
    NDBOX      *c = PG_GETARG_NDBOX(0);
    double      x1 = PG_GETARG_FLOAT8(1);
    double      x2 = PG_GETARG_FLOAT8(2);
    NDBOX      *result;
    int         size;
    int         i;

    size = offsetof(NDBOX, x[0]) +sizeof(double) * (c->dim + 1) *2;
    result = (NDBOX *) palloc0(size);
    SET_VARSIZE(result, size);
    result->dim = c->dim + 1;
    for (i = 0; i < c->dim; i++)
    {
        result->x[i] = c->x[i];
        result->x[result->dim + i] = c->x[c->dim + i];
    }
    result->x[result->dim - 1] = x1;
    result->x[2 * result->dim - 1] = x2;

    PG_FREE_IF_COPY(c, 0);
    PG_RETURN_NDBOX(result);
}

Datum cube_cmp ( PG_FUNCTION_ARGS   ) 

Definition at line 987 of file cube.c.

References cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_INT32.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    int32       res;

    res = cube_cmp_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_INT32(res);
}

int32 cube_cmp_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 907 of file cube.c.

References NDBOX::dim, i, Max, Min, and NDBOX::x.

Referenced by cube_cmp(), cube_eq(), cube_ge(), cube_gt(), cube_le(), cube_lt(), cube_ne(), g_cube_leaf_consistent(), and g_cube_same().

{
    int         i;
    int         dim;

    dim = Min(a->dim, b->dim);

    /* compare the common dimensions */
    for (i = 0; i < dim; i++)
    {
        if (Min(a->x[i], a->x[a->dim + i]) >
            Min(b->x[i], b->x[b->dim + i]))
            return 1;
        if (Min(a->x[i], a->x[a->dim + i]) <
            Min(b->x[i], b->x[b->dim + i]))
            return -1;
    }
    for (i = 0; i < dim; i++)
    {
        if (Max(a->x[i], a->x[a->dim + i]) >
            Max(b->x[i], b->x[b->dim + i]))
            return 1;
        if (Max(a->x[i], a->x[a->dim + i]) <
            Max(b->x[i], b->x[b->dim + i]))
            return -1;
    }

    /* compare extra dimensions to zero */
    if (a->dim > b->dim)
    {
        for (i = dim; i < a->dim; i++)
        {
            if (Min(a->x[i], a->x[a->dim + i]) > 0)
                return 1;
            if (Min(a->x[i], a->x[a->dim + i]) < 0)
                return -1;
        }
        for (i = dim; i < a->dim; i++)
        {
            if (Max(a->x[i], a->x[a->dim + i]) > 0)
                return 1;
            if (Max(a->x[i], a->x[a->dim + i]) < 0)
                return -1;
        }

        /*
         * if all common dimensions are equal, the cube with more dimensions
         * wins
         */
        return 1;
    }
    if (a->dim < b->dim)
    {
        for (i = dim; i < b->dim; i++)
        {
            if (Min(b->x[i], b->x[b->dim + i]) > 0)
                return -1;
            if (Min(b->x[i], b->x[b->dim + i]) < 0)
                return 1;
        }
        for (i = dim; i < b->dim; i++)
        {
            if (Max(b->x[i], b->x[b->dim + i]) > 0)
                return -1;
            if (Max(b->x[i], b->x[b->dim + i]) < 0)
                return 1;
        }

        /*
         * if all common dimensions are equal, the cube with more dimensions
         * wins
         */
        return -1;
    }

    /* They're really equal */
    return 0;
}

Datum cube_contained ( PG_FUNCTION_ARGS   ) 

Definition at line 1148 of file cube.c.

References cube_contains_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    bool        res;

    res = cube_contains_v0(b, a);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res);
}

Datum cube_contains ( PG_FUNCTION_ARGS   ) 

Definition at line 1132 of file cube.c.

References cube_contains_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    bool        res;

    res = cube_contains_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res);
}

bool cube_contains_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 1094 of file cube.c.

References NDBOX::dim, FALSE, i, Max, Min, NULL, TRUE, and NDBOX::x.

Referenced by cube_contained(), cube_contains(), g_cube_internal_consistent(), and g_cube_leaf_consistent().

{
    int         i;

    if ((a == NULL) || (b == NULL))
        return (FALSE);

    if (a->dim < b->dim)
    {
        /*
         * the further comparisons will make sense if the excess dimensions of
         * (b) were zeroes Since both UL and UR coordinates must be zero, we
         * can check them all without worrying about which is which.
         */
        for (i = a->dim; i < b->dim; i++)
        {
            if (b->x[i] != 0)
                return (FALSE);
            if (b->x[i + b->dim] != 0)
                return (FALSE);
        }
    }

    /* Can't care less about the excess dimensions of (a), if any */
    for (i = 0; i < Min(a->dim, b->dim); i++)
    {
        if (Min(a->x[i], a->x[a->dim + i]) >
            Min(b->x[i], b->x[b->dim + i]))
            return (FALSE);
        if (Max(a->x[i], a->x[a->dim + i]) <
            Max(b->x[i], b->x[b->dim + i]))
            return (FALSE);
    }

    return (TRUE);
}

Datum cube_dim ( PG_FUNCTION_ARGS   ) 

Definition at line 1312 of file cube.c.

References NDBOX::dim, PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_INT32.

{
    NDBOX      *c = PG_GETARG_NDBOX(0);
    int         dim = c->dim;

    PG_FREE_IF_COPY(c, 0);
    PG_RETURN_INT32(dim);
}

Datum cube_distance ( PG_FUNCTION_ARGS   ) 

Definition at line 1229 of file cube.c.

References NDBOX::dim, distance_1D(), i, PG_FREE_IF_COPY, PG_GETARG_NDBOX, PG_RETURN_FLOAT8, and NDBOX::x.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    bool        swapped = false;
    double      d,
                distance;
    int         i;

    /* swap the box pointers if needed */
    if (a->dim < b->dim)
    {
        NDBOX      *tmp = b;

        b = a;
        a = tmp;
        swapped = true;
    }

    distance = 0.0;
    /* compute within the dimensions of (b) */
    for (i = 0; i < b->dim; i++)
    {
        d = distance_1D(a->x[i], a->x[i + a->dim], b->x[i], b->x[i + b->dim]);
        distance += d * d;
    }

    /* compute distance to zero for those dimensions in (a) absent in (b) */
    for (i = b->dim; i < a->dim; i++)
    {
        d = distance_1D(a->x[i], a->x[i + a->dim], 0.0, 0.0);
        distance += d * d;
    }

    if (swapped)
    {
        PG_FREE_IF_COPY(b, 0);
        PG_FREE_IF_COPY(a, 1);
    }
    else
    {
        PG_FREE_IF_COPY(a, 0);
        PG_FREE_IF_COPY(b, 1);
    }

    PG_RETURN_FLOAT8(sqrt(distance));
}

Datum cube_enlarge ( PG_FUNCTION_ARGS   ) 

Definition at line 1357 of file cube.c.

References CUBE_MAX_DIM, NDBOX::dim, i, offsetof, palloc0(), PG_FREE_IF_COPY, PG_GETARG_FLOAT8, PG_GETARG_INT32, PG_GETARG_NDBOX, PG_RETURN_NDBOX, SET_VARSIZE, and NDBOX::x.

{
    NDBOX      *a = PG_GETARG_NDBOX(0);
    double      r = PG_GETARG_FLOAT8(1);
    int32       n = PG_GETARG_INT32(2);
    NDBOX      *result;
    int         dim = 0;
    int         size;
    int         i,
                j,
                k;

    if (n > CUBE_MAX_DIM)
        n = CUBE_MAX_DIM;
    if (r > 0 && n > 0)
        dim = n;
    if (a->dim > dim)
        dim = a->dim;
    size = offsetof(NDBOX, x[0]) +sizeof(double) * dim * 2;
    result = (NDBOX *) palloc0(size);
    SET_VARSIZE(result, size);
    result->dim = dim;
    for (i = 0, j = dim, k = a->dim; i < a->dim; i++, j++, k++)
    {
        if (a->x[i] >= a->x[k])
        {
            result->x[i] = a->x[k] - r;
            result->x[j] = a->x[i] + r;
        }
        else
        {
            result->x[i] = a->x[i] - r;
            result->x[j] = a->x[k] + r;
        }
        if (result->x[i] > result->x[j])
        {
            result->x[i] = (result->x[i] + result->x[j]) / 2;
            result->x[j] = result->x[i];
        }
    }
    /* dim > a->dim only if r > 0 */
    for (; i < dim; i++, j++)
    {
        result->x[i] = -r;
        result->x[j] = r;
    }

    PG_FREE_IF_COPY(a, 0);
    PG_RETURN_NDBOX(result);
}

Datum cube_eq ( PG_FUNCTION_ARGS   ) 

Definition at line 1002 of file cube.c.

References cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    int32       res;

    res = cube_cmp_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res == 0);
}

Datum cube_f8 ( PG_FUNCTION_ARGS   ) 

Definition at line 1410 of file cube.c.

References NDBOX::dim, offsetof, palloc0(), PG_GETARG_FLOAT8, PG_RETURN_NDBOX, SET_VARSIZE, and NDBOX::x.

{
    double      x = PG_GETARG_FLOAT8(0);
    NDBOX      *result;
    int         size;

    size = offsetof(NDBOX, x[0]) +sizeof(double) * 2;
    result = (NDBOX *) palloc0(size);
    SET_VARSIZE(result, size);
    result->dim = 1;
    result->x[0] = result->x[1] = x;

    PG_RETURN_NDBOX(result);
}

Datum cube_f8_f8 ( PG_FUNCTION_ARGS   ) 

Definition at line 1427 of file cube.c.

References NDBOX::dim, offsetof, palloc0(), PG_GETARG_FLOAT8, PG_RETURN_NDBOX, SET_VARSIZE, and NDBOX::x.

{
    double      x0 = PG_GETARG_FLOAT8(0);
    double      x1 = PG_GETARG_FLOAT8(1);
    NDBOX      *result;
    int         size;

    size = offsetof(NDBOX, x[0]) +sizeof(double) * 2;
    result = (NDBOX *) palloc0(size);
    SET_VARSIZE(result, size);
    result->dim = 1;
    result->x[0] = x0;
    result->x[1] = x1;

    PG_RETURN_NDBOX(result);
}

Datum cube_ge ( PG_FUNCTION_ARGS   ) 

Definition at line 1077 of file cube.c.

References cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    int32       res;

    res = cube_cmp_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res >= 0);
}

Datum cube_gt ( PG_FUNCTION_ARGS   ) 

Definition at line 1047 of file cube.c.

References cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    int32       res;

    res = cube_cmp_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res > 0);
}

Datum cube_in ( PG_FUNCTION_ARGS   ) 

Definition at line 156 of file cube.c.

References cube_scanner_finish(), cube_scanner_init(), cube_yyerror(), cube_yyparse(), PG_GETARG_CSTRING, and PG_RETURN_NDBOX.

{
    char       *str = PG_GETARG_CSTRING(0);
    void       *result;

    cube_scanner_init(str);

    if (cube_yyparse(&result) != 0)
        cube_yyerror("bogus input");

    cube_scanner_finish();

    PG_RETURN_NDBOX(result);
}

Datum cube_inter ( PG_FUNCTION_ARGS   ) 

Definition at line 798 of file cube.c.

References NDBOX::dim, i, Max, Min, palloc0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, PG_RETURN_NDBOX, SET_VARSIZE, VARSIZE, and NDBOX::x.

Referenced by g_cube_picksplit().

{
    NDBOX      *a = PG_GETARG_NDBOX(0);
    NDBOX      *b = PG_GETARG_NDBOX(1);
    NDBOX      *result;
    bool        swapped = false;
    int         i;

    if (a->dim >= b->dim)
    {
        result = palloc0(VARSIZE(a));
        SET_VARSIZE(result, VARSIZE(a));
        result->dim = a->dim;
    }
    else
    {
        result = palloc0(VARSIZE(b));
        SET_VARSIZE(result, VARSIZE(b));
        result->dim = b->dim;
    }

    /* swap the box pointers if needed */
    if (a->dim < b->dim)
    {
        NDBOX      *tmp = b;

        b = a;
        a = tmp;
        swapped = true;
    }

    /*
     * use the potentially  smaller of the two boxes (b) to fill in the
     * result, padding absent dimensions with zeroes
     */
    for (i = 0; i < b->dim; i++)
    {
        result->x[i] = Min(b->x[i], b->x[i + b->dim]);
        result->x[i + a->dim] = Max(b->x[i], b->x[i + b->dim]);
    }
    for (i = b->dim; i < a->dim; i++)
    {
        result->x[i] = 0;
        result->x[i + a->dim] = 0;
    }

    /* compute the intersection */
    for (i = 0; i < a->dim; i++)
    {
        result->x[i] =
            Max(Min(a->x[i], a->x[i + a->dim]), result->x[i]);
        result->x[i + a->dim] = Min(Max(a->x[i],
                                   a->x[i + a->dim]), result->x[i + a->dim]);
    }

    if (swapped)
    {
        PG_FREE_IF_COPY(b, 0);
        PG_FREE_IF_COPY(a, 1);
    }
    else
    {
        PG_FREE_IF_COPY(a, 0);
        PG_FREE_IF_COPY(b, 1);
    }

    /*
     * Is it OK to return a non-null intersection for non-overlapping boxes?
     */
    PG_RETURN_NDBOX(result);
}

Datum cube_is_point ( PG_FUNCTION_ARGS   ) 

Definition at line 1294 of file cube.c.

References NDBOX::dim, FALSE, i, PG_FREE_IF_COPY, PG_GETARG_NDBOX, PG_RETURN_BOOL, TRUE, and NDBOX::x.

{
    NDBOX      *a = PG_GETARG_NDBOX(0);
    int         i,
                j;

    for (i = 0, j = a->dim; i < a->dim; i++, j++)
    {
        if (a->x[i] != a->x[j])
            PG_RETURN_BOOL(FALSE);
    }

    PG_FREE_IF_COPY(a, 0);
    PG_RETURN_BOOL(TRUE);
}

Datum cube_le ( PG_FUNCTION_ARGS   ) 

Definition at line 1062 of file cube.c.

References cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    int32       res;

    res = cube_cmp_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res <= 0);
}

Datum cube_ll_coord ( PG_FUNCTION_ARGS   ) 

Definition at line 1323 of file cube.c.

References NDBOX::dim, Min, PG_FREE_IF_COPY, PG_GETARG_INT16, PG_GETARG_NDBOX, PG_RETURN_FLOAT8, and NDBOX::x.

{
    NDBOX      *c = PG_GETARG_NDBOX(0);
    int         n = PG_GETARG_INT16(1);
    double      result;

    if (c->dim >= n && n > 0)
        result = Min(c->x[n - 1], c->x[c->dim + n - 1]);
    else
        result = 0;

    PG_FREE_IF_COPY(c, 0);
    PG_RETURN_FLOAT8(result);
}

Datum cube_lt ( PG_FUNCTION_ARGS   ) 

Definition at line 1032 of file cube.c.

References cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    int32       res;

    res = cube_cmp_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res < 0);
}

Datum cube_ne ( PG_FUNCTION_ARGS   ) 

Definition at line 1017 of file cube.c.

References cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    int32       res;

    res = cube_cmp_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res != 0);
}

Datum cube_out ( PG_FUNCTION_ARGS   ) 

Definition at line 293 of file cube.c.

References appendStringInfo(), appendStringInfoChar(), buf, StringInfoData::data, NDBOX::dim, equal(), extra_float_digits, i, initStringInfo(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, PG_RETURN_CSTRING, and NDBOX::x.

{
    NDBOX      *cube = PG_GETARG_NDBOX(0);
    StringInfoData buf;
    int         dim = cube->dim;
    bool        equal = true;
    int         i;
    int         ndig;

    initStringInfo(&buf);

    /*
     * Get the number of digits to display.
     */
    ndig = DBL_DIG + extra_float_digits;
    if (ndig < 1)
        ndig = 1;

    /*
     * while printing the first (LL) corner, check if it is equal to the
     * second one
     */
    appendStringInfoChar(&buf, '(');
    for (i = 0; i < dim; i++)
    {
        if (i > 0)
            appendStringInfo(&buf, ", ");
        appendStringInfo(&buf, "%.*g", ndig, cube->x[i]);
        if (cube->x[i] != cube->x[i + dim])
            equal = false;
    }
    appendStringInfoChar(&buf, ')');

    if (!equal)
    {
        appendStringInfo(&buf, ",(");
        for (i = 0; i < dim; i++)
        {
            if (i > 0)
                appendStringInfo(&buf, ", ");
            appendStringInfo(&buf, "%.*g", ndig, cube->x[i + dim]);
        }
        appendStringInfoChar(&buf, ')');
    }

    PG_FREE_IF_COPY(cube, 0);
    PG_RETURN_CSTRING(buf.data);
}

Datum cube_overlap ( PG_FUNCTION_ARGS   ) 

Definition at line 1209 of file cube.c.

References cube_overlap_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_BOOL.

{
    NDBOX      *a = PG_GETARG_NDBOX(0),
               *b = PG_GETARG_NDBOX(1);
    bool        res;

    res = cube_overlap_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_BOOL(res);
}

bool cube_overlap_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 1164 of file cube.c.

References NDBOX::dim, FALSE, i, Max, Min, NULL, TRUE, and NDBOX::x.

Referenced by cube_overlap(), g_cube_internal_consistent(), and g_cube_leaf_consistent().

{
    int         i;

    /*
     * This *very bad* error was found in the source: if ( (a==NULL) ||
     * (b=NULL) ) return(FALSE);
     */
    if ((a == NULL) || (b == NULL))
        return (FALSE);

    /* swap the box pointers if needed */
    if (a->dim < b->dim)
    {
        NDBOX      *tmp = b;

        b = a;
        a = tmp;
    }

    /* compare within the dimensions of (b) */
    for (i = 0; i < b->dim; i++)
    {
        if (Min(a->x[i], a->x[a->dim + i]) >
            Max(b->x[i], b->x[b->dim + i]))
            return (FALSE);
        if (Max(a->x[i], a->x[a->dim + i]) <
            Min(b->x[i], b->x[b->dim + i]))
            return (FALSE);
    }

    /* compare to zero those dimensions in (a) absent in (b) */
    for (i = b->dim; i < a->dim; i++)
    {
        if (Min(a->x[i], a->x[a->dim + i]) > 0)
            return (FALSE);
        if (Max(a->x[i], a->x[a->dim + i]) < 0)
            return (FALSE);
    }

    return (TRUE);
}

void cube_scanner_finish ( void   ) 

Referenced by cube_in().

void cube_scanner_init ( const char *  str  ) 

Referenced by cube_in().

Datum cube_size ( PG_FUNCTION_ARGS   ) 

Definition at line 872 of file cube.c.

References Abs, NDBOX::dim, i, PG_FREE_IF_COPY, PG_GETARG_NDBOX, PG_RETURN_FLOAT8, and NDBOX::x.

{
    NDBOX      *a = PG_GETARG_NDBOX(0);
    double      result;
    int         i,
                j;

    result = 1.0;
    for (i = 0, j = a->dim; i < a->dim; i++, j++)
        result = result * Abs((a->x[j] - a->x[i]));

    PG_FREE_IF_COPY(a, 0);
    PG_RETURN_FLOAT8(result);
}

Datum cube_subset ( PG_FUNCTION_ARGS   ) 

Definition at line 252 of file cube.c.

References ARR_DATA_PTR, array_contains_nulls(), ARRNELEMS, NDBOX::dim, ereport, errcode(), errmsg(), ERROR, i, idx(), offsetof, palloc0(), pfree(), PG_FREE_IF_COPY, PG_GETARG_ARRAYTYPE_P, PG_GETARG_NDBOX, PG_RETURN_NDBOX, SET_VARSIZE, and NDBOX::x.

{
    NDBOX      *c = PG_GETARG_NDBOX(0);
    ArrayType  *idx = PG_GETARG_ARRAYTYPE_P(1);
    NDBOX      *result;
    int         size,
                dim,
                i;
    int        *dx;

    if (array_contains_nulls(idx))
        ereport(ERROR,
                (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
                 errmsg("cannot work with arrays containing NULLs")));

    dx = (int32 *) ARR_DATA_PTR(idx);

    dim = ARRNELEMS(idx);
    size = offsetof(NDBOX, x[0]) +sizeof(double) * 2 * dim;
    result = (NDBOX *) palloc0(size);
    SET_VARSIZE(result, size);
    result->dim = dim;

    for (i = 0; i < dim; i++)
    {
        if ((dx[i] <= 0) || (dx[i] > c->dim))
        {
            pfree(result);
            ereport(ERROR,
                    (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
                     errmsg("Index out of bounds")));
        }
        result->x[i] = c->x[dx[i] - 1];
        result->x[i + dim] = c->x[dx[i] + c->dim - 1];
    }

    PG_FREE_IF_COPY(c, 0);
    PG_RETURN_NDBOX(result);
}

Datum cube_union ( PG_FUNCTION_ARGS   ) 

Definition at line 783 of file cube.c.

References cube_union_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX, and PG_RETURN_NDBOX.

{
    NDBOX      *a = PG_GETARG_NDBOX(0);
    NDBOX      *b = PG_GETARG_NDBOX(1);
    NDBOX      *res;

    res = cube_union_v0(a, b);

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_NDBOX(res);
}

NDBOX * cube_union_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 728 of file cube.c.

References NDBOX::dim, i, Max, Min, palloc0(), SET_VARSIZE, VARSIZE, and NDBOX::x.

Referenced by cube_union(), g_cube_binary_union(), g_cube_penalty(), and g_cube_picksplit().

{
    int         i;
    NDBOX      *result;

    if (a->dim >= b->dim)
    {
        result = palloc0(VARSIZE(a));
        SET_VARSIZE(result, VARSIZE(a));
        result->dim = a->dim;
    }
    else
    {
        result = palloc0(VARSIZE(b));
        SET_VARSIZE(result, VARSIZE(b));
        result->dim = b->dim;
    }

    /* swap the box pointers if needed */
    if (a->dim < b->dim)
    {
        NDBOX      *tmp = b;

        b = a;
        a = tmp;
    }

    /*
     * use the potentially smaller of the two boxes (b) to fill in the result,
     * padding absent dimensions with zeroes
     */
    for (i = 0; i < b->dim; i++)
    {
        result->x[i] = Min(b->x[i], b->x[i + b->dim]);
        result->x[i + a->dim] = Max(b->x[i], b->x[i + b->dim]);
    }
    for (i = b->dim; i < a->dim; i++)
    {
        result->x[i] = 0;
        result->x[i + a->dim] = 0;
    }

    /* compute the union */
    for (i = 0; i < a->dim; i++)
    {
        result->x[i] =
            Min(Min(a->x[i], a->x[i + a->dim]), result->x[i]);
        result->x[i + a->dim] = Max(Max(a->x[i],
                                   a->x[i + a->dim]), result->x[i + a->dim]);
    }

    return (result);
}

Datum cube_ur_coord ( PG_FUNCTION_ARGS   ) 

Definition at line 1340 of file cube.c.

References NDBOX::dim, Max, PG_FREE_IF_COPY, PG_GETARG_INT16, PG_GETARG_NDBOX, PG_RETURN_FLOAT8, and NDBOX::x.

{
    NDBOX      *c = PG_GETARG_NDBOX(0);
    int         n = PG_GETARG_INT16(1);
    double      result;

    if (c->dim >= n && n > 0)
        result = Max(c->x[n - 1], c->x[c->dim + n - 1]);
    else
        result = 0;

    PG_FREE_IF_COPY(c, 0);
    PG_RETURN_FLOAT8(result);
}

void cube_yyerror ( const char *  message  ) 

Referenced by cube_in().

int cube_yyparse (  ) 

Referenced by cube_in().

static double distance_1D ( double  a1,
double  a2,
double  b1,
double  b2 
) [static]

Definition at line 1278 of file cube.c.

References Max, and Min.

Referenced by cube_distance().

{
    /* interval (a) is entirely on the left of (b) */
    if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
        return (Min(b1, b2) - Max(a1, a2));

    /* interval (a) is entirely on the right of (b) */
    if ((a1 > b1) && (a2 > b1) && (a1 > b2) && (a2 > b2))
        return (Min(a1, a2) - Max(b1, b2));

    /* the rest are all sorts of intersections */
    return (0.0);
}

NDBOX * g_cube_binary_union ( NDBOX r1,
NDBOX r2,
int *  sizep 
)

Definition at line 715 of file cube.c.

References cube_union_v0(), and VARSIZE.

Referenced by g_cube_union().

{
    NDBOX      *retval;

    retval = cube_union_v0(r1, r2);
    *sizep = VARSIZE(retval);

    return (retval);
}

Datum g_cube_compress ( PG_FUNCTION_ARGS   ) 

Definition at line 423 of file cube.c.

References PG_GETARG_DATUM, and PG_RETURN_DATUM.

Datum g_cube_consistent ( PG_FUNCTION_ARGS   ) 

Definition at line 354 of file cube.c.

References DatumGetNDBOX, g_cube_internal_consistent(), g_cube_leaf_consistent(), GIST_LEAF, GISTENTRY::key, PG_FREE_IF_COPY, PG_GETARG_NDBOX, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_BOOL.

{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    NDBOX      *query = PG_GETARG_NDBOX(1);
    StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);

    /* Oid      subtype = PG_GETARG_OID(3); */
    bool       *recheck = (bool *) PG_GETARG_POINTER(4);
    bool        res;

    /* All cases served by this function are exact */
    *recheck = false;

    /*
     * if entry is not leaf, use g_cube_internal_consistent, else use
     * g_cube_leaf_consistent
     */
    if (GIST_LEAF(entry))
        res = g_cube_leaf_consistent(DatumGetNDBOX(entry->key),
                                     query, strategy);
    else
        res = g_cube_internal_consistent(DatumGetNDBOX(entry->key),
                                         query, strategy);

    PG_FREE_IF_COPY(query, 1);
    PG_RETURN_BOOL(res);
}

Datum g_cube_decompress ( PG_FUNCTION_ARGS   ) 
bool g_cube_internal_consistent ( NDBOX key,
NDBOX query,
StrategyNumber  strategy 
)

Definition at line 685 of file cube.c.

References cube_contains_v0(), cube_overlap_v0(), RTContainedByStrategyNumber, RTContainsStrategyNumber, RTOldContainedByStrategyNumber, RTOldContainsStrategyNumber, RTOverlapStrategyNumber, and RTSameStrategyNumber.

Referenced by g_cube_consistent().

{
    bool        retval;

    /*
     * fprintf(stderr, "internal_consistent, %d\n", strategy);
     */
    switch (strategy)
    {
        case RTOverlapStrategyNumber:
            retval = (bool) cube_overlap_v0(key, query);
            break;
        case RTSameStrategyNumber:
        case RTContainsStrategyNumber:
        case RTOldContainsStrategyNumber:
            retval = (bool) cube_contains_v0(key, query);
            break;
        case RTContainedByStrategyNumber:
        case RTOldContainedByStrategyNumber:
            retval = (bool) cube_overlap_v0(key, query);
            break;
        default:
            retval = FALSE;
    }
    return (retval);
}

bool g_cube_leaf_consistent ( NDBOX key,
NDBOX query,
StrategyNumber  strategy 
)

Definition at line 653 of file cube.c.

References cube_cmp_v0(), cube_contains_v0(), cube_overlap_v0(), RTContainedByStrategyNumber, RTContainsStrategyNumber, RTOldContainedByStrategyNumber, RTOldContainsStrategyNumber, RTOverlapStrategyNumber, and RTSameStrategyNumber.

Referenced by g_cube_consistent().

{
    bool        retval;

    /*
     * fprintf(stderr, "leaf_consistent, %d\n", strategy);
     */
    switch (strategy)
    {
        case RTOverlapStrategyNumber:
            retval = (bool) cube_overlap_v0(key, query);
            break;
        case RTSameStrategyNumber:
            retval = (bool) (cube_cmp_v0(key, query) == 0);
            break;
        case RTContainsStrategyNumber:
        case RTOldContainsStrategyNumber:
            retval = (bool) cube_contains_v0(key, query);
            break;
        case RTContainedByStrategyNumber:
        case RTOldContainedByStrategyNumber:
            retval = (bool) cube_contains_v0(query, key);
            break;
        default:
            retval = FALSE;
    }
    return (retval);
}

Datum g_cube_penalty ( PG_FUNCTION_ARGS   ) 

Definition at line 452 of file cube.c.

References cube_union_v0(), DatumGetNDBOX, GISTENTRY::key, PG_GETARG_POINTER, PG_RETURN_FLOAT8, and rt_cube_size().

{
    GISTENTRY  *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
    GISTENTRY  *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
    float      *result = (float *) PG_GETARG_POINTER(2);
    NDBOX      *ud;
    double      tmp1,
                tmp2;

    ud = cube_union_v0(DatumGetNDBOX(origentry->key),
                       DatumGetNDBOX(newentry->key));
    rt_cube_size(ud, &tmp1);
    rt_cube_size(DatumGetNDBOX(origentry->key), &tmp2);
    *result = (float) (tmp1 - tmp2);

    /*
     * fprintf(stderr, "penalty\n"); fprintf(stderr, "\t%g\n", *result);
     */
    PG_RETURN_FLOAT8(*result);
}

Datum g_cube_picksplit ( PG_FUNCTION_ARGS   ) 

Definition at line 480 of file cube.c.

References cube_inter(), cube_union_v0(), DatumGetNDBOX, DirectFunctionCall2, FirstOffsetNumber, i, GISTENTRY::key, GistEntryVector::n, OffsetNumberNext, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum, rt_cube_size(), GIST_SPLITVEC::spl_ldatum, GIST_SPLITVEC::spl_left, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_rdatum, GIST_SPLITVEC::spl_right, and GistEntryVector::vector.

{
    GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
    GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
    OffsetNumber i,
                j;
    NDBOX      *datum_alpha,
               *datum_beta;
    NDBOX      *datum_l,
               *datum_r;
    NDBOX      *union_d,
               *union_dl,
               *union_dr;
    NDBOX      *inter_d;
    bool        firsttime;
    double      size_alpha,
                size_beta,
                size_union,
                size_inter;
    double      size_waste,
                waste;
    double      size_l,
                size_r;
    int         nbytes;
    OffsetNumber seed_1 = 1,
                seed_2 = 2;
    OffsetNumber *left,
               *right;
    OffsetNumber maxoff;

    /*
     * fprintf(stderr, "picksplit\n");
     */
    maxoff = entryvec->n - 2;
    nbytes = (maxoff + 2) * sizeof(OffsetNumber);
    v->spl_left = (OffsetNumber *) palloc(nbytes);
    v->spl_right = (OffsetNumber *) palloc(nbytes);

    firsttime = true;
    waste = 0.0;

    for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
    {
        datum_alpha = DatumGetNDBOX(entryvec->vector[i].key);
        for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
        {
            datum_beta = DatumGetNDBOX(entryvec->vector[j].key);

            /* 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);
            inter_d = DatumGetNDBOX(DirectFunctionCall2(cube_inter,
                          entryvec->vector[i].key, entryvec->vector[j].key));
            rt_cube_size(inter_d, &size_inter);
            size_waste = size_union - size_inter;

            /*
             * are these a more promising split than what we've already seen?
             */

            if (size_waste > waste || firsttime)
            {
                waste = size_waste;
                seed_1 = i;
                seed_2 = j;
                firsttime = false;
            }
        }
    }

    left = v->spl_left;
    v->spl_nleft = 0;
    right = v->spl_right;
    v->spl_nright = 0;

    datum_alpha = DatumGetNDBOX(entryvec->vector[seed_1].key);
    datum_l = cube_union_v0(datum_alpha, datum_alpha);
    rt_cube_size(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);

    /*
     * Now split up the regions between the two seeds.  An important property
     * of this split algorithm is that the split vector v has the indices of
     * items to be split in order in its left and right vectors.  We exploit
     * this property by doing a merge in the code that actually splits the
     * page.
     *
     * For efficiency, we also place the new index tuple in this loop. This is
     * handled at the very end, when we have placed all the existing tuples
     * and i == maxoff + 1.
     */

    maxoff = OffsetNumberNext(maxoff);
    for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
    {
        /*
         * If we've already decided where to place this item, just put it on
         * the right list.  Otherwise, we need to figure out which page needs
         * the least enlargement in order to store the item.
         */

        if (i == seed_1)
        {
            *left++ = i;
            v->spl_nleft++;
            continue;
        }
        else if (i == seed_2)
        {
            *right++ = i;
            v->spl_nright++;
            continue;
        }

        /* okay, which page needs least enlargement? */
        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);

        /* pick which page to add it to */
        if (size_alpha - size_l < size_beta - size_r)
        {
            datum_l = union_dl;
            size_l = size_alpha;
            *left++ = i;
            v->spl_nleft++;
        }
        else
        {
            datum_r = union_dr;
            size_r = size_beta;
            *right++ = i;
            v->spl_nright++;
        }
    }
    *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */

    v->spl_ldatum = PointerGetDatum(datum_l);
    v->spl_rdatum = PointerGetDatum(datum_r);

    PG_RETURN_POINTER(v);
}

Datum g_cube_same ( PG_FUNCTION_ARGS   ) 

Definition at line 632 of file cube.c.

References cube_cmp_v0(), PG_GETARG_NDBOX, PG_GETARG_POINTER, PG_RETURN_NDBOX, and TRUE.

{
    NDBOX      *b1 = PG_GETARG_NDBOX(0);
    NDBOX      *b2 = PG_GETARG_NDBOX(1);
    bool       *result = (bool *) PG_GETARG_POINTER(2);

    if (cube_cmp_v0(b1, b2) == 0)
        *result = TRUE;
    else
        *result = FALSE;

    /*
     * fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE" ));
     */
    PG_RETURN_NDBOX(result);
}

Datum g_cube_union ( PG_FUNCTION_ARGS   ) 

Definition at line 388 of file cube.c.

References DatumGetNDBOX, g_cube_binary_union(), i, GISTENTRY::key, GistEntryVector::n, NULL, PG_GETARG_POINTER, PG_RETURN_POINTER, VARSIZE, and GistEntryVector::vector.

{
    GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
    int        *sizep = (int *) PG_GETARG_POINTER(1);
    NDBOX      *out = (NDBOX *) NULL;
    NDBOX      *tmp;
    int         i;

    /*
     * fprintf(stderr, "union\n");
     */
    tmp = DatumGetNDBOX(entryvec->vector[0].key);

    /*
     * sizep = sizeof(NDBOX); -- NDBOX has variable size
     */
    *sizep = VARSIZE(tmp);

    for (i = 1; i < entryvec->n; i++)
    {
        out = g_cube_binary_union(tmp,
                                  DatumGetNDBOX(entryvec->vector[i].key),
                                  sizep);
        tmp = out;
    }

    PG_RETURN_POINTER(out);
}

PG_FUNCTION_INFO_V1 ( cube_overlap   ) 
PG_FUNCTION_INFO_V1 ( cube_union   ) 
PG_FUNCTION_INFO_V1 ( g_cube_same   ) 
PG_FUNCTION_INFO_V1 ( cube_out   ) 
PG_FUNCTION_INFO_V1 ( cube_ll_coord   ) 
PG_FUNCTION_INFO_V1 ( cube_in   ) 
PG_FUNCTION_INFO_V1 ( cube_ur_coord   ) 
PG_FUNCTION_INFO_V1 ( g_cube_compress   ) 
PG_FUNCTION_INFO_V1 ( g_cube_consistent   ) 
PG_FUNCTION_INFO_V1 ( cube_a_f8   ) 
PG_FUNCTION_INFO_V1 ( g_cube_penalty   ) 
PG_FUNCTION_INFO_V1 ( g_cube_union   ) 
PG_FUNCTION_INFO_V1 ( cube_f8   ) 
PG_FUNCTION_INFO_V1 ( cube_c_f8_f8   ) 
PG_FUNCTION_INFO_V1 ( cube_ge   ) 
PG_FUNCTION_INFO_V1 ( cube_c_f8   ) 
PG_FUNCTION_INFO_V1 ( cube_ne   ) 
PG_FUNCTION_INFO_V1 ( cube_cmp   ) 
PG_FUNCTION_INFO_V1 ( cube_contained   ) 
PG_FUNCTION_INFO_V1 ( cube_dim   ) 
PG_FUNCTION_INFO_V1 ( g_cube_picksplit   ) 
PG_FUNCTION_INFO_V1 ( cube_gt   ) 
PG_FUNCTION_INFO_V1 ( cube_inter   ) 
PG_FUNCTION_INFO_V1 ( cube_f8_f8   ) 
PG_FUNCTION_INFO_V1 ( cube_size   ) 
PG_FUNCTION_INFO_V1 ( g_cube_decompress   ) 
PG_FUNCTION_INFO_V1 ( cube_lt   ) 
PG_FUNCTION_INFO_V1 ( cube_eq   ) 
PG_FUNCTION_INFO_V1 ( cube_le   ) 
PG_FUNCTION_INFO_V1 ( cube_distance   ) 
PG_FUNCTION_INFO_V1 ( cube_a_f8_f8   ) 
PG_FUNCTION_INFO_V1 ( cube_subset   ) 
PG_FUNCTION_INFO_V1 ( cube_enlarge   ) 
PG_FUNCTION_INFO_V1 ( cube_contains   ) 
PG_FUNCTION_INFO_V1 ( cube_is_point   ) 
void rt_cube_size ( NDBOX a,
double *  sz 
)

Definition at line 888 of file cube.c.

References Abs, NDBOX::dim, i, NULL, and NDBOX::x.

Referenced by g_cube_penalty(), and g_cube_picksplit().

{
    int         i,
                j;

    if (a == (NDBOX *) NULL)
        *size = 0.0;
    else
    {
        *size = 1.0;
        for (i = 0, j = a->dim; i < a->dim; i++, j++)
            *size = (*size) * Abs((a->x[j] - a->x[i]));
    }
    return;
}


Variable Documentation

Definition at line 21 of file cube.c.