/* * Returns whether the Bloom filter contains the item or not */ Datum bloom_contains(PG_FUNCTION_ARGS) { BloomFilter *bloom; Datum elem = PG_GETARG_DATUM(1); bool contains = false; Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 1); TypeCacheEntry *typ; StringInfo buf; if (val_type == InvalidOid) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine input data type"))); if (PG_ARGISNULL(0)) PG_RETURN_BOOL(contains); bloom = (BloomFilter *) PG_GETARG_VARLENA_P(0); typ = lookup_type_cache(val_type, 0); buf = makeStringInfo(); DatumToBytes(elem, typ, buf); contains = BloomFilterContains(bloom, buf->data, buf->len); pfree(buf->data); pfree(buf); PG_RETURN_BOOL(contains); }
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))); }
END_TEST START_TEST(test_false_positives) { float p = 0.01; int n = 10000; BloomFilter *bf = BloomFilterCreateWithPAndN(p, n); float fp = 0; int i; for (i = 0; i < n; i++) BloomFilterAdd(bf, &i, sizeof(int)); for (i = 0; i < n; i++) { int r = rand(); if (BloomFilterContains(bf, &r, sizeof(int))) fp++; } ck_assert_int_le(fp / n, p); }