Datum fss_merge_agg_trans(PG_FUNCTION_ARGS) { MemoryContext old; MemoryContext context; FSS *state; FSS *incoming = fss_fix_ptrs(PG_GETARG_VARLENA_P(1)); if (!AggCheckCallContext(fcinfo, &context)) elog(ERROR, "fss_merge_agg_trans called in non-aggregate context"); old = MemoryContextSwitchTo(context); if (PG_ARGISNULL(0)) { state = FSSCopy(incoming); PG_RETURN_POINTER(state); } state = fss_fix_ptrs(PG_GETARG_VARLENA_P(0)); state = FSSMerge(state, incoming); MemoryContextSwitchTo(old); PG_RETURN_POINTER(state); }
END_TEST START_TEST(test_merge) { TypeCacheEntry *typ = get_int8_type(); FSS *fss1 = FSSCreate(K, typ); FSS *fss2 = FSSCreate(K, typ); int i, j; Datum *values1, *values2; uint64_t *freqs1, *freqs2; int soft_errors; for (j = 0; j < 10; j++) { FSS *tmp = FSSCreate(K, typ); for (i = 0; i < NUM_ITEMS; i++) { int value = 10 * gaussian(); value %= 500; FSSIncrement(fss1, value); FSSIncrement(tmp, value); assert_sorted(fss1); assert_sorted(tmp); } fss2 = FSSMerge(fss2, tmp); FSSDestroy(tmp); } values1 = FSSTopK(fss1, K, NULL); freqs1 = FSSTopKCounts(fss1, K, NULL); values2 = FSSTopK(fss2, K, NULL); freqs2 = FSSTopKCounts(fss2, K, NULL); soft_errors = 0; for (i = 0; i < 10; i++) { int value1 = values1[i]; int value2 = values2[i]; ck_assert(value1 == value2); if (abs(freqs1[i] - freqs2[i]) > 10) soft_errors++; } ck_assert(soft_errors < 3); }