2016-08-31 10:51:59 -07:00
|
|
|
#ifndef RUNTIME_ERROR_COSTS_H_
|
|
|
|
|
#define RUNTIME_ERROR_COSTS_H_
|
|
|
|
|
|
|
|
|
|
#define ERROR_COST_PER_SKIPPED_TREE 10
|
|
|
|
|
#define ERROR_COST_PER_SKIPPED_LINE 3
|
|
|
|
|
#define ERROR_COST_PER_SKIPPED_CHAR 0
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
unsigned cost;
|
|
|
|
|
unsigned count;
|
2016-08-31 17:29:14 -07:00
|
|
|
unsigned push_count;
|
2016-08-31 10:51:59 -07:00
|
|
|
} ErrorStatus;
|
|
|
|
|
|
2016-08-31 17:29:14 -07:00
|
|
|
static double error_threshold(unsigned push_count) {
|
|
|
|
|
return 6 * ERROR_COST_PER_SKIPPED_TREE / (1 + push_count / 2);
|
|
|
|
|
}
|
2016-08-31 10:51:59 -07:00
|
|
|
|
2016-08-31 17:29:14 -07:00
|
|
|
static inline int error_status_compare(ErrorStatus a, ErrorStatus b) {
|
2016-08-31 10:51:59 -07:00
|
|
|
// TODO remove
|
|
|
|
|
a.cost += ERROR_COST_PER_SKIPPED_TREE * a.count;
|
|
|
|
|
b.cost += ERROR_COST_PER_SKIPPED_TREE * b.count;
|
|
|
|
|
|
2016-08-31 17:29:14 -07:00
|
|
|
if ((a.count + 1 < b.count) ||
|
2016-08-31 10:51:59 -07:00
|
|
|
(a.count < b.count && a.cost <= b.cost)) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-31 17:29:14 -07:00
|
|
|
if ((b.count + 1 < a.count) ||
|
2016-08-31 10:51:59 -07:00
|
|
|
(b.count < a.count && b.cost <= a.cost)) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-31 17:29:14 -07:00
|
|
|
if (a.cost == b.cost) {
|
|
|
|
|
if (a.cost + error_threshold(a.push_count) < b.cost) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2016-08-31 10:51:59 -07:00
|
|
|
|
2016-08-31 17:29:14 -07:00
|
|
|
if (b.cost + error_threshold(b.push_count) < a.cost) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2016-08-31 10:51:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|