245 size_t selections_cap = 4 * MaxSubsets; // Start with some reasonably large initial capacity
246 LogSelection* selections = NEW_C_HEAP_ARRAY(LogSelection, selections_cap, mtLogging);
247
248 size_t n_deviates = 0;
249 const LogTagSet** deviates = NEW_C_HEAP_ARRAY(const LogTagSet*, deviating_tagsets, mtLogging);
250
251 // Generate all possible selections involving the deviating tag sets
252 for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
253 LogLevelType level = ts->level_for(this);
254 if (level == mcl) {
255 continue;
256 }
257 deviates[n_deviates++] = ts;
258 add_selections(&selections, &n_selections, &selections_cap, *ts, level);
259 }
260
261 // Reduce deviates greedily, using the "best" selection at each step to reduce the number of deviating tag sets
262 while (n_deviates > 0) {
263 size_t prev_deviates = n_deviates;
264 int max_score = 0;
265 const LogSelection* best_selection = NULL;
266 for (size_t i = 0; i < n_selections; i++) {
267
268 // Give the selection a score based on how many deviating tag sets it selects (with correct level)
269 int score = 0;
270 for (size_t d = 0; d < n_deviates; d++) {
271 if (selections[i].selects(*deviates[d]) && deviates[d]->level_for(this) == selections[i].level()) {
272 score++;
273 }
274 }
275
276 // Ignore selections with lower score than the current best even before subtracting mismatched selections
277 if (score < max_score) {
278 continue;
279 }
280
281 // Subtract from the score the number of tag sets it selects with an incorrect level
282 for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
283 if (selections[i].selects(*ts) && ts->level_for(this) != selections[i].level()) {
284 score--;
285 }
286 }
287
288 // Pick the selection with the best score, or in the case of a tie, the one with fewest tags
289 if (score > max_score ||
290 (score == max_score && best_selection != NULL && selections[i].ntags() < best_selection->ntags())) {
291 max_score = score;
292 best_selection = &selections[i];
293 }
294 }
295
296 assert(best_selection != NULL, "must always find a maximal selection");
297 add_to_config_string(*best_selection);
298
299 // Remove all deviates that this selection covered
300 for (size_t d = 0; d < n_deviates;) {
301 if (deviates[d]->level_for(this) == best_selection->level() && best_selection->selects(*deviates[d])) {
302 deviates[d] = deviates[--n_deviates];
303 continue;
304 }
305 d++;
306 }
307
308 // Add back any new deviates that this selection added (no array growth since removed > added)
309 for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
310 if (ts->level_for(this) == best_selection->level() || !best_selection->selects(*ts)) {
311 continue;
312 }
313
314 bool already_added = false;
315 for (size_t dev = 0; dev < n_deviates; dev++) {
316 if (deviates[dev] == ts) {
|
245 size_t selections_cap = 4 * MaxSubsets; // Start with some reasonably large initial capacity
246 LogSelection* selections = NEW_C_HEAP_ARRAY(LogSelection, selections_cap, mtLogging);
247
248 size_t n_deviates = 0;
249 const LogTagSet** deviates = NEW_C_HEAP_ARRAY(const LogTagSet*, deviating_tagsets, mtLogging);
250
251 // Generate all possible selections involving the deviating tag sets
252 for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
253 LogLevelType level = ts->level_for(this);
254 if (level == mcl) {
255 continue;
256 }
257 deviates[n_deviates++] = ts;
258 add_selections(&selections, &n_selections, &selections_cap, *ts, level);
259 }
260
261 // Reduce deviates greedily, using the "best" selection at each step to reduce the number of deviating tag sets
262 while (n_deviates > 0) {
263 size_t prev_deviates = n_deviates;
264 int max_score = 0;
265
266 guarantee(n_selections > 0, "Cannot find maximal selection.");
267 const LogSelection* best_selection = &selections[0];
268 for (size_t i = 0; i < n_selections; i++) {
269
270 // Give the selection a score based on how many deviating tag sets it selects (with correct level)
271 int score = 0;
272 for (size_t d = 0; d < n_deviates; d++) {
273 if (selections[i].selects(*deviates[d]) && deviates[d]->level_for(this) == selections[i].level()) {
274 score++;
275 }
276 }
277
278 // Ignore selections with lower score than the current best even before subtracting mismatched selections
279 if (score < max_score) {
280 continue;
281 }
282
283 // Subtract from the score the number of tag sets it selects with an incorrect level
284 for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
285 if (selections[i].selects(*ts) && ts->level_for(this) != selections[i].level()) {
286 score--;
287 }
288 }
289
290 // Pick the selection with the best score, or in the case of a tie, the one with fewest tags
291 if (score > max_score ||
292 (score == max_score && selections[i].ntags() < best_selection->ntags())) {
293 max_score = score;
294 best_selection = &selections[i];
295 }
296 }
297
298 add_to_config_string(*best_selection);
299
300 // Remove all deviates that this selection covered
301 for (size_t d = 0; d < n_deviates;) {
302 if (deviates[d]->level_for(this) == best_selection->level() && best_selection->selects(*deviates[d])) {
303 deviates[d] = deviates[--n_deviates];
304 continue;
305 }
306 d++;
307 }
308
309 // Add back any new deviates that this selection added (no array growth since removed > added)
310 for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
311 if (ts->level_for(this) == best_selection->level() || !best_selection->selects(*ts)) {
312 continue;
313 }
314
315 bool already_added = false;
316 for (size_t dev = 0; dev < n_deviates; dev++) {
317 if (deviates[dev] == ts) {
|