コード例 #1
0
Datum
adaptive_merge_agg(PG_FUNCTION_ARGS)
{

    AdaptiveCounter counter1;
    AdaptiveCounter counter2 = (AdaptiveCounter)PG_GETARG_BYTEA_P(1);

    /* is the counter created (if not, create it - error 1%, 10mil items) */
    if (PG_ARGISNULL(0)) {

        /* just copy the second estimator into the first one */
        counter1 = ac_copy(counter2);

    } else {

        /* ok, we already have the estimator - merge the second one into it */
        counter1 = (AdaptiveCounter)PG_GETARG_BYTEA_P(0);

        /* perform the merge (in place) */
        counter1 = ac_merge(counter1, counter2, true);

    }

    /* return the updated bytea */
    PG_RETURN_BYTEA_P(counter1);

}
コード例 #2
0
/* Merge an adaptive counter into another one. The first parameter 'dest' is the target
 * counter that will be modified during the merge.
 *
 * The counters have to be 'the same' i.e. the basic parameters (level, length, itemSize
 * and error rate) need to be equal.
 */
AdaptiveCounter ac_merge(AdaptiveCounter dest, AdaptiveCounter src) {

    AdaptiveCounter result;
    int i = 0;
  
    /* check if we need to swap dest/src - we need the destination to have
    * higher (>=) level and lower item size (<=) at the same time */
    if ((dest->level < src->level) ||
        ((dest->level == src->level) && (dest->itemSize > src->itemSize))) {
        return ac_merge(src, dest);
    }
  
    /* it's possible to have (dest->level > src->level) and
    * (dest->itemSize > src->itemSize) at the same time, which makes
    * the counters impossible to merge. */
  
    /* check that the counters are 'mergeable' - there are two
    * conditions: 
    * 
    * 1) Lower level has to be merged into the higher level (this is
    *    assured thanks to the previous swap, so we have assert here).
    * 
    * 2) The destination item size must not be higher than the source.
    * 
    * Anyway the best way to make sure two counters are mergeable is
    * to use exactly the same counters (error rate, item length).
    * 
    * Maybe there should be another condition on maxItems, but I don't
    * think so.
    */
    assert(dest->level >= src->level);
  
    if (dest->itemSize > src->itemSize) {
        elog(ERROR, "counters not mergeable - item length dest=%d > src=%d ",
            dest->itemSize, src->itemSize);
    }

    /* allocate space for the destination counter (mergeable -> same size) */
    result = ac_create_copy(dest);
  
    /* copy the items (from the src counter, the one with the lower level) */
    for (i = 0; i < src->items; i++) {
        ac_add_hash(result, &(src->bitmap[i*src->itemSize]));
    }
  
    return result;
  
}
コード例 #3
0
Datum
adaptive_merge_simple(PG_FUNCTION_ARGS)
{

    AdaptiveCounter counter1 = (AdaptiveCounter)PG_GETARG_BYTEA_P(0);
    AdaptiveCounter counter2 = (AdaptiveCounter)PG_GETARG_BYTEA_P(1);

    /* is the counter created (if not, create it - error 1%, 10mil items) */
    if (PG_ARGISNULL(0) && PG_ARGISNULL(1)) {
        PG_RETURN_NULL();
    } else if (PG_ARGISNULL(0)) {
        PG_RETURN_BYTEA_P(ac_copy(counter2));
    } else if (PG_ARGISNULL(1)) {
        PG_RETURN_BYTEA_P(ac_copy(counter1));
    } else {
        PG_RETURN_BYTEA_P(ac_merge(counter1, counter2, false));
    }

}