greenplum roaringbitmap插件

增加多层聚合功能:

注意要点:

(1)如果stype为internal,则prefunc/combinefunc参数和返回值均为internal

(2)sfunc 参数比aggregate参数多一个arg_0(第一个参数),作为内部状态保存并进行计算迭代。

(3)参数为internal的combinefunc必须提供serialfunc/deserialfunc

(4)finalfunc在combinefunc结束后调用一次,对最终结果进行转换

(5)执行逻辑:

        多层聚合:sfunc在segment上执行,prefunc/combinefunc在master上执行

        单层聚合:sfunc在master上执行

(6)prefunc必须保证context为aggregate

(7)serialfunc/deserialfunc的context为当前内存 context即可

 

roaringbitmap.sql:

CREATE OR REPLACE FUNCTION rb_or_trans_pre(internal, internal)

     RETURNS internal

      AS 'MODULE_PATHNAME', 'rb_or_trans_pre'

     LANGUAGE C IMMUTABLE;

 

CREATE AGGREGATE rb_or_agg(roaringbitmap)(

       SFUNC = rb_or_trans,

       PREFUNC = rb_or_trans_pre,

       STYPE = internal,

       FINALFUNC = rb_serialize,

       SERIALFUNC = rb_serialfunc,
       DESERIALFUNC = rb_deserialfunc

);

 

roaringbitmap.c:

//bitmap or trans pre

PG_FUNCTION_INFO_V1(rb_or_trans_pre);

Datum rb_or_trans_pre(PG_FUNCTION_ARGS);

 

Datum

    rb_or_trans_pre(PG_FUNCTION_ARGS)

{

    MemoryContext aggctx;

    bytea *bb;

    roaring_bitmap_t *r1;

    roaring_bitmap_t *r2;

 

    // We must be called as a transition routine or we fail.

    if (!AggCheckCallContext(fcinfo, &aggctx))

        ereport(ERROR,

                (errcode(ERRCODE_DATA_EXCEPTION),

                 errmsg("rb_or_trans_pre outside transition context")));

    // Is the first argument a NULL?

    if (PG_ARGISNULL(0))

    {

        r1 = setup_roaringbitmap(aggctx);

    }

    else

    {

        r1 = (roaring_bitmap_t *)PG_GETARG_POINTER(0);

    }

 

    // Is the second argument non-null?

    if (!PG_ARGISNULL(1))

    {

        r2 = (roaring_bitmap_t *) PG_GETARG_POINTER(1);

        if (PG_ARGISNULL(0))

        {

            r1 = roaring_bitmap_copy(r2);

        }

        else

        {

            roaring_bitmap_xor_inplace(r1, r2);

        }

        roaring_bitmap_free(r2);

    }

 

    PG_RETURN_POINTER(r1);

}

 

Datum rb_serialfunc(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(rb_serialfunc);

 

Datum

    rb_serialfunc(PG_FUNCTION_ARGS)

{

    roaring_bitmap_t *r1;

    bytea *bb;

    bytea *result;

    if (PG_ARGISNULL(0))

    {

        PG_RETURN_NULL();

    }else{

        r1 = (roaring_bitmap_t *)PG_GETARG_POINTER(0);

        if(r1!=NULL){

            size_t expectedsize = roaring_bitmap_portable_size_in_bytes(r1);

            bytea *serializedbytes = (bytea *)palloc(VARHDRSZ + expectedsize);

            roaring_bitmap_portable_serialize(r1, VARDATA(serializedbytes));

            roaring_bitmap_free(r1);

            SET_VARSIZE(serializedbytes, VARHDRSZ + expectedsize);

            PG_RETURN_BYTEA_P(serializedbytes);

        }else{

            PG_RETURN_NULL();

        }

    }

}

 

PG_FUNCTION_INFO_V1(rb_deserialfunc);

Datum rb_deserialfunc(PG_FUNCTION_ARGS);

 

Datum

    rb_deserialfunc(PG_FUNCTION_ARGS)

{

    bytea *bb ;

    roaring_bitmap_t *r1;

 

    if (PG_ARGISNULL(0))

    {

        PG_RETURN_NULL();

    }else{

        bb = PG_GETARG_BYTEA_P(0);

        r1 = roaring_bitmap_portable_deserialize(VARDATA(bb));

        PG_RETURN_POINTER(r1);

    }  

}

 

select * from pg_aggregate where aggfnoid='rb_and_cardinality_agg'::regproc;

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值