开发者

unordered_multimap<string, string> to map<string, string> soft search, How to do such thing and how to preprocessed maps for faster search?

We have a map<boost::shared_ptr<service>, rules> service_map where rules is

struct rules
{
boost::unordered_multimap<string, string> set_of_rules_1;
boost::unordered_multimap<string, string> set_of_rules_2;
}

In my case of rules are pairs from of http request headers and arguments, for example in one such unordered_multimap we could find Accept-Language : FR and Accept-Language : US.

Each boost::shared_ptr<service> is some instance of class that inherits from service class.

I fill this map of servise <-> rules on fly with services and rules (from some shared libs and some text files with rules).

Now I am 开发者_开发百科given instances of data

struct data
{
map<string, string> headers;
map<string, string> arguments;
}

For each given data object I need to find most relevant service from service_map and call its service->inherited_method();

By relevant here we mean one whose rules fit to given data mostly. For example if we have in rules Accept-Language : FR and Accept-Language : US than if data contains pair Accept-Language : fr-FR,ru;q=0.8,en-US;q=0.6,en;q=0.4 we think it is relevant.

What would be best way to preprocess my service_map for faster soft search, and how to implement such search?


This is a tall order, and you'll have to develop some of the logic yourself. However, here's a skeleton solution:

1) Write a function that ranks rules according to their relevance for a given set of data:

int relevance(const rules & r, const data & d); // write this

2) For each piece of data, create a sorted ranking of the rules. For instance, you could keep a bunch of iterators around. Then find the service that matches the most relevant rule set.

typedef RuleCollection::const_iterator rit;

boost::shared_ptr<service> find_service(cosnt data & d, ...)
{
  std::multimap<int, rit> relevant_rules;

  for (rit it = rc.begin(), end = rc.end(); it != end; ++it)
  {
    // relevant_rules[relevance(*it, d)] = it; // sorry, that was nonsense
    relevant_rules.insert(std::make_pair(relevance(*it, d), it));
  }

  for (auto it = relevant_rules.rbegin(), rend = relevant_rules.rend(); it != rend; ++it)
  {
    for (auto st = service_map.begin(), end = service_map.end(); st != end; ++st)
    {
      if (*st->second == *it->second) return st->first;
    }
  }
  throw std::exception("Could not find suitable service.");
}

I'm supposing that all your rules are kept in RuleCollection rc;, some container of value type rules.

Edit: Fixed multimap element insertion -- multimap does not have a [] access operator for obvious reasons.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜