const M *getPolicySet();
};
-inline boost::string_ref s(const flatbuffers::String *str) {
- return boost::string_ref(str->c_str(), str->size());
-}
-
-template <typename T, typename I>
-bool match(const T &match, const I *i) {
- return match.match(makeMessageType(i->type()),
- s(i->interface()),
- s(i->path()),
- s(i->member()),
- s(i->name()),
- i->is_name_prefix(),
- makeDecision(i->decision()->decision()));
-}
-
ldp_xml_parser::DecisionItem StorageBackendSerialized::StorageBackendSerializedImpl::getDecisionFromSendIndex(const MatchItemSend &item,
- const MapIndex &index, const SendPrefixIndex &prefixIndex) {
- ldp_xml_parser::DecisionItem decision(ldp_xml_parser::Decision::ANY);
+ const FB::PolicySend *policy) {
+
+ const auto *index = policy->index();
+
+ if (!index || index->size() == 0) // this indicates version earlier than LDP2
+ return getDecisionItem(item, policy); // make it old way for old databases
+
+ std::pair<const ItemSend*, uint32_t> currentBest(nullptr, 0);
+
+ auto updateCurrentBest = [¤tBest, &item, &policy](const flatbuffers::Vector<uint32_t> *vec) {
+ // look from the back, the rule is the same as for the full database
+ // we now only check among less elements, because the database is indexed to small lists
+ // item_scores are in increasing order in the index, and they serve also as ids of the policy rules
+ for (auto item_score_it = vec->rbegin(); item_score_it != vec->rend(); item_score_it++) {
+ const auto *fb_item = policy->items()->Get(*item_score_it - 1); // rules are indexed/scored from 1
+ if (*item_score_it > currentBest.second && match(item, fb_item)) {
+ currentBest.first = fb_item;
+ currentBest.second = *item_score_it;
+ return;
+ } else if (*item_score_it <= currentBest.second) {
+ // there is no need to look further as we can't improve the score anymore
+ return;
+ }
+ }
+ };
- ItemWithScore currentBest(nullptr, 0);
+ auto searchAndUpdateCurrentBest = [¤tBest, &index, &updateCurrentBest](boost::string_ref name_ref) {
+ // we need to create C-string for flatbuffers lookups
+ // boost::string_ref gives us correct start, but possibly NUL-terminated in a wrong place, as it does not modify
+ // input string and keeps only the length
+ std::string name(name_ref.data(), name_ref.size());
- auto updateCurrentBest = [¤tBest, &item, &index](boost::string_ref name) {
// check if there are any rules for the name
- auto fit = index.find(name);
- if (fit == index.end())
+ const auto *fit = index->LookupByKey(name.c_str());
+ if (!fit)
return;
// check if there's any chance to get better score