@@ -526,6 +526,50 @@ FUZZ_TARGET(txgraph)
526526 // these here without making more calls to real, which could affect its internal
527527 // state. A full comparison is done at the end.
528528 break ;
529+ } else if (!sel_sim.IsOversized () && command-- == 0 ) {
530+ // CountDistinctClusters.
531+ std::vector<TxGraph::Ref*> refs;
532+ // Gather a list of up to 15 (or up to 255) Ref pointers.
533+ auto count = provider.ConsumeIntegralInRange <size_t >(0 , alt ? 255 : 15 );
534+ refs.resize (count);
535+ for (size_t i = 0 ; i < count; ++i) {
536+ refs[i] = pick_fn ();
537+ }
538+ // Their order should not matter, shuffle them.
539+ std::shuffle (refs.begin (), refs.end (), rng);
540+ // Invoke the real function.
541+ auto result = real->CountDistinctClusters (refs, use_main);
542+ // Build a vector with representatives of the clusters the Refs occur in in the
543+ // simulated graph. For each, remember the lowest-index transaction SimPos in the
544+ // cluster.
545+ std::vector<DepGraphIndex> sim_reps;
546+ for (auto ref : refs) {
547+ // Skip Refs that do not occur in the simulated graph.
548+ auto simpos = sel_sim.Find (ref);
549+ if (simpos == SimTxGraph::MISSING) continue ;
550+ // Start with component equal to just the Ref's SimPos.
551+ auto component = SimTxGraph::SetType::Singleton (simpos);
552+ // Keep adding ancestors/descendants of all elements in component until it no
553+ // longer changes.
554+ while (true ) {
555+ auto old_component = component;
556+ for (auto i : component) {
557+ component |= sel_sim.graph .Ancestors (i);
558+ component |= sel_sim.graph .Descendants (i);
559+ }
560+ if (component == old_component) break ;
561+ }
562+ // Remember the lowest-index SimPos in component, as a representative for it.
563+ assert (component.Any ());
564+ sim_reps.push_back (component.First ());
565+ }
566+ // Remove duplicates from sim_reps.
567+ std::sort (sim_reps.begin (), sim_reps.end ());
568+ sim_reps.erase (std::unique (sim_reps.begin (), sim_reps.end ()), sim_reps.end ());
569+ // Compare the number of deduplicated representatives with the value returned by
570+ // the real function.
571+ assert (result == sim_reps.size ());
572+ break ;
529573 } else if (command-- == 0 ) {
530574 // DoWork.
531575 real->DoWork ();
0 commit comments