Skip to content

Commit 552eaee

Browse files
tatiana-yanmaksimandrianov
authored andcommitted
[indexer] Lazy metadata read.
1 parent 29eb04a commit 552eaee

File tree

18 files changed

+130
-61
lines changed

18 files changed

+130
-61
lines changed

drape_frontend/rule_drawer.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,17 @@ double GetBuildingHeightInMeters(FeatureType & f)
5252
double constexpr kDefaultHeightInMeters = 3.0;
5353
double constexpr kMetersPerLevel = 3.0;
5454

55-
feature::Metadata const & md = f.GetMetadata();
5655
double heightInMeters = kDefaultHeightInMeters;
5756

58-
std::string value = md.Get(feature::Metadata::FMD_HEIGHT);
57+
std::string value = f.GetMetadata(feature::Metadata::FMD_HEIGHT);
5958
if (!value.empty())
6059
{
6160
if (!strings::to_double(value, heightInMeters))
6261
heightInMeters = kDefaultHeightInMeters;
6362
}
6463
else
6564
{
66-
value = md.Get(feature::Metadata::FMD_BUILDING_LEVELS);
65+
value = f.GetMetadata(feature::Metadata::FMD_BUILDING_LEVELS);
6766
if (!value.empty())
6867
{
6968
if (strings::to_double(value, heightInMeters))
@@ -75,8 +74,7 @@ double GetBuildingHeightInMeters(FeatureType & f)
7574

7675
double GetBuildingMinHeightInMeters(FeatureType & f)
7776
{
78-
feature::Metadata const & md = f.GetMetadata();
79-
std::string value = md.Get(feature::Metadata::FMD_MIN_HEIGHT);
77+
std::string value = f.GetMetadata(feature::Metadata::FMD_MIN_HEIGHT);
8078
if (value.empty())
8179
return 0.0;
8280

@@ -92,12 +90,11 @@ df::BaseApplyFeature::HotelData ExtractHotelData(FeatureType & f)
9290
df::BaseApplyFeature::HotelData result;
9391
if (ftypes::IsBookingChecker::Instance()(f))
9492
{
95-
auto const & metadata = f.GetMetadata();
9693
result.m_isHotel = true;
97-
result.m_rating = metadata.Get(feature::Metadata::FMD_RATING);
98-
if (!strings::to_int(metadata.Get(feature::Metadata::FMD_STARS), result.m_stars))
94+
result.m_rating = f.GetMetadata(feature::Metadata::FMD_RATING);
95+
if (!strings::to_int(f.GetMetadata(feature::Metadata::FMD_STARS), result.m_stars))
9996
result.m_stars = 0;
100-
if (!strings::to_int(metadata.Get(feature::Metadata::FMD_PRICE_RATE), result.m_priceCategory))
97+
if (!strings::to_int(f.GetMetadata(feature::Metadata::FMD_PRICE_RATE), result.m_priceCategory))
10198
result.m_priceCategory = 0;
10299
}
103100
return result;

feature_list/feature_list.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,10 @@ class Processor
205205
{
206206
f.ParseBeforeStatistic();
207207
string const & category = GetReadableType(f);
208+
auto const & meta = f.GetMetadata();
208209
// "operator" is a reserved word, hence "operatr". This word is pretty
209210
// common in C++ projects.
210-
string const & operatr = f.GetMetadata().Get(feature::Metadata::FMD_OPERATOR);
211+
string const & operatr = meta.Get(feature::Metadata::FMD_OPERATOR);
211212
auto const & osmIt = ft2osm.find(f.GetID().m_index);
212213
if ((!f.HasName() && operatr.empty()) ||
213214
(f.GetGeomType() == feature::GeomType::Line && category != "highway-pedestrian") ||
@@ -238,7 +239,7 @@ class Processor
238239
{
239240
// For sponsored types, adding invented sponsored ids (booking = 00) to the id tail.
240241
if (ftypes::IsBookingChecker::Instance()(f))
241-
osmId = f.GetMetadata().Get(feature::Metadata::FMD_SPONSORED_ID) + "00";
242+
osmId = meta.Get(feature::Metadata::FMD_SPONSORED_ID) + "00";
242243
}
243244
string const & uid = BuildUniqueId(ll, name);
244245
string const & lat = strings::to_string_with_digits_after_comma(ll.m_lat, 6);
@@ -261,17 +262,17 @@ class Processor
261262
addrHouse = addr.GetHouseNumber();
262263
}
263264
}
264-
string const & phone = f.GetMetadata().Get(feature::Metadata::FMD_PHONE_NUMBER);
265-
string const & website = f.GetMetadata().Get(feature::Metadata::FMD_WEBSITE);
266-
string cuisine = f.GetMetadata().Get(feature::Metadata::FMD_CUISINE);
265+
string const & phone = meta.Get(feature::Metadata::FMD_PHONE_NUMBER);
266+
string const & website = meta.Get(feature::Metadata::FMD_WEBSITE);
267+
string cuisine = meta.Get(feature::Metadata::FMD_CUISINE);
267268
replace(cuisine.begin(), cuisine.end(), ';', ',');
268-
string const & stars = f.GetMetadata().Get(feature::Metadata::FMD_STARS);
269-
string const & internet = f.GetMetadata().Get(feature::Metadata::FMD_INTERNET);
270-
string const & denomination = f.GetMetadata().Get(feature::Metadata::FMD_DENOMINATION);
269+
string const & stars = meta.Get(feature::Metadata::FMD_STARS);
270+
string const & internet = meta.Get(feature::Metadata::FMD_INTERNET);
271+
string const & denomination = meta.Get(feature::Metadata::FMD_DENOMINATION);
271272
string const & wheelchair = GetWheelchairType(f);
272-
string const & opening_hours = f.GetMetadata().Get(feature::Metadata::FMD_OPEN_HOURS);
273-
string const & wikipedia = f.GetMetadata().GetWikiURL();
274-
string const & floor = f.GetMetadata().Get(feature::Metadata::FMD_LEVEL);
273+
string const & opening_hours = meta.Get(feature::Metadata::FMD_OPEN_HOURS);
274+
string const & wikipedia = meta.GetWikiURL();
275+
string const & floor = meta.Get(feature::Metadata::FMD_LEVEL);
275276
string const & fee = strings::EndsWith(category, "-fee") ? "yes" : "";
276277
string const & atm = HasAtm(f) ? "yes" : "";
277278

generator/generator_tests_support/test_feature.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ void TestFeature::Init()
8989

9090
bool TestFeature::Matches(FeatureType & feature) const
9191
{
92-
istringstream is(feature.GetMetadata().Get(Metadata::FMD_TEST_ID));
92+
istringstream is(feature.GetMetadata(Metadata::FMD_TEST_ID));
9393
uint64_t id;
9494
is >> id;
9595
return id == m_id;

generator/search_index_builder.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ bool InsertPostcodes(FeatureType & f, function<void(strings::UniString const &)>
247247
using namespace search;
248248

249249
auto const & postBoxChecker = ftypes::IsPostBoxChecker::Instance();
250-
string const postcode = f.GetMetadata().Get(feature::Metadata::FMD_POSTCODE);
250+
string const postcode = f.GetMetadata(feature::Metadata::FMD_POSTCODE);
251251
vector<string> postcodes;
252252
if (!postcode.empty())
253253
postcodes.push_back(postcode);
@@ -332,17 +332,17 @@ class FeatureInserter
332332

333333
if (ftypes::IsAirportChecker::Instance()(types))
334334
{
335-
string const iata = f.GetMetadata().Get(feature::Metadata::FMD_AIRPORT_IATA);
335+
string const iata = f.GetMetadata(feature::Metadata::FMD_AIRPORT_IATA);
336336
if (!iata.empty())
337337
inserter(StringUtf8Multilang::kDefaultCode, iata);
338338
}
339339

340340
// Index operator to support "Sberbank ATM" for objects with amenity=atm and operator=Sberbank.
341-
string const op = f.GetMetadata().Get(feature::Metadata::FMD_OPERATOR);
341+
string const op = f.GetMetadata(feature::Metadata::FMD_OPERATOR);
342342
if (!op.empty())
343343
inserter(StringUtf8Multilang::kDefaultCode, op);
344344

345-
string const brand = f.GetMetadata().Get(feature::Metadata::FMD_BRAND);
345+
string const brand = f.GetMetadata(feature::Metadata::FMD_BRAND);
346346
if (!brand.empty())
347347
{
348348
auto const & brands = indexer::GetDefaultBrands();

generator/utils.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ bool ParseFeatureIdToTestIdMapping(std::string const & path,
117117
{
118118
bool success = true;
119119
feature::ForEachFeature(path, [&](FeatureType & feature, uint32_t fid) {
120-
auto const & metatada = feature.GetMetadata();
121-
auto const testIdStr = metatada.Get(feature::Metadata::FMD_TEST_ID);
120+
auto const testIdStr = feature.GetMetadata(feature::Metadata::FMD_TEST_ID);
122121
uint64_t testId;
123122
if (!strings::to_uint64(testIdStr, testId))
124123
{

indexer/drules_selector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ bool GetRating(FeatureType & ft, double & rating)
160160
{
161161
double constexpr kDefaultRating = 0.0;
162162

163-
string ratingStr = ft.GetMetadata().Get(feature::Metadata::FMD_RATING);
163+
string ratingStr = ft.GetMetadata(feature::Metadata::FMD_RATING);
164164
if (ratingStr.empty() || !strings::to_double(ratingStr, rating))
165165
rating = kDefaultRating;
166166
return true;

indexer/feature.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ FeatureType::FeatureType(osm::MapObject const & emo)
244244

245245
m_metadata = emo.GetMetadata();
246246
m_parsed.m_metadata = true;
247+
m_parsed.m_metaIds = true;
247248

248249
CHECK_LESS_OR_EQUAL(emo.GetTypes().Size(), feature::kMaxTypesCount, ());
249250
copy(emo.GetTypes().begin(), emo.GetTypes().end(), m_types.begin());
@@ -586,6 +587,28 @@ void FeatureType::ParseMetadata()
586587
m_parsed.m_metadata = true;
587588
}
588589

590+
void FeatureType::ParseMetaIds()
591+
{
592+
if (m_parsed.m_metaIds)
593+
return;
594+
595+
CHECK(m_loadInfo, ());
596+
try
597+
{
598+
auto const format = m_loadInfo->GetMWMFormat();
599+
if (format >= version::Format::v11)
600+
UNUSED_VALUE(m_metadataDeserializer->GetIds(m_id.m_index, m_metaIds));
601+
else
602+
ParseMetadata();
603+
}
604+
catch (Reader::OpenException const &)
605+
{
606+
// now ignore exception because not all mwm have needed sections
607+
}
608+
609+
m_parsed.m_metaIds = true;
610+
}
611+
589612
StringUtf8Multilang const & FeatureType::GetNames()
590613
{
591614
ParseCommon();
@@ -803,8 +826,33 @@ string FeatureType::GetRoadNumber()
803826
return m_params.ref;
804827
}
805828

806-
feature::Metadata & FeatureType::GetMetadata()
829+
feature::Metadata const & FeatureType::GetMetadata()
807830
{
808831
ParseMetadata();
809832
return m_metadata;
810833
}
834+
835+
std::string FeatureType::GetMetadata(feature::Metadata::EType type)
836+
{
837+
ParseMetaIds();
838+
if (m_metadata.Has(type))
839+
return m_metadata.Get(type);
840+
841+
auto const it = base::FindIf(m_metaIds, [&type](auto const & v) { return v.first == type; });
842+
if (it == m_metaIds.end())
843+
return {};
844+
845+
auto const value = m_metadataDeserializer->GetMetaById(it->second);
846+
m_metadata.Set(type, value);
847+
return value;
848+
}
849+
850+
bool FeatureType::HasMetadata(feature::Metadata::EType type)
851+
{
852+
ParseMetaIds();
853+
if (m_metadata.Has(type))
854+
return true;
855+
856+
return base::FindIf(m_metaIds, [&type](auto const & v) { return v.first == type; }) !=
857+
m_metaIds.end();
858+
}

indexer/feature.hpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,11 @@ class FeatureType
157157
uint64_t GetPopulation();
158158
std::string GetRoadNumber();
159159

160-
feature::Metadata & GetMetadata();
160+
feature::Metadata const & GetMetadata();
161+
162+
// Gets single metadata string. Does not parse all metadata.
163+
std::string GetMetadata(feature::Metadata::EType type);
164+
bool HasMetadata(feature::Metadata::EType type);
161165

162166
/// @name Statistic functions.
163167
//@{
@@ -195,8 +199,12 @@ class FeatureType
195199
bool m_points = false;
196200
bool m_triangles = false;
197201
bool m_metadata = false;
202+
bool m_metaIds = false;
198203

199-
void Reset() { m_types = m_common = m_header2 = m_points = m_triangles = m_metadata = false; }
204+
void Reset()
205+
{
206+
m_types = m_common = m_header2 = m_points = m_triangles = m_metadata = m_metaIds = false;
207+
}
200208
};
201209

202210
struct Offsets
@@ -218,6 +226,7 @@ class FeatureType
218226
void ParseCommon();
219227
void ParseHeader2();
220228
void ParseMetadata();
229+
void ParseMetaIds();
221230
void ParseGeometryAndTriangles(int scale);
222231

223232
uint8_t m_header = 0;
@@ -235,6 +244,7 @@ class FeatureType
235244
using Points = buffer_vector<m2::PointD, kStaticBufferSize>;
236245
Points m_points, m_triangles;
237246
feature::Metadata m_metadata;
247+
indexer::MetadataDeserializer::MetaIds m_metaIds;
238248

239249
// Non-owning pointer to shared load info. SharedLoadInfo created once per FeaturesVector.
240250
feature::SharedLoadInfo const * m_loadInfo = nullptr;

indexer/indexer_tests/features_vector_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ UNIT_TEST(FeaturesVectorTest_ParseMetadata)
6565
map<string, int> actual;
6666
fv.ForEach([&](FeatureType & ft, uint32_t index)
6767
{
68-
string postcode = ft.GetMetadata().Get(feature::Metadata::FMD_POSTCODE);
68+
string postcode = ft.GetMetadata(feature::Metadata::FMD_POSTCODE);
6969
if (!postcode.empty())
7070
++actual[postcode];
7171
});

indexer/metadata_serdes.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ void MetadataDeserializer::Header::Read(Reader & reader)
2525
m_metadataMapSize = ReadPrimitiveFromSource<uint32_t>(source);
2626
}
2727

28-
bool MetadataDeserializer::Get(uint32_t id, feature::MetadataBase & meta)
28+
bool MetadataDeserializer::Get(uint32_t featureId, feature::MetadataBase & meta)
2929
{
3030
MetaIds metaIds;
31-
if (!m_map->GetThreadsafe(id, metaIds))
31+
if (!m_map->GetThreadsafe(featureId, metaIds))
3232
return false;
3333

3434
lock_guard<mutex> guard(m_stringsMutex);
@@ -40,6 +40,17 @@ bool MetadataDeserializer::Get(uint32_t id, feature::MetadataBase & meta)
4040
return true;
4141
}
4242

43+
bool MetadataDeserializer::GetIds(uint32_t featureId, MetaIds & metaIds) const
44+
{
45+
return m_map->GetThreadsafe(featureId, metaIds);
46+
}
47+
48+
std::string MetadataDeserializer::GetMetaById(uint8_t id)
49+
{
50+
lock_guard<mutex> guard(m_stringsMutex);
51+
return m_strings.ExtractString(*m_stringsSubreader, id);
52+
}
53+
4354
// static
4455
unique_ptr<MetadataDeserializer> MetadataDeserializer::Load(Reader & reader)
4556
{

0 commit comments

Comments
 (0)