| 228 | } |
| 229 | |
| 230 | static size_t prune_log(struct log_book *log) |
| 231 | { |
| 232 | size_t skipped = 0, deleted = 0, count = 0, dst = 0, max, tail; |
| 233 | |
| 234 | /* Never delete the last 10% (and definitely not last one!). */ |
| 235 | tail = log->num_entries / 10 + 1; |
| 236 | max = log->num_entries - tail; |
| 237 | |
| 238 | for (count = 0; count < max; count++) { |
| 239 | struct log_entry *i = &log->log[count]; |
| 240 | |
| 241 | if (pseudorand(1000) > delete_threshold(i->level)) { |
| 242 | i->skipped += skipped; |
| 243 | skipped = 0; |
| 244 | /* Move down if necesary. */ |
| 245 | log->log[dst++] = *i; |
| 246 | continue; |
| 247 | } |
| 248 | |
| 249 | skipped += delete_entry(log, i); |
| 250 | deleted++; |
| 251 | } |
| 252 | |
| 253 | /* Any skipped at tail go on the next entry */ |
| 254 | log->log[count].skipped += skipped; |
| 255 | |
| 256 | /* Move down the last 10% */ |
| 257 | memmove(log->log + dst, log->log + count, tail * sizeof(*log->log)); |
| 258 | return deleted; |
| 259 | } |
| 260 | |
| 261 | static void destroy_log_book(struct log_book *log) |
| 262 | { |
no test coverage detected