diff --git a/lib/pc_filter.c b/lib/pc_filter.c index 5686ae0..ccce948 100644 --- a/lib/pc_filter.c +++ b/lib/pc_filter.c @@ -183,12 +183,54 @@ pc_patch_dimensional_filter(const PCPATCH_DIMENSIONAL *pdl, const PCBITMAP *map) return fpdl; } +/* See if it's possible for the filter to have any results, given the stats */ +static int +pc_patch_filter_has_results(const PCSTATS *stats, uint32_t dimnum, PC_FILTERTYPE filter, double val1, double val2) +{ + double min, max; + pc_point_get_double_by_index(&(stats->min), dimnum, &min); + pc_point_get_double_by_index(&(stats->max), dimnum, &max); + switch ( filter ) + { + case PC_GT: + { + if ( max < val1 ) return PC_FALSE; + break; + } + case PC_LT: + { + if ( min > val1 ) return PC_FALSE; + break; + } + case PC_EQUAL: + { + if ( min > val1 || max < val1 ) return PC_FALSE; + break; + } + case PC_BETWEEN: + { + if ( min > val2 || max < val1 ) return PC_FALSE; + break; + } + } + return PC_TRUE; +} + + PCPATCH * pc_patch_filter(const PCPATCH *pa, uint32_t dimnum, PC_FILTERTYPE filter, double val1, double val2) { if ( ! pa ) return NULL; PCPATCH *paout; + /* If the stats say this filter returns an empty result, do that */ + if ( pa->stats && ! pc_patch_filter_has_results(pa->stats, dimnum, filter, val1, val2) ) + { + /* Empty uncompressed patch to return */ + paout = (PCPATCH*)pc_patch_uncompressed_make(pa->schema, 0); + return paout; + } + switch ( pa->type ) { case PC_NONE: diff --git a/lib/pc_patch_uncompressed.c b/lib/pc_patch_uncompressed.c index 07e6253..1949ab4 100644 --- a/lib/pc_patch_uncompressed.c +++ b/lib/pc_patch_uncompressed.c @@ -166,9 +166,12 @@ pc_patch_uncompressed_make(const PCSCHEMA *s, uint32_t maxpoints) /* Make our own data area */ datasize = s->size * maxpoints; - pch->data = pcalloc(datasize); pch->datasize = datasize; - + pch->data = NULL; + if ( datasize ) + { + pch->data = pcalloc(datasize); + } pc_bounds_init(&(pch->bounds)); return pch;