Open castilma opened 2 years ago
This looks like a problem with the blocked bloom filter configuration. There isn't currently a way to change that exposed in the interface, but try editing src/theft_run.c
to provide larger sizes than the default configuration:
@@ -101,7 +101,11 @@ theft_run_init(const struct theft_run_config *cfg, struct theft **output) {
/* If all arguments are hashable, then attempt to use
* a bloom filter to avoid redundant checking. */
if (all_hashable) {
- t->bloom = theft_bloom_init(NULL);
+ struct theft_bloom_config cfg = {
+ .top_block_bits = 12, /* 12 to 14 */
+ .min_filter_bits = 12,
+ };
+ t->bloom = theft_bloom_init(&cfg);
}
With that setting I'm getting more reasonable results:
.top_block_bits == 12:
== PASS 'test_ipv6_dups': pass 4178707, fail 0, skip 0, dup 821293
== PASS 'test_ipv6_dups': pass 4179940, fail 0, skip 0, dup 820060
.top_block_bits == 14:
== PASS 'test_ipv6_dups': pass 4395986, fail 0, skip 0, dup 604014
== PASS 'test_ipv6_dups': pass 4396817, fail 0, skip 0, dup 603183
Why is the hash function called 5136711 times?
Rather than storing the argument hashes it recalculates them on demand, and it uses the hashes both to check if the arguments have already been run AND to mark them as run, in sufficiently different code paths that retaining them does not seem worthwhile. There shouldn't be any expectation that the arguments will be hashed exactly once per trial. It will hash lots of variants of the input while shrinking failures.
Also, with autoshrink enabled, you don't need to provide a hash function at all -- it will hash the bits consumed by theft_random_choice
, which should work well as long as the autoshrink invariants are met. Commenting out .hash = ipv6_hash_cb,
gets a very similar result.
It should probably check the trial count in the configuration, and use larger values than the default if the trial count is higher than a certain threshold -- 5 million trials is enough to saturate the bloom filter even with its automatic growing strategy, its settings were tuned with around 10k - 100k trials in mind. I can't promise I'll get to it soon, but I will probably cut a new patch release with that, because the current behavior is pretty broken with very large trial counts.
Thanks for the detailed report, it made reproducing this easy.
ITheft says there are many duplicates when I test with big trial numbers. But the output seems to be misleading?
I interpret the output like this. Theft created 5000000 test inputs. Then it called the test function only 136711 times. The other 4863289 inputs were not tested, because they were duplicates.
Is my understanding correct?
My test inputs are ipv6 addresses. Therefore I find it highly unlikely to get this many duplicates. Either the random number generator is bad, or the hash function used to check for duplicates is bad.
I printed the generated inputs and the hashes:
Why is the hash function called 5136711 times? If there are 5000000 different hashes, then the test should pass that many times, and have no duplicates!
I must be misinterpreting thefts output. And if that's true, the output is quiet misleading, IMHO.
I'm using theft 0.4.5.
Here is the code.