@@ -45,13 +45,12 @@ namespace fuzztest::internal {
4545// Corpus
4646// ------------------------------------------------------------------------------
4747
48- // Returns the weight of `fv` computed using `fs` and `coverage_frontier`.
49- static size_t ComputeWeight (const FeatureVec &fv, const FeatureSet &fs,
50- const CoverageFrontier &coverage_frontier) {
51- size_t weight = fs.ComputeWeight (fv);
48+ // Returns the weight of `fv` computed using `coverage_frontier`.
49+ static size_t ComputeFrontierWeight (const FeatureVec& fv,
50+ const CoverageFrontier& coverage_frontier) {
5251 // The following is checking for the cases where PCTable is not present. In
5352 // such cases, we cannot use any ControlFlow related features.
54- if (coverage_frontier.MaxPcIndex () == 0 ) return weight ;
53+ if (coverage_frontier.MaxPcIndex () == 0 ) return 1 ;
5554 size_t frontier_weights_sum = 0 ;
5655 for (const auto feature : fv) {
5756 if (!feature_domains::kPCs .Contains (feature)) continue ;
@@ -63,7 +62,7 @@ static size_t ComputeWeight(const FeatureVec &fv, const FeatureSet &fs,
6362 frontier_weights_sum += coverage_frontier.FrontierWeight (pc_index);
6463 }
6564 }
66- return weight * ( frontier_weights_sum + 1 ) ; // Multiply by at least 1.
65+ return frontier_weights_sum + 1 ; // Multiply by at least 1.
6766}
6867
6968std::pair<size_t , size_t > Corpus::MaxAndAvgSize () const {
@@ -79,14 +78,27 @@ std::pair<size_t, size_t> Corpus::MaxAndAvgSize() const {
7978
8079void Corpus::UpdateWeights (const FeatureSet& fs,
8180 const CoverageFrontier& coverage_frontier,
82- bool scale_by_exec_time) {
81+ WeightMethod method, bool scale_by_exec_time) {
8382 std::vector<double > weights;
8483 weights.resize (records_.size ());
8584 for (size_t i = 0 , n = records_.size (); i < n; ++i) {
8685 auto & record = records_[i];
8786 const size_t unseen = fs.PruneFeaturesAndCountUnseen (record.features );
8887 FUZZTEST_CHECK_EQ (unseen, 0 );
89- weights[i] = fs.ComputeWeight (record.features );
88+ switch (method) {
89+ case WeightMethod::Uniform:
90+ weights[i] = 1 ;
91+ break ;
92+ case WeightMethod::Recency:
93+ weights[i] = i + 1 ;
94+ break ;
95+ case WeightMethod::Rarity:
96+ weights[i] = fs.ComputeRarityWeight (record.features );
97+ break ;
98+ default :
99+ FUZZTEST_LOG (FATAL) << " Unknown corpus weight method" ;
100+ }
101+ weights[i] *= ComputeFrontierWeight (record.features , coverage_frontier);
90102 }
91103 if (scale_by_exec_time) {
92104 double total_exec_time_usec = 0 ;
@@ -199,7 +211,8 @@ void Corpus::Add(const ByteArray& data, const FeatureVec& fv,
199211 << " Got request to add empty element to corpus: ignoring" ;
200212 FUZZTEST_CHECK_EQ (records_.size (), weighted_distribution_.size ());
201213 records_.push_back ({data, fv, metadata, stats});
202- weighted_distribution_.AddWeight (ComputeWeight (fv, fs, coverage_frontier));
214+ // Will be updated by `UpdateWeights`.
215+ weighted_distribution_.AddWeight (0 );
203216}
204217
205218const CorpusRecord& Corpus::WeightedRandom (absl::BitGenRef rng) const {
0 commit comments