Skip to content
Merged
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
72 changes: 36 additions & 36 deletions contrib/mobilitydb/mobilitydb_mest--1.0.sql

Large diffs are not rendered by default.

92 changes: 39 additions & 53 deletions contrib/mobilitydb/mobilitydb_mest.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
#define BORDER_INC true
#define BORDER_EXC false

/** Origin the time bins and the time dimension of the tiles are anchored at */
#define MEST_TIME_ORIGIN "2020-03-01"

/*****************************************************************************/

/** Enumeration for the types of SP-GiST indexes */
Expand All @@ -78,66 +81,30 @@ typedef struct
Span right;
} SpanNode;

#define MAXDIMS 4

/**
* Structure for storing a bit matrix
*/
typedef struct
{
int ndims; /**< Number of dimensions */
int count[MAXDIMS]; /**< Number of elements in each dimension */
uint8_t byte[1]; /**< beginning of variable-length data */
} BitMatrix;

/**
* Struct for storing the state that persists across multiple calls generating
* a multidimensional grid
*/
typedef struct STboxGridState
{
bool done; /**< True when all tiles have been processed */
bool hasz; /**< True when tiles have Z dimension */
bool hast; /**< True when tiles have T dimension */
int i; /**< Number of current tile */
double xsize; /**< Size of the x dimension */
double ysize; /**< Size of the y dimension */
double zsize; /**< Size of the z dimension, 0 for 2D */
int64 tunits; /**< Size of the time dimension, 0 for spatial only */
STBox box; /**< Bounding box of the grid */
const Temporal *temp; /**< Optional temporal point to be split */
BitMatrix *bm; /**< Optional bit matrix for speeding up the
computation of the split functions */
double x; /**< Minimum x value of the current tile */
double y; /**< Minimum y value of the current tile */
double z; /**< Minimum z value of the current tile, if any */
TimestampTz t; /**< Minimum t value of the current tile, if any */
int ntiles; /**< Total number of tiles */
int max_coords[MAXDIMS]; /**< Maximum coordinates of the tiles */
int coords[MAXDIMS]; /**< Coordinates of the current tile */
} STboxGridState;

/*****************************************************************************
* External functions from MobilityDB
*****************************************************************************/

extern bool ensure_not_null(const void *ptr);
extern bool ensure_positive(int i);
extern Oid type_oid(meosType t);
extern Oid meostype_oid(MeosType type);
extern ArrayType *stboxarr_to_array(STBox *boxes, int count);
extern Datum call_function1(PGFunction func, Datum arg1);
extern Datum call_function2(PGFunction func, Datum arg1, Datum arg2);
extern Datum date_in(PG_FUNCTION_ARGS);
extern Datum interval_in(PG_FUNCTION_ARGS);
extern Datum timestamptz_in(PG_FUNCTION_ARGS);
extern void spanset_span_slice(Datum d, Span *s);
extern Temporal *temporal_slice(Datum tempdatum);
extern meosType oid_type(Oid typid);
extern void spannode_init(SpanNode *nodebox, meosType spantype,
meosType basetype);
extern MeosType oid_meostype(Oid typid);
extern void spannode_init(SpanNode *nodebox, MeosType spantype,
MeosType basetype);
extern bool span_gist_get_span(FunctionCallInfo fcinfo, Span *result,
Oid typid);
extern bool span_spgist_get_span(const ScanKeyData *scankey, Span *result);
extern bool span_spgist_get_span(Datum value, MeosType type,
Span *result);
extern SpanNode *spannode_copy(const SpanNode *orig);
extern double distance_span_nodespan(Span *query, SpanNode *nodebox);
extern double distance_span_nodespan(const Span *query,
const SpanNode *nodebox);
extern double distance_double(Datum dist, MeosType type);
extern void spannode_quadtree_next(const SpanNode *nodebox,
const Span *centroid, uint8 quadrant, SpanNode *next_nodespan);
extern void spannode_kdtree_next(const SpanNode *nodebox, const Span *centroid,
Expand All @@ -149,11 +116,30 @@ extern bool overLeft2D(const SpanNode *nodebox, const Span *query);
extern bool right2D(const SpanNode *nodebox, const Span *query);
extern bool overRight2D(const SpanNode *nodebox, const Span *query);
extern bool adjacent2D(const SpanNode *nodebox, const Span *query);
extern void stbox_tile_state_next(STboxGridState *state);
extern bool stbox_tile_state_get(STboxGridState *state, STBox *box);
extern STboxGridState *tpoint_space_time_tile_init(const Temporal *temp,
float xsize, float ysize, float zsize, const Interval *duration,
const GSERIALIZED *sorigin, TimestampTz torigin, bool bitmatrix,
bool border_inc, int *ntiles);

/*****************************************************************************
* Origin of the time bins and of the time dimension of the tiles
*****************************************************************************/

/**
* @brief Return the origin of the time dimension as a date
*/
static inline DateADT
mest_date_origin(void)
{
return DatumGetDateADT(DirectFunctionCall1(date_in,
CStringGetDatum(MEST_TIME_ORIGIN)));
}

/**
* @brief Return the origin of the time dimension as a timestamptz
*/
static inline TimestampTz
mest_timestamptz_origin(void)
{
return DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in,
CStringGetDatum(MEST_TIME_ORIGIN), ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1)));
}

/*****************************************************************************/
79 changes: 53 additions & 26 deletions contrib/mobilitydb/spanset_mest.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <math.h>

#include "postgres.h"
#include "common/pg_prng.h"
#include "fmgr.h"
#include "access/gist.h"
#include "access/spgist.h"
Expand Down Expand Up @@ -282,7 +283,7 @@ Intspanset_mest_binsplit(PG_FUNCTION_ARGS)
int32 vsize = MEST_INTSPANSET_GET_BINSIZE();
int32 vorigin = 0;
int32 count;
Span *spans= spanset_value_spans(ss, Int32GetDatum(vsize),
Span *spans = spanset_bins(ss, Int32GetDatum(vsize),
Int32GetDatum(vorigin), &count);
Datum *keys = palloc(sizeof(Datum) * count);
for (int i = 0; i < count; ++i)
Expand All @@ -304,7 +305,7 @@ Bigintspanset_mest_binsplit(PG_FUNCTION_ARGS)
int64 vsize = (int64) MEST_INTSPANSET_GET_BINSIZE();
int64 vorigin = 0;
int32 count;
Span *spans= spanset_value_spans(ss, Int64GetDatum(vsize),
Span *spans = spanset_bins(ss, Int64GetDatum(vsize),
Int64GetDatum(vorigin), &count);
Datum *keys = palloc(sizeof(Datum) * count);
for (int i = 0; i < count; ++i)
Expand All @@ -326,7 +327,7 @@ Floatspanset_mest_binsplit(PG_FUNCTION_ARGS)
double vsize = MEST_FLOATSPANSET_GET_BINSIZE();
double vorigin = 0;
int32 count;
Span *spans= spanset_value_spans(ss, Float8GetDatum(vsize),
Span *spans = spanset_bins(ss, Float8GetDatum(vsize),
Float8GetDatum(vorigin), &count);
Datum *keys = palloc(sizeof(Datum) * count);
for (int i = 0; i < count; ++i)
Expand All @@ -349,20 +350,26 @@ Timespanset_mest_binsplit(PG_FUNCTION_ARGS)
int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
char *duration;
Interval *interv = NULL;
TimestampTz torigin = pg_timestamptz_in("2020-03-01", -1);
Datum torigin;
int32 count;
Span *spanarr;
Span **spans;


/* The origin is a value of the base type of the span set */
torigin = (ss->basetype == T_DATE) ?
DateADTGetDatum(mest_date_origin()) :
TimestampTzGetDatum(mest_timestamptz_origin());

/* Index parameters */
if (PG_HAS_OPCLASS_OPTIONS())
{
TimespansetBinOptions *options = (TimespansetBinOptions *) PG_GET_OPCLASS_OPTIONS();
duration = GET_STRING_RELOPTION(options, duration);
if (strlen(duration) > 0)
{
interv = (Interval *) DatumGetPointer(call_function2(interval_in,
PointerGetDatum(duration), -1));
interv = DatumGetIntervalP(DirectFunctionCall3(interval_in,
CStringGetDatum(duration), ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1)));
if (! interv)
{
ereport(ERROR,
Expand All @@ -371,9 +378,13 @@ Timespanset_mest_binsplit(PG_FUNCTION_ARGS)
}
}
}
if (! interv)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("the operator class requires a duration parameter")));

/* Get the spans */
spanarr = spanset_time_spans(ss, interv, torigin, &count);
spanarr = spanset_bins(ss, PointerGetDatum(interv), torigin, &count);
spans = palloc(sizeof(Span *) * count);
for (int i = 0; i < count; i++)
spans[i] = &spanarr[i];
Expand Down Expand Up @@ -420,21 +431,24 @@ span_mest_leaf_consistent(const Span *key, const Span *query,
case RTContainedByStrategyNumber:
case RTEqualStrategyNumber:
case RTSameStrategyNumber:
return over_span_span(key, query);
return overlaps_span_span(key, query);
case RTAdjacentStrategyNumber:
return lf_span_span(key, query) || ri_span_span(key, query);
/* Two spans sharing a boundary value are adjacent whatever their bound
* inclusivity, so an adjacent pair may also overlap and a single entry
* of a multi-entry key is neither strictly left nor strictly right */
return adjacent_span_span(key, query) || overlaps_span_span(key, query);
case RTLeftStrategyNumber:
case RTBeforeStrategyNumber:
return lf_span_span(key, query);
return left_span_span(key, query);
case RTOverLeftStrategyNumber:
case RTOverBeforeStrategyNumber:
return ovlf_span_span(key, query);
return overleft_span_span(key, query);
case RTRightStrategyNumber:
case RTAfterStrategyNumber:
return ri_span_span(key, query);
return right_span_span(key, query);
case RTOverRightStrategyNumber:
case RTOverAfterStrategyNumber:
return ovri_span_span(key, query);
return overright_span_span(key, query);
default:
elog(ERROR, "unrecognized span strategy: %d", strategy);
return false; /* keep compiler quiet */
Expand All @@ -458,21 +472,21 @@ span_mgist_inner_consistent(const Span *key, const Span *query,
case RTContainsStrategyNumber:
case RTEqualStrategyNumber:
case RTSameStrategyNumber:
return over_span_span(key, query);
return overlaps_span_span(key, query);
case RTAdjacentStrategyNumber:
return adj_span_span(key, query) || overlaps_span_span(key, query);
return adjacent_span_span(key, query) || overlaps_span_span(key, query);
case RTLeftStrategyNumber:
case RTBeforeStrategyNumber:
return ! ovri_span_span(key, query);
return ! overright_span_span(key, query);
case RTOverLeftStrategyNumber:
case RTOverBeforeStrategyNumber:
return ! ri_span_span(key, query);
return ! right_span_span(key, query);
case RTRightStrategyNumber:
case RTAfterStrategyNumber:
return ! ovlf_span_span(key, query);
return ! overleft_span_span(key, query);
case RTOverRightStrategyNumber:
case RTOverAfterStrategyNumber:
return ! lf_span_span(key, query);
return ! left_span_span(key, query);
default:
elog(ERROR, "unrecognized span strategy: %d", strategy);
return false; /* keep compiler quiet */
Expand Down Expand Up @@ -575,7 +589,11 @@ Spanset_mspgist_inner_consistent(FunctionCallInfo fcinfo,
{
orderbys = palloc0(sizeof(Span) * in->norderbys);
for (i = 0; i < in->norderbys; i++)
span_spgist_get_span(&in->orderbys[i], &orderbys[i]);
{
const ScanKeyData *scankey = &in->orderbys[i];
span_spgist_get_span(scankey->sk_argument,
oid_meostype(scankey->sk_subtype), &orderbys[i]);
}
}

if (in->allTheSame)
Expand Down Expand Up @@ -617,7 +635,11 @@ Spanset_mspgist_inner_consistent(FunctionCallInfo fcinfo,
{
queries = palloc0(sizeof(Span) * in->nkeys);
for (i = 0; i < in->nkeys; i++)
span_spgist_get_span(&in->scankeys[i], &queries[i]);
{
const ScanKeyData *scankey = &in->scankeys[i];
span_spgist_get_span(scankey->sk_argument,
oid_meostype(scankey->sk_subtype), &queries[i]);
}
}

/* Allocate enough memory for nodes */
Expand Down Expand Up @@ -763,13 +785,15 @@ Spanset_mspgist_leaf_consistent(PG_FUNCTION_ARGS)
/* Perform the required comparison(s) */
for (i = 0; i < in->nkeys; i++)
{
StrategyNumber strategy = in->scankeys[i].sk_strategy;
const ScanKeyData *scankey = &in->scankeys[i];
StrategyNumber strategy = scankey->sk_strategy;

/* Update the recheck flag according to the strategy */
out->recheck = true;

/* Convert the query to a span and perform the test */
span_spgist_get_span(&in->scankeys[i], &span);
span_spgist_get_span(scankey->sk_argument,
oid_meostype(scankey->sk_subtype), &span);
result = span_mest_leaf_consistent(key, &span, strategy);

/* If any check is failed, we have found our answer. */
Expand All @@ -786,8 +810,11 @@ Spanset_mspgist_leaf_consistent(PG_FUNCTION_ARGS)
for (i = 0; i < in->norderbys; i++)
{
/* Convert the order by argument to a span and perform the test */
span_spgist_get_span(&in->orderbys[i], &span);
distances[i] = dist_span_span(&span, key);
const ScanKeyData *scankey = &in->orderbys[i];
span_spgist_get_span(scankey->sk_argument,
oid_meostype(scankey->sk_subtype), &span);
distances[i] = distance_double(distance_span_span(&span, key),
key->basetype);
}
}

Expand Down
10 changes: 6 additions & 4 deletions contrib/mobilitydb/temporal_mest.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <math.h>

#include "postgres.h"
#include "common/pg_prng.h"
#include "fmgr.h"
#include "access/gist.h"
#include "access/spgist.h"
Expand Down Expand Up @@ -223,7 +224,7 @@ Temporal_mest_binsplit(PG_FUNCTION_ARGS)
// bool **nullFlags = (bool **) PG_GETARG_POINTER(2);
char *duration;
Interval *interv = NULL;
TimestampTz torigin = pg_timestamptz_in("2020-03-01", -1);
TimestampTz torigin = mest_timestamptz_origin();
int32 count;
Span *spans;
Datum *keys;
Expand All @@ -235,8 +236,9 @@ Temporal_mest_binsplit(PG_FUNCTION_ARGS)
duration = GET_STRING_RELOPTION(options, duration);
if (strlen(duration) > 0)
{
interv = (Interval *) DatumGetPointer(call_function2(interval_in,
PointerGetDatum(duration), -1));
interv = DatumGetIntervalP(DirectFunctionCall3(interval_in,
CStringGetDatum(duration), ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1)));
if (! interv)
{
ereport(ERROR,
Expand All @@ -247,7 +249,7 @@ Temporal_mest_binsplit(PG_FUNCTION_ARGS)
}

/* Get the spans */
spans = temporal_time_spans(temp, interv, torigin, &count);
spans = temporal_time_bins(temp, interv, torigin, &count);
keys = palloc(sizeof(Datum) * count);
assert(temp);
for (int i = 0; i < count; ++i)
Expand Down
Loading
Loading