From: Piotr Ginalski Date: Thu, 16 Jun 2022 15:54:50 +0000 (+0200) Subject: Changes based on upstream pull request comments X-Git-Tag: auth-4.8.0-alpha0~36^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f52e47ebf309a3e748becc3c780ced343decbd82;p=thirdparty%2Fpdns.git Changes based on upstream pull request comments --- diff --git a/pdns/lua-record.cc b/pdns/lua-record.cc index fa8de9e612..4ad9a7ff6b 100644 --- a/pdns/lua-record.cc +++ b/pdns/lua-record.cc @@ -311,7 +311,8 @@ static std::string getGeo(const std::string& ip, GeoIPInterface::GeoIPQueryAttri return g_getGeo(ip, (int)qa); } -static string pickRandomString(const vector& items) +template +static T pickRandom(const vector& items) { if (items.empty()) { throw std::invalid_argument("The items list cannot be empty"); @@ -319,24 +320,8 @@ static string pickRandomString(const vector& items) return items[dns_random(items.size())]; } -static ComboAddress pickRandomComboAddress(const vector& items) -{ - if (items.empty()) { - throw std::invalid_argument("The items list cannot be empty"); - } - return items[dns_random(items.size())]; -} - -static string pickHashedString(const ComboAddress& who, const vector& items) -{ - if (items.empty()) { - throw std::invalid_argument("The items list cannot be empty"); - } - ComboAddress::addressOnlyHash aoh; - return items[aoh(who) % items.size()]; -} - -static ComboAddress pickHashedComboAddress(const ComboAddress& who, const vector& items) +template +static T pickHashed(const ComboAddress& who, const vector& items) { if (items.empty()) { throw std::invalid_argument("The items list cannot be empty"); @@ -345,13 +330,14 @@ static ComboAddress pickHashedComboAddress(const ComboAddress& who, const vector return items[aoh(who) % items.size()]; } -static string pickWeightedRandomString(const vector< pair >& items) +template +static T pickWeightedRandom(const vector< pair >& items) { if (items.empty()) { throw std::invalid_argument("The items list cannot be empty"); } int sum=0; - vector< pair > pick; + vector< pair > pick; pick.reserve(items.size()); for(auto& i : items) { @@ -360,46 +346,22 @@ static string pickWeightedRandomString(const vector< pair >& items) } if (sum == 0) { - /* we should not have any weight of zero, but better safe than sorry */ - return std::string(); - } - - int r = dns_random(sum); - auto p = upper_bound(pick.begin(), pick.end(), r, [](int rarg, const decltype(pick)::value_type& a) { return rarg < a.first; }); - return p->second; -} - -static ComboAddress pickWeightedRandomComboAddress(const vector< pair >& items) -{ - if (items.empty()) { - throw std::invalid_argument("The items list cannot be empty"); - } - int sum=0; - vector< pair > pick; - pick.reserve(items.size()); - - for(auto& i : items) { - sum += i.first; - pick.emplace_back(sum, ComboAddress(i.second)); - } - - if (sum == 0) { - /* we should not have any weight of zero, but better safe than sorry */ - return ComboAddress(); + throw std::invalid_argument("The sum of items cannot be zero"); } int r = dns_random(sum); - auto p = upper_bound(pick.begin(), pick.end(), r, [](int rarg, const decltype(pick)::value_type& a) { return rarg < a.first; }); + auto p = upper_bound(pick.begin(), pick.end(), r, [](int rarg, const typename decltype(pick)::value_type& a) { return rarg < a.first; }); return p->second; } -static string pickWeightedHashedString(const ComboAddress& bestwho, vector< pair >& items) +template +static T pickWeightedHashed(const ComboAddress& bestwho, vector< pair >& items) { if (items.empty()) { throw std::invalid_argument("The items list cannot be empty"); } int sum=0; - vector< pair > pick; + vector< pair > pick; pick.reserve(items.size()); for(auto& i : items) { @@ -408,48 +370,23 @@ static string pickWeightedHashedString(const ComboAddress& bestwho, vector< pair } if (sum == 0) { - /* we should not have any weight of zero, but better safe than sorry */ - return std::string(); - } - - ComboAddress::addressOnlyHash aoh; - int r = aoh(bestwho) % sum; - auto p = upper_bound(pick.begin(), pick.end(), r, [](int rarg, const decltype(pick)::value_type& a) { return rarg < a.first; }); - return p->second; -} - -static ComboAddress pickWeightedHashedComboAddress(const ComboAddress& bestwho, vector< pair >& items) -{ - if (items.empty()) { - throw std::invalid_argument("The items list cannot be empty"); - } - int sum=0; - vector< pair > pick; - pick.reserve(items.size()); - - for(auto& i : items) { - sum += i.first; - pick.push_back({sum, ComboAddress(i.second)}); - } - - if (sum == 0) { - /* we should not have any weight of zero, but better safe than sorry */ - return ComboAddress(); + throw std::invalid_argument("The sum of items cannot be zero"); } ComboAddress::addressOnlyHash aoh; int r = aoh(bestwho) % sum; - auto p = upper_bound(pick.begin(), pick.end(), r, [](int rarg, const decltype(pick)::value_type& a) { return rarg < a.first; }); + auto p = upper_bound(pick.begin(), pick.end(), r, [](int rarg, const typename decltype(pick)::value_type& a) { return rarg < a.first; }); return p->second; } -static vector pickRandomStrings(int n, const vector& items) +template +static vector pickRandomSample(int n, const vector& items) { if (items.empty()) { throw std::invalid_argument("The items list cannot be empty"); } - vector pick; + vector pick; pick.reserve(items.size()); for(auto& item : items) { @@ -459,14 +396,14 @@ static vector pickRandomStrings(int n, const vector& items) int count = std::min(std::max(0, n), items.size()); if (count == 0) { - return vector(); + return vector(); } auto rdev = std::random_device {}; auto reng = std::default_random_engine { rdev() }; std::shuffle(pick.begin(), pick.end(), reng); - vector result = {pick.begin(), pick.begin() + count}; + vector result = {pick.begin(), pick.begin() + count}; return result; } @@ -512,7 +449,7 @@ static bool getLatLon(const std::string& ip, string& loc) >>> deg = int(R) >>> min = int((R - int(R)) * 60.0) >>> sec = (((R - int(R)) * 60.0) - min) * 60.0 - >>> print("{}º {}' {}\"".format(deg, min, sec)) + >>> print("{}ยบ {}' {}\"".format(deg, min, sec)) */ @@ -590,14 +527,14 @@ static vector useSelector(const std::string &selector, const Combo if(selector=="all") return candidates; else if(selector=="random") - ret.emplace_back(pickRandomComboAddress(candidates)); + ret.emplace_back(pickRandom(candidates)); else if(selector=="pickclosest") ret.emplace_back(pickclosest(bestwho, candidates)); else if(selector=="hashed") - ret.emplace_back(pickHashedComboAddress(bestwho, candidates)); + ret.emplace_back(pickHashed(bestwho, candidates)); else { g_log<(candidates)); } return ret; @@ -1005,17 +942,17 @@ static void setupLuaRecords() */ lua.writeFunction("pickrandom", [](const iplist_t& ips) { vector items = convStringList(ips); - return pickRandomString(items); + return pickRandom(items); }); lua.writeFunction("pickrandomsample", [](int n, const iplist_t& ips) { vector items = convStringList(ips); - return pickRandomStrings(n, items); + return pickRandomSample(n, items); }); lua.writeFunction("pickhashed", [](const iplist_t& ips) { vector items = convStringList(ips); - return pickHashedString(s_lua_record_ctx->bestwho, items); + return pickHashed(s_lua_record_ctx->bestwho, items); }); /* * Returns a random IP address from the supplied list, as weighted by the @@ -1024,7 +961,7 @@ static void setupLuaRecords() */ lua.writeFunction("pickwrandom", [](std::unordered_map ips) { vector< pair > items = convIntStringPairList(ips); - return pickWeightedRandomString(items); + return pickWeightedRandom(items); }); /* @@ -1039,7 +976,7 @@ static void setupLuaRecords() for(auto& i : ips) items.emplace_back(atoi(i.second[1].c_str()), i.second[2]); - return pickWeightedHashedString(s_lua_record_ctx->bestwho, items); + return pickWeightedHashed(s_lua_record_ctx->bestwho, items); });