# # # patch "src/server_manager.cc" # from [444fdd0e31957863451d6ca36706879dfce87c9f] # to [b68337990121dee138f0ff4e0bbc2473629824ec] # # patch "src/server_manager.hh" # from [1152c59274ff86e1192341696acfe57a15a146a2] # to [f82d7eb59f9f44f0d0c5202d66864232f69fe9b0] # ============================================================ --- src/server_manager.cc 444fdd0e31957863451d6ca36706879dfce87c9f +++ src/server_manager.cc b68337990121dee138f0ff4e0bbc2473629824ec @@ -29,43 +29,6 @@ server_manager::server_manager(serverlis reload_servers(); } -server_manager::prefix::prefix(string const &s) - : str(s), ok_shorter(true) {} -server_manager::prefix::prefix(string const &s, bool b) - : str(s), ok_shorter(b) {} -server_manager::prefix::~prefix() {} -server_manager::prefix::operator string() {return str;} -int server_manager::prefix::cmp(prefix const &r) const -{ - unsigned int size = min(str.size(), r.str.size()); - int c = strncmp(str.c_str(), r.str.c_str(), size); - int longer = str.size() - r.str.size();// positive is *this is longer than r - int res = c; - if (ok_shorter == r.ok_shorter) - res = (c==0)?longer:c; - else if (ok_shorter) - res = (c==0)?max(longer,0):c; - else // (r.ok_shorter) - res = (c==0)?min(longer,0):c; -// fprintf(stderr, "cmp(<%s,%s>, <%s,%s>) = %i\n", -// str.c_str(), ok_shorter?"true":"false", -// r.str.c_str(), r.ok_shorter?"true":"false", -// res); - return res; -} -bool server_manager::prefix::operator<(prefix const &r) const -{ - return cmp(r) < 0; -} -bool server_manager::prefix::operator==(prefix const &r) const -{ - return cmp(r) == 0; -} -bool server_manager::prefix::operator>(prefix const &r) const -{ - return cmp(r) > 0; -} - void server_manager::set_opts(map > const & o) { @@ -99,7 +62,7 @@ server_manager::delist_server(shared_ptr if (j == by_name.end()) return; by_name.erase(j); - map >::iterator i; + prefix_map::iterator i; for (set::iterator j = sd.hosts.begin(); j != sd.hosts.end(); ++j) { @@ -180,6 +143,24 @@ server_manager::reload_servers() } } +namespace { + shared_ptr + find_by_prefix(server_manager::prefix_map const & servers, + string const & key) + { + for (server_manager::prefix_map::const_iterator i = servers.begin(); + i != servers.end(); ++i) + { + string const & prefix(i->first); + if (key.compare(0, min(key.size(), prefix.size()), prefix) == 0) + { + return i->second; + } + } + return shared_ptr(); + } +} + serversock server_manager::connect_to_server(string const &host, string const &pattern, @@ -187,20 +168,13 @@ server_manager::connect_to_server(string { if (!connections_allowed) throw errstr("All servers are disabled."); + shared_ptr srv; - map >::iterator i; if (!host.empty() && !by_host.empty()) - { - i = by_host.lower_bound(prefix(host, false)); - if (i != by_host.end() && i->first == prefix(host, false)) - srv = i->second; - } + srv = find_by_prefix(by_host, host); if (!srv && !pattern.empty() && !by_pattern.empty()) - { - i = by_pattern.lower_bound(prefix(pattern, false)); - if (i != by_pattern.end() && i->first == prefix(pattern, false)) - srv = i->second; - } + srv = find_by_prefix(by_pattern, pattern); + if (srv) { sock s = srv->connect(name); ============================================================ --- src/server_manager.hh 1152c59274ff86e1192341696acfe57a15a146a2 +++ src/server_manager.hh f82d7eb59f9f44f0d0c5202d66864232f69fe9b0 @@ -33,20 +33,12 @@ class server_manager set hosts, patterns; bool operator==(serverdata const &o); }; - struct prefix - { - string str; - bool ok_shorter; - prefix(string const &s); - prefix(string const &s, bool b); - ~prefix(); - operator string(); - int cmp(prefix const &r) const; - bool operator<(prefix const &r) const; - bool operator==(prefix const &r) const; - bool operator>(prefix const &r) const; - }; - map, std::greater > by_host, by_pattern; + // use std::greater so that longer strings come first + // this will make it prefer the longest prefix that matches +public: + typedef map, std::greater > prefix_map; +private: + prefix_map by_host, by_pattern; map > by_name; set > live; map, serverdata> servers;