Beispiel #1
0
/*
 * 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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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)));
}