@@ -45,15 +45,15 @@ 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 ;
56- for (const auto feature : fv) {
55+ for (size_t i = 0 ; i < fv.size (); ++i) {
56+ const auto feature = fv[i];
5757 if (!feature_domains::kPCs .Contains (feature)) continue ;
5858 const auto pc_index = ConvertPCFeatureToPcIndex (feature);
5959 // Avoid checking frontier for out-of-bounds indices.
@@ -63,7 +63,7 @@ static size_t ComputeWeight(const FeatureVec &fv, const FeatureSet &fs,
6363 frontier_weights_sum += coverage_frontier.FrontierWeight (pc_index);
6464 }
6565 }
66- return weight * ( frontier_weights_sum + 1 ) ; // Multiply by at least 1.
66+ return frontier_weights_sum + 1 ; // Multiply by at least 1.
6767}
6868
6969std::pair<size_t , size_t > Corpus::MaxAndAvgSize () const {
@@ -79,14 +79,27 @@ std::pair<size_t, size_t> Corpus::MaxAndAvgSize() const {
7979
8080void Corpus::UpdateWeights (const FeatureSet& fs,
8181 const CoverageFrontier& coverage_frontier,
82- bool scale_by_exec_time) {
82+ WeightMethod method, bool scale_by_exec_time) {
8383 std::vector<double > weights;
8484 weights.resize (records_.size ());
8585 for (size_t i = 0 , n = records_.size (); i < n; ++i) {
8686 auto & record = records_[i];
8787 const size_t unseen = fs.PruneFeaturesAndCountUnseen (record.features );
8888 FUZZTEST_CHECK_EQ (unseen, 0 );
89- weights[i] = fs.ComputeWeight (record.features );
89+ switch (method) {
90+ case WeightMethod::Uniform:
91+ weights[i] = 1 ;
92+ break ;
93+ case WeightMethod::Recency:
94+ weights[i] = i;
95+ break ;
96+ case WeightMethod::Rarity:
97+ weights[i] = fs.ComputeRarityWeight (record.features );
98+ break ;
99+ default :
100+ FUZZTEST_LOG (FATAL) << " Unknown corpus weight method" ;
101+ }
102+ weights[i] *= ComputeFrontierWeight (record.features , coverage_frontier);
90103 }
91104 if (scale_by_exec_time) {
92105 double total_exec_time_usec = 0 ;
@@ -199,7 +212,8 @@ void Corpus::Add(const ByteArray& data, const FeatureVec& fv,
199212 << " Got request to add empty element to corpus: ignoring" ;
200213 FUZZTEST_CHECK_EQ (records_.size (), weighted_distribution_.size ());
201214 records_.push_back ({data, fv, metadata, stats});
202- weighted_distribution_.AddWeight (ComputeWeight (fv, fs, coverage_frontier));
215+ // Will be updated by `UpdateWeights`.
216+ weighted_distribution_.AddWeight (0 );
203217}
204218
205219const CorpusRecord& Corpus::WeightedRandom (absl::BitGenRef rng) const {
0 commit comments