diff options
author | Anatoly Serdtcev <serdtcev@maps.me> | 2019-05-08 13:35:42 +0300 |
---|---|---|
committer | mpimenov <mpimenov@users.noreply.github.com> | 2019-06-03 12:29:34 +0300 |
commit | 947cae3105dae88a4f5d904d3ea48129d2e072b1 (patch) | |
tree | 6eb7c65c1e1c2ef3b0265569abb7b281c5c6a6d5 /generator | |
parent | 2f393239dfd53f2bce6d0fdebcc2e62a5d067fe9 (diff) |
[generator] Add parallel ready for KeyValueStorage
Diffstat (limited to 'generator')
-rw-r--r-- | generator/geo_objects/geo_object_info_getter.hpp | 9 | ||||
-rw-r--r-- | generator/geo_objects/geo_objects.cpp | 20 | ||||
-rw-r--r-- | generator/key_value_storage.cpp | 18 | ||||
-rw-r--r-- | generator/key_value_storage.hpp | 27 | ||||
-rw-r--r-- | generator/regions/region_info_getter.cpp | 19 | ||||
-rw-r--r-- | generator/regions/region_info_getter.hpp | 6 | ||||
-rw-r--r-- | generator/streets/streets_builder.cpp | 10 | ||||
-rw-r--r-- | generator/streets/streets_builder.hpp | 4 |
8 files changed, 65 insertions, 48 deletions
diff --git a/generator/geo_objects/geo_object_info_getter.hpp b/generator/geo_objects/geo_object_info_getter.hpp index f922f910d1..f91175d84e 100644 --- a/generator/geo_objects/geo_object_info_getter.hpp +++ b/generator/geo_objects/geo_object_info_getter.hpp @@ -10,6 +10,8 @@ #include "base/geo_object_id.hpp" +#include <functional> +#include <memory> #include <utility> #include <vector> @@ -29,7 +31,7 @@ public: GeoObjectInfoGetter(indexer::GeoObjectsIndex<IndexReader> && index, KeyValueStorage && kvStorage); template <typename Predicate> - boost::optional<base::Json> Find(m2::PointD const & point, Predicate && pred) const; + std::shared_ptr<JsonValue> Find(m2::PointD const & point, Predicate && pred) const; private: std::vector<base::GeoObjectId> SearchObjectsInIndex(m2::PointD const & point) const; @@ -39,7 +41,8 @@ private: }; template <typename Predicate> -boost::optional<base::Json> GeoObjectInfoGetter::Find(m2::PointD const & point, Predicate && pred) const +std::shared_ptr<JsonValue> GeoObjectInfoGetter::Find( + m2::PointD const & point, Predicate && pred) const { auto const ids = SearchObjectsInIndex(point); for (auto const & id : ids) @@ -48,7 +51,7 @@ boost::optional<base::Json> GeoObjectInfoGetter::Find(m2::PointD const & point, if (!object) continue; - if (pred(*object)) + if (pred(std::cref(*object))) return object; } diff --git a/generator/geo_objects/geo_objects.cpp b/generator/geo_objects/geo_objects.cpp index 4653ad7f32..f2b7ce1440 100644 --- a/generator/geo_objects/geo_objects.cpp +++ b/generator/geo_objects/geo_objects.cpp @@ -40,15 +40,15 @@ namespace { using IndexReader = ReaderPtr<Reader>; -bool HouseHasAddress(base::Json const & json) +bool HouseHasAddress(JsonValue const & json) { - auto && properties = base::GetJSONObligatoryField(json.get(), "properties"); + auto && properties = base::GetJSONObligatoryField(json, "properties"); auto && address = base::GetJSONObligatoryField(properties, "address"); auto && building = base::GetJSONOptionalField(address, "building"); return building && !base::JSONIsNull(building); } -void UpdateCoordinates(m2::PointD const & point, base::Json json) +void UpdateCoordinates(m2::PointD const & point, base::JSONPtr & json) { auto geometry = json_object_get(json.get(), "geometry"); auto coordinates = json_object_get(geometry, "coordinates"); @@ -60,9 +60,9 @@ void UpdateCoordinates(m2::PointD const & point, base::Json json) } } -base::Json AddAddress(FeatureBuilder1 const & fb, KeyValue const & regionKeyValue) +base::JSONPtr AddAddress(FeatureBuilder1 const & fb, KeyValue const & regionKeyValue) { - base::Json result = regionKeyValue.second.GetDeepCopy(); + auto result = regionKeyValue.second->MakeDeepCopyJson(); int const kHouseOrPoiRank = 30; UpdateCoordinates(fb.GetKeyPoint(), result); auto properties = json_object_get(result.get(), "properties"); @@ -94,16 +94,16 @@ MakeGeoObjectValueWithAddress(FeatureBuilder1 const & fb, KeyValue const & keyVa return std::unique_ptr<char, JSONFreeDeleter>(cstr); } -boost::optional<base::Json> +std::shared_ptr<JsonValue> FindHousePoi(FeatureBuilder1 const & fb, GeoObjectInfoGetter const & geoObjectInfoGetter) { return geoObjectInfoGetter.Find(fb.GetKeyPoint(), HouseHasAddress); } std::unique_ptr<char, JSONFreeDeleter> -MakeGeoObjectValueWithoutAddress(FeatureBuilder1 const & fb, base::Json json) +MakeGeoObjectValueWithoutAddress(FeatureBuilder1 const & fb, JsonValue const & json) { - auto const jsonWithAddress = json.GetDeepCopy(); + auto jsonWithAddress = json.MakeDeepCopyJson(); auto properties = json_object_get(jsonWithAddress.get(), "properties"); ToJSONObject(*properties, "name", fb.GetName()); UpdateCoordinates(fb.GetKeyPoint(), jsonWithAddress); @@ -152,7 +152,7 @@ void FilterAddresslessByCountryAndRepackMwm(std::string const & pathInGeoObjects if (!regionKeyValue) return; - auto && properties = base::GetJSONObligatoryField(regionKeyValue->second.get(), "properties"); + auto && properties = base::GetJSONObligatoryField(*regionKeyValue->second, "properties"); auto && address = base::GetJSONObligatoryField(properties, "address"); auto && country = base::GetJSONObligatoryField(address, "country"); auto countryName = FromJSON<std::string>(country); @@ -250,7 +250,7 @@ bool GenerateGeoObjects(std::string const & pathInRegionsIndex, BuildGeoObjectsWithAddresses(regionInfoGetter, pathInGeoObjectsTmpMwm, streamGeoObjectsKv, verbose); LOG(LINFO, ("Geo objects with addresses were built.")); - auto const pred = [](KeyValue const & kv) { return HouseHasAddress(kv.second); }; + auto const pred = [](KeyValue const & kv) { return HouseHasAddress(*kv.second); }; KeyValueStorage geoObjectsKv(pathOutGeoObjectsKv, pred); LOG(LINFO, ("Size of geo objects key-value storage:", geoObjectsKv.Size())); diff --git a/generator/key_value_storage.cpp b/generator/key_value_storage.cpp index 2c4271285a..cd7dfc218d 100644 --- a/generator/key_value_storage.cpp +++ b/generator/key_value_storage.cpp @@ -45,24 +45,20 @@ bool KeyValueStorage::ParseKeyValueLine(std::string const & line, KeyValue & res return false; } - base::Json json; - try + auto jsonString = std::string_view{line.c_str() + pos + 1}; + json_error_t jsonError; + base::JSONPtr json{json_loadb(jsonString.data(), jsonString.size(), 0, &jsonError)}; + if (!json) { - json = base::Json(line.c_str() + pos + 1); - if (!json.get()) - return false; - } - catch (base::Json::Exception const & err) - { - LOG(LWARNING, ("Cannot create base::Json in line", lineNumber, ":", err.Msg())); + LOG(LWARNING, ("Cannot create base::Json in line", lineNumber, ":", jsonError.text)); return false; } - res = std::make_pair(static_cast<uint64_t>(id), json); + res = std::make_pair(static_cast<uint64_t>(id), std::make_shared<JsonValue>(std::move(json))); return true; } -boost::optional<base::Json> KeyValueStorage::Find(uint64_t key) const +std::shared_ptr<JsonValue> KeyValueStorage::Find(uint64_t key) const { auto const it = m_values.find(key); if (it == std::end(m_values)) diff --git a/generator/key_value_storage.hpp b/generator/key_value_storage.hpp index eb4947e4a8..a0a5da5420 100644 --- a/generator/key_value_storage.hpp +++ b/generator/key_value_storage.hpp @@ -3,6 +3,7 @@ #include <cstdint> #include <fstream> #include <functional> +#include <memory> #include <string> #include <unordered_map> #include <utility> @@ -13,7 +14,27 @@ namespace generator { -using KeyValue = std::pair<uint64_t, base::Json>; +class JsonValue +{ +public: + explicit JsonValue(json_t * value = nullptr) : m_handle{value} { } + explicit JsonValue(base::JSONPtr && value) : m_handle{std::move(value)} { } + + JsonValue(JsonValue const &) = delete; + JsonValue & operator=(JsonValue const &) = delete; + + operator json_t const * () const noexcept { return m_handle.get(); } + + base::JSONPtr MakeDeepCopyJson() const + { + return base::JSONPtr{json_deep_copy(m_handle.get())}; + } + +private: + base::JSONPtr m_handle; +}; + +using KeyValue = std::pair<uint64_t, std::shared_ptr<JsonValue>>; class KeyValueStorage { @@ -27,13 +48,13 @@ public: KeyValueStorage(KeyValueStorage const &) = delete; KeyValueStorage & operator=(KeyValueStorage const &) = delete; - boost::optional<base::Json> Find(uint64_t key) const; + std::shared_ptr<JsonValue> Find(uint64_t key) const; size_t Size() const; private: static bool DefaultPred(KeyValue const &) { return true; } static bool ParseKeyValueLine(std::string const & line, KeyValue & res, std::streamoff lineNumber); - std::unordered_map<uint64_t, base::Json> m_values; + std::unordered_map<uint64_t, std::shared_ptr<JsonValue>> m_values; }; } // namespace generator diff --git a/generator/regions/region_info_getter.cpp b/generator/regions/region_info_getter.cpp index f910d0711a..6a560caf57 100644 --- a/generator/regions/region_info_getter.cpp +++ b/generator/regions/region_info_getter.cpp @@ -50,7 +50,7 @@ boost::optional<KeyValue> RegionInfoGetter::GetDeepest(m2::PointD const & point, } auto rank = GetRank(*region); - regionsByRank.emplace(rank, KeyValue{id.GetEncodedId(), std::move(*region)}); + regionsByRank.emplace(rank, KeyValue{id.GetEncodedId(), std::move(region)}); } boost::optional<uint64_t> borderCheckSkipRegionId; @@ -61,29 +61,26 @@ boost::optional<KeyValue> RegionInfoGetter::GetDeepest(m2::PointD const & point, if (regionId != borderCheckSkipRegionId && !m_borders.IsPointInside(regionId, point)) continue; - if (selector(kv.second)) + if (selector(kv)) return std::move(kv); // Skip border check for parent region. - if (auto pid = GetPid(kv.second)) + if (auto pid = GetPid(*kv.second)) borderCheckSkipRegionId = pid; } return {}; } -int RegionInfoGetter::GetRank(base::Json const & json) const +int RegionInfoGetter::GetRank(JsonValue const & json) const { - json_t * properties = nullptr; - FromJSONObject(json.get(), "properties", properties); - int rank; - FromJSONObject(properties, "rank", rank); - return rank; + auto && properties = base::GetJSONObligatoryField(json, "properties"); + return FromJSONObject<int>(properties, "rank"); } -boost::optional<uint64_t> RegionInfoGetter::GetPid(base::Json const & json) const +boost::optional<uint64_t> RegionInfoGetter::GetPid(JsonValue const & json) const { - auto && properties = base::GetJSONObligatoryField(json.get(), "properties"); + auto && properties = base::GetJSONObligatoryField(json, "properties"); auto && pid = base::GetJSONOptionalField(properties, "pid"); if (!pid || base::JSONIsNull(pid)) return {}; diff --git a/generator/regions/region_info_getter.hpp b/generator/regions/region_info_getter.hpp index eabbba0e68..77fd1c7c44 100644 --- a/generator/regions/region_info_getter.hpp +++ b/generator/regions/region_info_getter.hpp @@ -25,7 +25,7 @@ namespace regions class RegionInfoGetter { public: - using Selector = std::function<bool(base::Json const & json)>; + using Selector = std::function<bool(KeyValue const & json)>; RegionInfoGetter(std::string const & indexPath, std::string const & kvPath); @@ -39,9 +39,9 @@ private: std::vector<base::GeoObjectId> SearchObjectsInIndex(m2::PointD const & point) const; boost::optional<KeyValue> GetDeepest(m2::PointD const & point, std::vector<base::GeoObjectId> const & ids, Selector const & selector) const; - int GetRank(base::Json const & json) const; + int GetRank(JsonValue const & json) const; // Get parent id of object: optional field `properties.pid` in JSON. - boost::optional<uint64_t> GetPid(base::Json const & json) const; + boost::optional<uint64_t> GetPid(JsonValue const & json) const; indexer::RegionsIndex<IndexReader> m_index; indexer::Borders m_borders; diff --git a/generator/streets/streets_builder.cpp b/generator/streets/streets_builder.cpp index 29dce2daa1..4a00338790 100644 --- a/generator/streets/streets_builder.cpp +++ b/generator/streets/streets_builder.cpp @@ -103,8 +103,8 @@ boost::optional<KeyValue> StreetsBuilder::FindStreetRegionOwner(FeatureBuilder1 boost::optional<KeyValue> StreetsBuilder::FindStreetRegionOwner(m2::PointD const & point) { - auto const isStreetAdministrator = [] (base::Json const & region) { - auto const && properties = base::GetJSONObligatoryField(region.get(), "properties"); + auto const isStreetAdministrator = [] (KeyValue const & region) { + auto const && properties = base::GetJSONObligatoryField(*region.second, "properties"); auto const && address = base::GetJSONObligatoryField(properties, "address"); if (base::GetJSONOptionalField(address, "suburb")) @@ -137,11 +137,11 @@ bool StreetsBuilder::InsertSurrogateStreet(KeyValue const & region, std::string } std::unique_ptr<char, JSONFreeDeleter> StreetsBuilder::MakeStreetValue( - uint64_t regionId, base::Json const regionObject, std::string const & streetName) + uint64_t regionId, JsonValue const & regionObject, std::string const & streetName) { - auto const && regionProperties = base::GetJSONObligatoryField(regionObject.get(), "properties"); + auto const && regionProperties = base::GetJSONObligatoryField(regionObject, "properties"); auto const && regionAddress = base::GetJSONObligatoryField(regionProperties, "address"); - auto address = base::JSONPtr{json_deep_copy(regionAddress)}; + auto address = base::JSONPtr{json_deep_copy(const_cast<json_t *>(regionAddress))}; ToJSONObject(*address, "street", streetName); auto properties = base::NewJSONObject(); diff --git a/generator/streets/streets_builder.hpp b/generator/streets/streets_builder.hpp index 21ed6f2ecb..0d46a531b4 100644 --- a/generator/streets/streets_builder.hpp +++ b/generator/streets/streets_builder.hpp @@ -47,8 +47,8 @@ private: boost::optional<KeyValue> FindStreetRegionOwner(m2::PointD const & point); bool InsertStreet(KeyValue const & region, std::string && streetName, base::GeoObjectId id); bool InsertSurrogateStreet(KeyValue const & region, std::string && streetName); - std::unique_ptr<char, JSONFreeDeleter> MakeStreetValue(uint64_t regionId, base::Json const regionObject, - std::string const & streetName); + std::unique_ptr<char, JSONFreeDeleter> MakeStreetValue( + uint64_t regionId, JsonValue const & regionObject, std::string const & streetName); base::GeoObjectId NextOsmSurrogateId(); std::unordered_map<uint64_t, RegionStreets> m_regions; |