diff --git a/lib/pc_api.h b/lib/pc_api.h index eb800d3..e817255 100644 --- a/lib/pc_api.h +++ b/lib/pc_api.h @@ -383,10 +383,16 @@ PCSTATS* pc_stats_new_from_data(const PCSCHEMA *schema, const uint8_t *mindata, /** Free a stats object */ void pc_stats_free(PCSTATS *stats); -/** Calculate stats from an existing patch */ +/** How big is the serialzation of a stats? */ +size_t pc_stats_size(const PCSCHEMA *schema); + +/** Calculate stats on an existing patch */ int pc_patch_compute_stats(PCPATCH *patch); + +/** Calculate extent on an existing patch */ int pc_patch_compute_extent(PCPATCH *patch); +/** True/false if bounds intersect */ int pc_bounds_intersects(const PCBOUNDS *b1, const PCBOUNDS *b2); diff --git a/lib/pc_api_internal.h b/lib/pc_api_internal.h index ebe3eba..3d1d93d 100644 --- a/lib/pc_api_internal.h +++ b/lib/pc_api_internal.h @@ -229,7 +229,7 @@ uint64_t pc_bytes_sigbits_count_64(const PCBYTES *pcb, uint32_t *nsigbits); /** Initialize with very large mins and very small maxes */ void pc_bounds_init(PCBOUNDS *b); PCSTATS* pc_stats_clone(const PCSTATS *stats); -size_t pc_stats_size(const PCSCHEMA *schema); +void pc_bounds_merge(PCBOUNDS *b1, const PCBOUNDS *b2); #endif /* _PC_API_INTERNAL_H */ \ No newline at end of file diff --git a/lib/pc_patch.c b/lib/pc_patch.c index 390171c..bc990e2 100644 --- a/lib/pc_patch.c +++ b/lib/pc_patch.c @@ -382,10 +382,7 @@ pc_patch_from_patchlist(PCPATCH **palist, int numpatches) const PCPATCH *pa = palist[i]; /* Update bounds */ - if ( pa->bounds.xmin < paout->bounds.xmin ) paout->bounds.xmin = pa->bounds.xmin; - if ( pa->bounds.ymin < paout->bounds.ymin ) paout->bounds.ymin = pa->bounds.ymin; - if ( pa->bounds.xmax > paout->bounds.xmax ) paout->bounds.xmax = pa->bounds.xmax; - if ( pa->bounds.ymax > paout->bounds.ymax ) paout->bounds.ymax = pa->bounds.ymax; + pc_bounds_merge(&(paout->bounds), &(pa->bounds)); switch ( pa->type ) { diff --git a/lib/pc_util.c b/lib/pc_util.c index be09072..5cdaec5 100644 --- a/lib/pc_util.c +++ b/lib/pc_util.c @@ -286,8 +286,6 @@ bytebuffer_copy(bytebuffer_t *bb) return (void *)buf; } - - int pc_bounds_intersects(const PCBOUNDS *b1, const PCBOUNDS *b2) { @@ -306,4 +304,12 @@ pc_bounds_init(PCBOUNDS *b) { b->xmin = b->ymin = DBL_MAX; b->xmax = b->ymax = -1*DBL_MAX; +} + +void pc_bounds_merge(PCBOUNDS *b1, const PCBOUNDS *b2) +{ + if ( b2->xmin < b1->xmin ) b1->xmin = b2->xmin; + if ( b2->ymin < b1->ymin ) b1->ymin = b2->ymin; + if ( b2->xmax > b1->xmax ) b1->xmax = b2->xmax; + if ( b2->ymax > b1->ymax ) b1->ymax = b2->ymax; } \ No newline at end of file diff --git a/pgsql/pc_access.c b/pgsql/pc_access.c index f1d0c9d..097d695 100644 --- a/pgsql/pc_access.c +++ b/pgsql/pc_access.c @@ -601,9 +601,9 @@ Datum pcpatch_get_stat(PG_FUNCTION_ARGS) float8 double_result; int rv; - if ( stats_size_guess < 3*schema->size ) + if ( stats_size_guess < pc_stats_size(schema) ) { - serpa = PG_GETHEADERX_SERPATCH_P(0, 3*schema->size); + serpa = PG_GETHEADERX_SERPATCH_P(0, pc_stats_size(schema) ); } stats = pc_patch_stats_deserialize(schema, serpa->data); diff --git a/pgsql/pc_pgsql.c b/pgsql/pc_pgsql.c index 161f0ee..db6d913 100644 --- a/pgsql/pc_pgsql.c +++ b/pgsql/pc_pgsql.c @@ -444,7 +444,7 @@ pc_point_deserialize(const SERIALIZED_POINT *serpt, const PCSCHEMA *schema) size_t pc_patch_serialized_size(const PCPATCH *patch) { - size_t stats_size = patch->schema->size * 3; + size_t stats_size = pc_stats_size(patch->schema); size_t common_size = sizeof(SERIALIZED_PATCH) - 1; switch( patch->type ) { @@ -748,7 +748,7 @@ pc_patch_uncompressed_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHE // SERIALIZED_PATCH; uint8_t *buf; - size_t stats_size = 3*schema->size; // 3 pcpoints worth of stats + size_t stats_size = pc_stats_size(schema); // 3 pcpoints worth of stats PCPATCH_UNCOMPRESSED *patch = pcalloc(sizeof(PCPATCH_UNCOMPRESSED)); /* Set up basic info */ @@ -769,6 +769,8 @@ pc_patch_uncompressed_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHE /* Calculate the point data buffer size */ patch->datasize = VARSIZE(serpatch) - sizeof(SERIALIZED_PATCH) + 1 - stats_size; + if ( patch->datasize != patch->npoints * schema->size ) + pcerror("%s: calucated patch data sizes don't match (%d != %d)", __func__, patch->datasize, patch->npoints * schema->size); return (PCPATCH*)patch; } @@ -794,7 +796,7 @@ pc_patch_dimensional_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEM const uint8_t *buf; int ndims = schema->ndims; int npoints = serpatch->npoints; - size_t stats_size = 3*schema->size; // 3 pcpoints worth of stats + size_t stats_size = pc_stats_size(schema); // 3 pcpoints worth of stats /* Reference the external data */ patch = pcalloc(sizeof(PCPATCH_DIMENSIONAL)); @@ -850,7 +852,7 @@ pc_patch_ght_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEMA *schem PCPATCH_GHT *patch; uint32_t ghtsize; int npoints = serpatch->npoints; - size_t stats_size = 3*schema->size; // 3 pcpoints worth of stats + size_t stats_size = pc_stats_size(schema); // 3 pcpoints worth of stats uint8_t *buf = (uint8_t*)serpatch->data + stats_size; /* Reference the external data */