/* * bloom_union_agg transition function - * * returns the union of the transition state and the given Bloom filter */ Datum bloom_union_agg_trans(PG_FUNCTION_ARGS) { MemoryContext old; MemoryContext context; BloomFilter *state; BloomFilter *incoming; if (!AggCheckCallContext(fcinfo, &context)) elog(ERROR, "bloom_union_agg_trans called in non-aggregate context"); if (PG_ARGISNULL(0) && PG_ARGISNULL(1)) PG_RETURN_NULL(); old = MemoryContextSwitchTo(context); if (PG_ARGISNULL(0)) { incoming = (BloomFilter *) PG_GETARG_VARLENA_P(1); state = BloomFilterCopy(incoming); } else if (PG_ARGISNULL(1)) state = (BloomFilter *) PG_GETARG_VARLENA_P(0); else { state = (BloomFilter *) PG_GETARG_VARLENA_P(0); incoming = (BloomFilter *) PG_GETARG_VARLENA_P(1); state = BloomFilterUnion(state, incoming); } MemoryContextSwitchTo(old); PG_RETURN_POINTER(state); }
static BloomFilter * bloom_operation(FunctionCallInfo fcinfo, bool intersection) { Oid bf_type = LookupTypeNameOid(NULL, SystemTypeName("bloom"), false); BloomFilter *result = NULL; int i; for (i = 0; i < PG_NARGS(); i++) { BloomFilter *bf; if (PG_ARGISNULL(i)) continue; if (get_fn_expr_argtype(fcinfo->flinfo, i) != bf_type) elog(ERROR, "argument %d is not of type \"bloom\"", i + 1); bf = (BloomFilter *) PG_GETARG_VARLENA_P(i); if (result) { if (bf->m != result->m) elog(ERROR, "bloom filters must have the same p"); else if (bf->k != result->k) elog(ERROR, "bloom filters must have the same n"); } if (result == NULL) result = bf; else if (intersection) result = BloomFilterIntersection(result, bf); else result = BloomFilterUnion(result, bf); } return result; }
END_TEST START_TEST(test_union) { BloomFilter *bf1 = BloomFilterCreate(); BloomFilter *bf2 = BloomFilterCreate(); int num_keys = 25000; int *keys = palloc(sizeof(int) * num_keys * 2); int i; for (i = 0; i < num_keys; i++) { int k1 = rand(); int k2 = rand(); keys[i] = k1; keys[num_keys + i] = k2; BloomFilterAdd(bf1, &k1, sizeof(int)); BloomFilterAdd(bf2, &k2, sizeof(int)); } bf1 = BloomFilterUnion(bf1, bf2); for (i = 0; i < num_keys * 2; i++) ck_assert(BloomFilterContains(bf1, &keys[i], sizeof(int))); }