diff options
author | Jochen Topf <jochen@topf.org> | 2014-05-15 09:45:13 +0200 |
---|---|---|
committer | Jochen Topf <jochen@topf.org> | 2014-05-15 09:45:13 +0200 |
commit | 48e92622f92fd0dc8ddca415c61b44730b925abf (patch) | |
tree | d42604e54cea3af09971901d90ed8f90cff5b93d /tagstats | |
parent | 6cb9e2de145ebfc8a3caad377cd40780823d1ad2 (diff) | |
download | taginfo-48e92622f92fd0dc8ddca415c61b44730b925abf.tar taginfo-48e92622f92fd0dc8ddca415c61b44730b925abf.tar.gz |
Use pair of strings instead of concatenated string for hash map.
For the geodistribution hash we concatenated the key and value with an equal
sign in between and used that as a hash key. But this will lead to problems
when the key or value contain an equals sign. So instead we do the proper
thing now and use a std::pair<const char*, const char*>.
Diffstat (limited to 'tagstats')
-rw-r--r-- | tagstats/tagstats_handler.hpp | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/tagstats/tagstats_handler.hpp b/tagstats/tagstats_handler.hpp index a03467c..41dd186 100644 --- a/tagstats/tagstats_handler.hpp +++ b/tagstats/tagstats_handler.hpp @@ -26,6 +26,7 @@ #include <fstream> #include <iostream> #include <map> +#include <utility> #include <google/sparse_hash_map> #include <boost/foreach.hpp> @@ -50,6 +51,13 @@ struct djb2_hash { return hash; } + + size_t operator()(std::pair<const char *, const char*> p) const { + std::string s = p.first; + s += '='; + s += p.second; + return operator()(s.c_str()); + } }; /** @@ -59,6 +67,10 @@ struct eqstr { bool operator()(const char* s1, const char* s2) const { return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0); } + + bool operator()(std::pair<const char*, const char*> p1, std::pair<const char*, const char*> p2) const { + return operator()(p1.first, p2.first) && operator()(p1.second, p2.second); + } }; /** @@ -181,7 +193,7 @@ public: }; // class KeyValueStats typedef google::sparse_hash_map<const char *, KeyValueStats *, djb2_hash, eqstr> key_value_hash_map_t; -typedef google::sparse_hash_map<const char *, GeoDistribution *, djb2_hash, eqstr> key_value_geodistribution_hash_map_t; +typedef google::sparse_hash_map<std::pair<const char*, const char*>, GeoDistribution *, djb2_hash, eqstr> key_value_geodistribution_hash_map_t; #endif // TAGSTATS_COUNT_TAG_COMBINATIONS struct RelationRoleStats { @@ -384,13 +396,9 @@ class TagStatsHandler : public Osmium::Handler::Base { void* ptr = geo->create_png(&size); sum_size += size; - std::vector<std::string> kv; - boost::split(kv, it->first, boost::is_any_of("=")); - kv.push_back(""); // if there is no = in key, make sure there is an empty value - statement_insert_into_tag_distributions - .bind_text(kv[0].c_str()) // column: key - .bind_text(kv[1].c_str()) // column: value + .bind_text(it->first.first) // column: key + .bind_text(it->first.second) // column: value .bind_text(for_nodes ? "n" : "w") // column: object_type .bind_blob(ptr, size) // column: png .execute(); @@ -452,14 +460,12 @@ class TagStatsHandler : public Osmium::Handler::Base { } stat->update(it->value(), object, m_string_store); - std::string keyvalue = it->key(); - keyvalue += "="; - keyvalue += it->value(); + std::pair<const char*, const char*> keyvalue = std::make_pair(it->key(), it->value()); if (object.type() == NODE) { rough_position_t location = m_map_to_int(static_cast<const Osmium::OSM::Node&>(object).position()); stat->distribution.add_coordinate(location); - key_value_geodistribution_hash_map_t::iterator gd_it = m_key_value_geodistribution.find(keyvalue.c_str()); + key_value_geodistribution_hash_map_t::iterator gd_it = m_key_value_geodistribution.find(keyvalue); if (gd_it != m_key_value_geodistribution.end()) { gd_it->second->add_coordinate(location); } @@ -471,7 +477,7 @@ class TagStatsHandler : public Osmium::Handler::Base { // coordinates of all nodes? const Osmium::OSM::WayNodeList& wnl = static_cast<const Osmium::OSM::Way&>(object).nodes(); if (!wnl.empty()) { - key_value_geodistribution_hash_map_t::iterator gd_it = m_key_value_geodistribution.find(keyvalue.c_str()); + key_value_geodistribution_hash_map_t::iterator gd_it = m_key_value_geodistribution.find(keyvalue); for (Osmium::OSM::WayNodeList::const_iterator it = wnl.begin(); it != wnl.end(); ++it) { rough_position_t location = m_storage[it->ref()]; stat->distribution.add_coordinate(location); @@ -535,10 +541,11 @@ public: } #endif // TAGSTATS_COUNT_TAG_COMBINATIONS { - Sqlite::Statement select(sdb, "SELECT key || '=' || value FROM frequent_tags;"); + Sqlite::Statement select(sdb, "SELECT key, value FROM frequent_tags;"); while (select.read()) { - std::string key_value = select.get_text(0); - m_key_value_geodistribution[m_string_store.add(key_value.c_str())] = new GeoDistribution(); + std::string key = select.get_text(0); + std::string value = select.get_text(1); + m_key_value_geodistribution[std::make_pair(m_string_store.add(key.c_str()), m_string_store.add(value.c_str()))] = new GeoDistribution(); } } { |