[fix](Nereids) use a threshold to check the equal double values in n-th rank (#17118)

The cost is inaccurate, so we use a threshold to check the equal double values
This commit is contained in:
谢健
2023-02-24 22:12:47 +08:00
committed by GitHub
parent a90e11a025
commit 83e5ecdecc

View File

@ -51,7 +51,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
@ -721,20 +720,24 @@ public class Memo {
* In unrank() function, we will extract the actual physical function according the unique ID
*/
public long rank(long n) {
double threshold = 0.000000001;
Preconditions.checkArgument(n > 0, "the n %d must be greater than 0 in nthPlan", n);
List<Pair<Long, Double>> plans = rankGroup(root, PhysicalProperties.GATHER);
Queue<Pair<Long, Double>> rankingQueue = new PriorityQueue<>(
(l, r) -> -Double.compare(l.second, r.second));
for (Pair<Long, Double> plan : plans) {
if (rankingQueue.size() == 0 || rankingQueue.size() < n) {
rankingQueue.add(plan);
} else if (rankingQueue.peek().second > plan.second) {
rankingQueue.poll();
rankingQueue.add(plan);
plans = plans.stream().filter(
p -> !p.second.equals(Double.NaN)
&& !p.second.equals(Double.POSITIVE_INFINITY)
&& !p.second.equals(Double.NEGATIVE_INFINITY))
.collect(Collectors.toList());
// This is big heap, it always pops the element with larger cost or larger id.
PriorityQueue<Pair<Long, Double>> pq = new PriorityQueue<>((l, r) -> Math.abs(l.second - r.second) < threshold
? -Long.compare(l.first, r.first) : -Double.compare(l.second, r.second));
for (Pair<Long, Double> p : plans) {
pq.add(p);
if (pq.size() > n) {
pq.poll();
}
}
return rankingQueue.peek().first;
return pq.peek().first;
}
private List<Pair<Long, Double>> rankGroup(Group group, PhysicalProperties prop) {