Browse Source

Add support for thresh policy with k=1 or k=n

analysis
Pieter Wuille 5 years ago
parent
commit
53d3658095
  1. 20
      compiler.cpp

20
compiler.cpp

@ -147,16 +147,17 @@ Policy Parse(Span<const char>& in) {
if (!sub.back()()) return Policy(Policy::Type::NONE);
}
return Policy(Policy::Type::AND, std::move(sub));
} else if (Func("thresh", expr) || Func("thres", expr)) {
} else if (Func("thresh", expr)) {
auto arg = Expr(expr);
uint32_t count = std::stoul(std::string(arg.begin(), arg.end()));
if (count < 1 || count > 16) return Policy(Policy::Type::NONE);
if (count < 1) return Policy(Policy::Type::NONE);
std::vector<Policy> sub;
while (expr.size()) {
if (!Const(",", expr)) return Policy(Policy::Type::NONE);
sub.emplace_back(Parse(expr));
if (!sub.back()()) return Policy(Policy::Type::NONE);
}
if (sub.size() > 100 || count > sub.size()) return Policy(Policy::Type::NONE);
return Policy(Policy::Type::THRESH, std::move(sub), count);
}
@ -298,14 +299,25 @@ const Strat* ComputeStrategy(const Policy& node, std::unordered_map<const Policy
for (const auto& s : subs) {
if (!s) return {};
}
if (std::all_of(node.sub.begin(), node.sub.end(), [&](const Policy& x){ return x.node_type == Policy::Type::PK; })) {
if (node.sub.size() <= 20 && std::all_of(node.sub.begin(), node.sub.end(), [&](const Policy& x){ return x.node_type == Policy::Type::PK; })) {
std::vector<std::string> keys;
for (const Policy& x : node.sub) {
keys.push_back(x.keys[0]);
}
strats.push_back(MakeStrat(store, Strat::Type::THRESH_M, std::move(keys), node.k));
}
strats.push_back(MakeStrat(store, Strat::Type::THRESH, std::move(subs), node.k, (double)node.k / subs.size()));
if (node.k > 1 && node.k < node.sub.size()) {
strats.push_back(MakeStrat(store, Strat::Type::THRESH, subs, node.k, (double)node.k / subs.size()));
}
if (node.k == 1 || node.k == node.sub.size()) {
while (subs.size() > 1) {
auto rep = MakeStrat(store, node.k == 1 ? Strat::Type::OR : Strat::Type::AND, Vector(*(subs.rbegin() + 1), subs.back()), 1.0 / subs.size());
subs.pop_back();
subs.pop_back();
subs.push_back(MakeStrat(store, Strat::Type::CACHE, Vector(rep)));
}
strats.push_back(subs[0]);
}
break;
}
}

Loading…
Cancel
Save