* compare_path_costs_fuzzily * Compare the costs of two paths to see if either can be said to * dominate the other. * * We use fuzzy comparisons so that add_path() can avoid keeping both of * a pair of paths that really have insignificantly different cost. * * The fuzz_factor argument must be 1.0 plus delta, where delta is the * fraction of the smaller cost that is considered to be a s
| 188 | * in hopes of eliminating one path or the other.) |
| 189 | */ |
| 190 | static PathCostComparison |
| 191 | compare_path_costs_fuzzily(Path *path1, Path *path2, double fuzz_factor) |
| 192 | { |
| 193 | #define CONSIDER_PATH_STARTUP_COST(p) \ |
| 194 | ((p)->param_info == NULL ? (p)->parent->consider_startup : (p)->parent->consider_param_startup) |
| 195 | |
| 196 | /* |
| 197 | * Check total cost first since it's more likely to be different; many |
| 198 | * paths have zero startup cost. |
| 199 | */ |
| 200 | if (path1->total_cost > path2->total_cost * fuzz_factor) |
| 201 | { |
| 202 | /* path1 fuzzily worse on total cost */ |
| 203 | if (CONSIDER_PATH_STARTUP_COST(path1) && |
| 204 | path2->startup_cost > path1->startup_cost * fuzz_factor) |
| 205 | { |
| 206 | /* ... but path2 fuzzily worse on startup, so DIFFERENT */ |
| 207 | return COSTS_DIFFERENT; |
| 208 | } |
| 209 | /* else path2 dominates */ |
| 210 | return COSTS_BETTER2; |
| 211 | } |
| 212 | if (path2->total_cost > path1->total_cost * fuzz_factor) |
| 213 | { |
| 214 | /* path2 fuzzily worse on total cost */ |
| 215 | if (CONSIDER_PATH_STARTUP_COST(path2) && |
| 216 | path1->startup_cost > path2->startup_cost * fuzz_factor) |
| 217 | { |
| 218 | /* ... but path1 fuzzily worse on startup, so DIFFERENT */ |
| 219 | return COSTS_DIFFERENT; |
| 220 | } |
| 221 | /* else path1 dominates */ |
| 222 | return COSTS_BETTER1; |
| 223 | } |
| 224 | /* fuzzily the same on total cost ... */ |
| 225 | if (path1->startup_cost > path2->startup_cost * fuzz_factor) |
| 226 | { |
| 227 | /* ... but path1 fuzzily worse on startup, so path2 wins */ |
| 228 | return COSTS_BETTER2; |
| 229 | } |
| 230 | if (path2->startup_cost > path1->startup_cost * fuzz_factor) |
| 231 | { |
| 232 | /* ... but path2 fuzzily worse on startup, so path1 wins */ |
| 233 | return COSTS_BETTER1; |
| 234 | } |
| 235 | /* fuzzily the same on both costs */ |
| 236 | return COSTS_EQUAL; |
| 237 | |
| 238 | #undef CONSIDER_PATH_STARTUP_COST |
| 239 | } |
| 240 | |
| 241 | /* |
| 242 | * set_cheapest |