Add a stats-based pre-filter to the generic filtering

This commit is contained in:
Paul Ramsey 2013-07-03 13:26:09 -07:00
parent 75fdd0fb90
commit 1d586ee151
2 changed files with 47 additions and 2 deletions

View File

@ -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:

View File

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