diff options
author | vng <viktor.govako@gmail.com> | 2015-03-21 12:55:05 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:57:09 +0300 |
commit | 792311a255f844b940fee3ade42fda4195cbaa0f (patch) | |
tree | 58314904937f4b7fdf2ac2e4e675d84e98790203 | |
parent | b7e5bc5301e1563664028677d36711a4a0872fee (diff) |
Feature index refactoring.
31 files changed, 220 insertions, 210 deletions
diff --git a/generator/check_model.cpp b/generator/check_model.cpp index 4feed76d7b..a008a2c630 100644 --- a/generator/check_model.cpp +++ b/generator/check_model.cpp @@ -23,7 +23,7 @@ namespace check_model header.Load(cont.GetReader(HEADER_FILE_TAG)); FeaturesVector vec(cont, header); - vec.ForEachOffset([&] (FeatureType const & ft, uint32_t) + vec.ForEach([&] (FeatureType const & ft, uint32_t) { TypesHolder types(ft); diff --git a/generator/routing_generator.cpp b/generator/routing_generator.cpp index 198602b221..bcf5aeb0c2 100644 --- a/generator/routing_generator.cpp +++ b/generator/routing_generator.cpp @@ -271,7 +271,7 @@ void BuildRoutingIndex(string const & baseDir, string const & countryName, strin FeatureType ft; Index::FeaturesLoaderGuard loader(index, p.first.GetId()); - loader.GetFeature(fID, ft); + loader.GetFeatureByIndex(fID, ft); ft.ParseGeometry(FeatureType::BEST_GEOMETRY); diff --git a/graphics/overlay_element.hpp b/graphics/overlay_element.hpp index 0b5a5d35e8..6dcc4c4b56 100644 --- a/graphics/overlay_element.hpp +++ b/graphics/overlay_element.hpp @@ -24,13 +24,13 @@ namespace graphics struct UserInfo { MwmSet::MwmId m_mwmID; - uint32_t m_offset; + uint32_t m_fID; - UserInfo() : m_offset(0) {} + UserInfo() : m_fID(0) {} inline bool IsValid() const { return m_mwmID.IsAlive(); } inline bool operator== (UserInfo const & a) const { - return IsValid() && (a.m_mwmID == m_mwmID) && (a.m_offset == m_offset); + return IsValid() && (a.m_mwmID == m_mwmID) && (a.m_fID == m_fID); } }; diff --git a/indexer/data_header.cpp b/indexer/data_header.cpp index 83bf6dcf91..4e89333bcd 100644 --- a/indexer/data_header.cpp +++ b/indexer/data_header.cpp @@ -93,8 +93,7 @@ namespace feature WriteVarInt(w, static_cast<int32_t>(m_type)); } - void DataHeader::Load(ModelReaderPtr const & r, - version::Format format /* = version::unknownFormat */) + void DataHeader::Load(ModelReaderPtr const & r, version::Format format /* = version::lastFormat */) { ReaderSource<ModelReaderPtr> src(r); m_codingParams.Load(src); diff --git a/indexer/data_header.hpp b/indexer/data_header.hpp index 662726eae5..d4ba2d43e2 100644 --- a/indexer/data_header.hpp +++ b/indexer/data_header.hpp @@ -67,7 +67,9 @@ namespace feature //@{ void Save(FileWriter & w) const; - void Load(ModelReaderPtr const & r, version::Format format = version::unknownFormat); + /// Use lastFormat as a default value for indexes building. + /// Pass the valid format from wmw in all other cases. + void Load(ModelReaderPtr const & r, version::Format format = version::lastFormat); void LoadV1(ModelReaderPtr const & r); //@} diff --git a/indexer/feature_decl.cpp b/indexer/feature_decl.cpp index f62b6f533a..063b1afd89 100644 --- a/indexer/feature_decl.cpp +++ b/indexer/feature_decl.cpp @@ -6,6 +6,6 @@ string DebugPrint(FeatureID const & id) { ostringstream ss; - ss << "{ " << id.m_mwmId << ", " << id.m_offset << " }"; + ss << "{ " << id.m_mwmId << ", " << id.m_ind << " }"; return ss.str(); } diff --git a/indexer/feature_decl.hpp b/indexer/feature_decl.hpp index 2c0f93f88c..b0f706fa7d 100644 --- a/indexer/feature_decl.hpp +++ b/indexer/feature_decl.hpp @@ -20,24 +20,24 @@ enum EGeomType struct FeatureID { MwmSet::MwmId m_mwmId; - uint32_t m_offset; + uint32_t m_ind; - FeatureID() : m_offset(0) {} - FeatureID(MwmSet::MwmId const & mwmId, uint32_t offset) : m_mwmId(mwmId), m_offset(offset) {} + FeatureID() : m_ind(0) {} + FeatureID(MwmSet::MwmId const & mwmId, uint32_t ind) : m_mwmId(mwmId), m_ind(ind) {} bool IsValid() const { return m_mwmId.IsAlive(); } inline bool operator<(FeatureID const & r) const { if (m_mwmId == r.m_mwmId) - return m_offset < r.m_offset; + return m_ind < r.m_ind; else return m_mwmId < r.m_mwmId; } inline bool operator==(FeatureID const & r) const { - return m_mwmId == r.m_mwmId && m_offset == r.m_offset; + return (m_mwmId == r.m_mwmId && m_ind == r.m_ind); } inline bool operator!=(FeatureID const & r) const { return !(*this == r); } diff --git a/indexer/feature_loader.cpp b/indexer/feature_loader.cpp index ccb60d3d7d..85e03bb9d9 100644 --- a/indexer/feature_loader.cpp +++ b/indexer/feature_loader.cpp @@ -260,11 +260,11 @@ void LoaderCurrent::ParseMetadata() DDVector<IdxElementT, FilesContainerR::ReaderT> idx(m_Info.GetMetadataIndexReader()); auto it = lower_bound(idx.begin(), idx.end() - , make_pair(uint32_t(m_pF->m_id.m_offset), uint32_t(0)) + , make_pair(uint32_t(m_pF->m_id.m_ind), uint32_t(0)) , [](IdxElementT const & v1, IdxElementT const & v2) { return v1.first < v2.first; } ); - if (it != idx.end() && m_pF->m_id.m_offset == it->first) + if (it != idx.end() && m_pF->m_id.m_ind == it->first) { ReaderSource<FilesContainerR::ReaderT> reader(m_Info.GetMetadataReader()); reader.Skip(it->second); diff --git a/indexer/feature_processor.hpp b/indexer/feature_processor.hpp index 758e3b1cf6..d524a94940 100644 --- a/indexer/feature_processor.hpp +++ b/indexer/feature_processor.hpp @@ -22,7 +22,7 @@ namespace feature header.Load(container.GetReader(HEADER_FILE_TAG)); FeaturesVector featureSource(container, header); - featureSource.ForEachOffset(ref(toDo)); + featureSource.ForEach(ref(toDo)); } template <class ToDo> diff --git a/indexer/features_offsets_table.cpp b/indexer/features_offsets_table.cpp index 9c194b1579..e541cd12e0 100644 --- a/indexer/features_offsets_table.cpp +++ b/indexer/features_offsets_table.cpp @@ -46,13 +46,18 @@ namespace feature return unique_ptr<FeaturesOffsetsTable>(new FeaturesOffsetsTable(elias_fano_builder)); } + unique_ptr<FeaturesOffsetsTable> FeaturesOffsetsTable::LoadImpl(string const & fileName) + { + return unique_ptr<FeaturesOffsetsTable>(new FeaturesOffsetsTable(fileName)); + } + // static unique_ptr<FeaturesOffsetsTable> FeaturesOffsetsTable::Load(string const & fileName) { uint64_t size; if (!GetPlatform().GetFileSizeByFullPath(fileName, size)) return unique_ptr<FeaturesOffsetsTable>(); - return unique_ptr<FeaturesOffsetsTable>(new FeaturesOffsetsTable(fileName)); + return LoadImpl(fileName); } // static @@ -60,24 +65,19 @@ namespace feature string const & fileName, platform::LocalCountryFile const & localFile) { uint64_t size; - if (GetPlatform().GetFileSizeByFullPath(fileName,size)) - return Load(fileName); + if (GetPlatform().GetFileSizeByFullPath(fileName, size)) + return LoadImpl(fileName); - FilesContainerR mwmFileContainer(localFile.GetPath(TMapOptions::EMap)); + LOG(LINFO, ("Creating features offset table file", fileName)); - LOG(LINFO, ("Features offsets table is absent! Creating a new one.")); - - if (!mwmFileContainer.IsExist(HEADER_FILE_TAG)) - return unique_ptr<FeaturesOffsetsTable>(); - - DataHeader header; - header.Load(mwmFileContainer.GetReader(HEADER_FILE_TAG)); + FilesContainerR mwmFileContainer(localFile.GetPath(TMapOptions::EMap)); Builder builder; - FeaturesVector(mwmFileContainer, header).ForEachOffset([&builder] (FeatureType const &, uint32_t offset) + FeaturesVector::ForEachOffset(mwmFileContainer.GetReader(DATA_FILE_TAG), [&builder] (uint32_t offset) { builder.PushOffset(offset); }); + unique_ptr<FeaturesOffsetsTable> table(Build(builder)); table->Save(fileName); return table; diff --git a/indexer/features_offsets_table.hpp b/indexer/features_offsets_table.hpp index 50aca51203..b34f7073d5 100644 --- a/indexer/features_offsets_table.hpp +++ b/indexer/features_offsets_table.hpp @@ -100,8 +100,9 @@ namespace feature private: FeaturesOffsetsTable(succinct::elias_fano::elias_fano_builder & builder); + FeaturesOffsetsTable(string const & fileName); - FeaturesOffsetsTable(string const &); + static unique_ptr<FeaturesOffsetsTable> LoadImpl(string const & fileName); succinct::elias_fano m_table; diff --git a/indexer/features_vector.hpp b/indexer/features_vector.hpp index 665e7de98c..b858f33925 100644 --- a/indexer/features_vector.hpp +++ b/indexer/features_vector.hpp @@ -1,53 +1,61 @@ #pragma once -#include "indexer/feature.hpp" -#include "indexer/feature_loader_base.hpp" +#include "feature.hpp" +#include "feature_loader_base.hpp" +#include "features_offsets_table.hpp" + +#include "platform/platform.hpp" #include "coding/var_record_reader.hpp" +#include "coding/file_name_utils.hpp" /// Note! This class is NOT Thread-Safe. /// You should have separate instance of Vector for every thread. class FeaturesVector { + unique_ptr<feature::FeaturesOffsetsTable> m_table; + public: FeaturesVector(FilesContainerR const & cont, feature::DataHeader const & header) : m_LoadInfo(cont, header), m_RecordReader(m_LoadInfo.GetDataReader(), 256) { + if (header.GetFormat() >= version::v5) + { + string const & filePath = cont.GetFileName(); + size_t const sepIndex = filePath.rfind(my::GetNativeSeparator()); + string const name(filePath, sepIndex + 1, filePath.rfind(DATA_FILE_EXTENSION) - sepIndex - 1); + string const path = GetPlatform().GetIndexFileName(name, FEATURES_OFFSETS_TABLE_FILE_EXT); + + m_table = feature::FeaturesOffsetsTable::CreateIfNotExistsAndLoad(path, cont); + } } - void Get(uint64_t pos, FeatureType & ft) const + void GetByIndex(uint32_t ind, FeatureType & ft) const { uint32_t offset = 0, size = 0; - m_RecordReader.ReadRecord(pos, m_buffer, offset, size); - + m_RecordReader.ReadRecord(m_table ? m_table->GetFeatureOffset(ind) : ind, m_buffer, offset, size); ft.Deserialize(m_LoadInfo.GetLoader(), &m_buffer[offset]); } - template <class ToDo> void ForEachOffset(ToDo toDo) const + template <class ToDo> void ForEach(ToDo toDo) const { - m_RecordReader.ForEachRecord(DoGetFeatures<ToDo>(m_LoadInfo, toDo)); + uint32_t ind = 0; + m_RecordReader.ForEachRecord([&] (uint32_t pos, char const * data, uint32_t /*size*/) + { + FeatureType ft; + ft.Deserialize(m_LoadInfo.GetLoader(), data); + toDo(ft, m_table ? ind++ : pos); + }); } -private: - template <class ToDo> class DoGetFeatures + template <class ToDo> static void ForEachOffset(ModelReaderPtr reader, ToDo toDo) { - feature::SharedLoadInfo const & m_loadInfo; - ToDo & m_toDo; - - public: - DoGetFeatures(feature::SharedLoadInfo const & loadInfo, ToDo & toDo) - : m_loadInfo(loadInfo), m_toDo(toDo) - { - } - - void operator() (uint32_t pos, char const * data, uint32_t /*size*/) const + VarRecordReader<ModelReaderPtr, &VarRecordSizeReaderVarint> recordReader(reader, 256); + recordReader.ForEachRecord([&] (uint32_t pos, char const * /*data*/, uint32_t /*size*/) { - FeatureType ft; - ft.Deserialize(m_loadInfo.GetLoader(), data); - - m_toDo(ft, pos); - } - }; + toDo(pos); + }); + } private: feature::SharedLoadInfo m_LoadInfo; diff --git a/indexer/index.cpp b/indexer/index.cpp index edba96bef6..ac01d91f14 100644 --- a/indexer/index.cpp +++ b/indexer/index.cpp @@ -2,10 +2,12 @@ #include "platform/platform.hpp" -#include "base/logging.hpp" #include "coding/file_name_utils.hpp" #include "coding/internal/file_data.hpp" +#include "base/logging.hpp" + + using platform::CountryFile; using platform::LocalCountryFile; @@ -91,8 +93,8 @@ bool Index::FeaturesLoaderGuard::IsWorld() const return m_handle.GetValue<MwmValue>()->GetHeader().GetType() == feature::DataHeader::world; } -void Index::FeaturesLoaderGuard::GetFeature(uint32_t offset, FeatureType & ft) +void Index::FeaturesLoaderGuard::GetFeatureByIndex(uint32_t ind, FeatureType & ft) { - m_vector.Get(offset, ft); - ft.SetID(FeatureID(m_handle.GetId(), offset)); + m_vector.GetByIndex(ind, ft); + ft.SetID(FeatureID(m_handle.GetId(), ind)); } diff --git a/indexer/index.hpp b/indexer/index.hpp index 9991798964..7eae88fe9b 100644 --- a/indexer/index.hpp +++ b/indexer/index.hpp @@ -5,6 +5,7 @@ #include "indexer/features_vector.hpp" #include "indexer/mwm_set.hpp" #include "indexer/scale_index.hpp" +#include "indexer/unique_index.hpp" #include "coding/file_container.hpp" @@ -80,36 +81,9 @@ public: private: - template <typename F> - class ReadMWMFunctor + template <typename F> class ReadMWMFunctor { - class ImplFunctor : private noncopyable - { - FeaturesVector const & m_V; - F & m_F; - unordered_set<uint32_t> m_offsets; - MwmId m_mwmID; - - public: - ImplFunctor(FeaturesVector const & v, F & f, MwmId mwmID) - : m_V(v), m_F(f), m_mwmID(mwmID) - { - } - - void operator() (uint32_t offset) - { - if (m_offsets.insert(offset).second) - { - FeatureType feature; - - m_V.Get(offset, feature); - feature.SetID(FeatureID(m_mwmID, offset)); - - m_F(feature); - } - } - }; - + F & m_f; public: ReadMWMFunctor(F & f) : m_f(f) {} @@ -135,37 +109,31 @@ private: pValue->m_factory); // iterate through intervals - ImplFunctor implF(fv, m_f, handle.GetId()); - for (size_t i = 0; i < interval.size(); ++i) - index.ForEachInIntervalAndScale(implF, interval[i].first, interval[i].second, scale); - } - } + CheckUniqueIndexes checkUnique; + MwmId const mwmID = handle.GetId(); - private: - F & m_f; - }; + for (auto const & i : interval) + { + index.ForEachInIntervalAndScale([&] (uint32_t ind) + { + if (checkUnique(ind)) + { + FeatureType feature; - template <typename F> - class ReadFeatureIndexFunctor - { - struct ImplFunctor : private noncopyable - { - public: - ImplFunctor(F & f, MwmId id) : m_f(f), m_id(id) {} + fv.GetByIndex(ind, feature); + feature.SetID(FeatureID(mwmID, ind)); - void operator() (uint32_t offset) - { - ASSERT(m_id.IsAlive(), ()); - if (m_offsets.insert(offset).second) - m_f(FeatureID(m_id, offset)); + m_f(feature); + } + }, i.first, i.second, scale); + } } + } + }; - private: - F & m_f; - MwmId m_id; - unordered_set<uint32_t> m_offsets; - }; - + template <typename F> class ReadFeatureIndexFunctor + { + F & m_f; public: ReadFeatureIndexFunctor(F & f) : m_f(f) {} @@ -188,14 +156,19 @@ private: pValue->m_factory); // iterate through intervals - ImplFunctor implF(m_f, handle.GetId()); - for (size_t i = 0; i < interval.size(); ++i) - index.ForEachInIntervalAndScale(implF, interval[i].first, interval[i].second, scale); + CheckUniqueIndexes checkUnique; + MwmId const mwmID = handle.GetId(); + + for (auto const & i : interval) + { + index.ForEachInIntervalAndScale([&] (uint32_t ind) + { + if (checkUnique(ind)) + m_f(FeatureID(mwmID, ind)); + }, i.first, i.second, scale); + } } } - - private: - F & m_f; }; public: @@ -246,7 +219,7 @@ public: inline MwmSet::MwmId GetId() const { return m_handle.GetId(); } string GetCountryFileName() const; bool IsWorld() const; - void GetFeature(uint32_t offset, FeatureType & ft); + void GetFeatureByIndex(uint32_t ind, FeatureType & ft); private: MwmHandle m_handle; @@ -269,6 +242,7 @@ public: } private: + // "features" must be sorted using FeatureID::operator< as predicate template <typename F> size_t ReadFeatureRange(F & f, vector<FeatureID> const & features, size_t index) const @@ -286,7 +260,7 @@ private: FeatureID const & featureId = features[result]; FeatureType featureType; - featureReader.Get(featureId.m_offset, featureType); + featureReader.GetByIndex(featureId.m_ind, featureType); featureType.SetID(featureId); f(featureType); diff --git a/indexer/indexer.pro b/indexer/indexer.pro index b56055175a..48399e8d7e 100644 --- a/indexer/indexer.pro +++ b/indexer/indexer.pro @@ -101,6 +101,7 @@ HEADERS += \ tesselator_decl.hpp \ tree_structure.hpp \ types_mapping.hpp \ + unique_index.hpp \ OTHER_FILES += drules_struct.proto diff --git a/indexer/indexer_tests/features_offsets_table_test.cpp b/indexer/indexer_tests/features_offsets_table_test.cpp index 2b1b854a94..677cf88dd2 100644 --- a/indexer/indexer_tests/features_offsets_table_test.cpp +++ b/indexer/indexer_tests/features_offsets_table_test.cpp @@ -79,7 +79,7 @@ namespace feature header.Load(baseContainer.GetReader(HEADER_FILE_TAG)); uint64_t builderSize = 0; - FeaturesVector(baseContainer, header).ForEachOffset([&builderSize](FeatureType const & /* type */, uint64_t) + FeaturesVector(baseContainer, header).ForEach([&builderSize](FeatureType const & /*ft*/, uint32_t /*ind*/) { ++builderSize; }); @@ -100,14 +100,11 @@ namespace feature FilesContainerR baseContainer(p.GetReader("minsk-pass" DATA_FILE_EXTENSION)); const string indexFile = CountryIndexes::GetPath(localFile, CountryIndexes::Index::Offsets); - feature::DataHeader header; - header.Load(baseContainer.GetReader(HEADER_FILE_TAG)); - FeaturesOffsetsTable::Builder builder; - FeaturesVector(baseContainer, header).ForEachOffset([&builder](FeatureType const & /* type */, uint64_t offset) - { - builder.PushOffset(offset); - }); + FeaturesVector::ForEachOffset(baseContainer.GetReader(DATA_FILE_TAG), [&builder](uint64_t offset) + { + builder.PushOffset(offset); + }); unique_ptr<FeaturesOffsetsTable> table(FeaturesOffsetsTable::Build(builder)); TEST(table.get(), ()); @@ -124,9 +121,9 @@ namespace feature // Just copy all sections except a possibly existing offsets // table section. baseContainer.ForEachTag([&baseContainer, &testContainer](string const & tag) - { - testContainer.Write(baseContainer.GetReader(tag), tag); - }); + { + testContainer.Write(baseContainer.GetReader(tag), tag); + }); table->Save(indexFile); testContainer.Finish(); } diff --git a/indexer/mwm_version.hpp b/indexer/mwm_version.hpp index a041ae9f5b..b189d9ff04 100644 --- a/indexer/mwm_version.hpp +++ b/indexer/mwm_version.hpp @@ -15,7 +15,8 @@ enum Format v2, // November 2011 (store type index, instead of raw type in mwm) v3, // March 2013 (store type index, instead of raw type in search data) v4, // April 2015 (distinguish и and й in search index) - lastFormat = v4 + v5, // July 2015 (feature id is the index in vector now). + lastFormat = v5 }; struct MwmVersion diff --git a/indexer/scale_index.hpp b/indexer/scale_index.hpp index 807662f0d8..76674f2272 100644 --- a/indexer/scale_index.hpp +++ b/indexer/scale_index.hpp @@ -54,12 +54,12 @@ public: } template <typename F> - void ForEachInIntervalAndScale(F & f, uint64_t beg, uint64_t end, uint32_t scale) const + void ForEachInIntervalAndScale(F const & f, uint64_t beg, uint64_t end, uint32_t scale) const { size_t const scaleBucket = BucketByScale(scale); if (scaleBucket < m_IndexForScale.size()) { - IntervalIndexIFace::FunctionT f1(ref(f)); + IntervalIndexIFace::FunctionT f1(cref(f)); for (size_t i = 0; i <= scaleBucket; ++i) m_IndexForScale[i]->DoForEach(f1, beg, end); } diff --git a/indexer/scale_index_builder.hpp b/indexer/scale_index_builder.hpp index 345d2edcc7..a2b7103bd5 100644 --- a/indexer/scale_index_builder.hpp +++ b/indexer/scale_index_builder.hpp @@ -23,6 +23,7 @@ #include "std/utility.hpp" #include "std/vector.hpp" + namespace covering { class CellFeaturePair @@ -100,7 +101,7 @@ public: } template <class TFeature> - void operator() (TFeature const & f, uint32_t offset) const + void operator() (TFeature const & f, uint32_t ind) const { m_scalesIdx = 0; uint32_t minScaleClassif = feature::GetMinDrawableScaleClassifOnly(f); @@ -113,14 +114,14 @@ public: // This is not immediately obvious and in fact there was an idea to map // a bucket to a contiguous range of scales. // todo(@pimenov): We probably should remove scale_index.hpp altogether. - if (!FeatureShouldBeIndexed(f, offset, bucket, bucket == minScaleClassif /* needReset */)) + if (!FeatureShouldBeIndexed(f, bucket, bucket == minScaleClassif /* needReset */)) { continue; } vector<int64_t> const cells = covering::CoverFeature(f, m_codingDepth, 250); for (int64_t cell : cells) - m_sorter.Add(CellFeatureBucketTuple(CellFeaturePair(cell, offset), bucket)); + m_sorter.Add(CellFeatureBucketTuple(CellFeaturePair(cell, ind), bucket)); m_featuresInBucket[bucket] += 1; m_cellsInBucket[bucket] += cells.size(); @@ -136,8 +137,7 @@ private: // -- it is allowed by the classificator. // If the feature is invisible at all scales, do not index it. template <class TFeature> - bool FeatureShouldBeIndexed(TFeature const & f, uint32_t offset, uint32_t scale, - bool needReset) const + bool FeatureShouldBeIndexed(TFeature const & f, uint32_t scale, bool needReset) const { while (m_scalesIdx < m_header.GetScalesCount() && m_header.GetScale(m_scalesIdx) < scale) { @@ -212,7 +212,7 @@ void IndexScales(feature::DataHeader const & header, TFeaturesVector const & fea TSorter sorter(1024 * 1024 /* bufferBytes */, tmpFilePrefix + CELL2FEATURE_TMP_EXT, out); vector<uint32_t> featuresInBucket(bucketsCount); vector<uint32_t> cellsInBucket(bucketsCount); - featuresVector.ForEachOffset( + featuresVector.ForEach( FeatureCoverer<TSorter>(header, sorter, featuresInBucket, cellsInBucket)); sorter.SortAndFinish(); diff --git a/indexer/search_index_builder.cpp b/indexer/search_index_builder.cpp index 7c31318521..50afaf92e8 100644 --- a/indexer/search_index_builder.cpp +++ b/indexer/search_index_builder.cpp @@ -158,11 +158,11 @@ struct ValueBuilder<SerializedFeatureInfoValue> ValueBuilder(serial::CodingParams const & cp) : m_valueSaver(cp) {} - void MakeValue(FeatureType const & f, feature::TypesHolder const & types, uint64_t pos, + void MakeValue(FeatureType const & f, feature::TypesHolder const & types, uint32_t ind, SerializedFeatureInfoValue & value) const { SaverT::ValueType v; - v.m_featureId = static_cast<uint32_t>(pos); + v.m_featureId = ind; // get BEST geometry rect of feature v.m_pt = feature::GetCenter(f); @@ -178,10 +178,9 @@ template <> struct ValueBuilder<FeatureIndexValue> { void MakeValue(FeatureType const & /* f */, feature::TypesHolder const & /* types */, - uint64_t pos, FeatureIndexValue & value) const + uint32_t ind, FeatureIndexValue & value) const { - ASSERT_LESS(pos, numeric_limits<uint32_t>::max(), ()); - value.m_value = static_cast<uint32_t>(pos); + value.m_value = ind; } }; @@ -314,7 +313,7 @@ public: { } - void operator() (FeatureType const & f, uint64_t pos) const + void operator() (FeatureType const & f, uint32_t ind) const { feature::TypesHolder types(f); @@ -328,7 +327,7 @@ public: // Insert synonyms only for countries and states (maybe will add cities in future). FeatureNameInserter<StringsFileT> inserter(skipIndex.IsCountryOrState(types) ? m_synonyms : 0, m_names); - m_valueBuilder.MakeValue(f, types, pos, inserter.m_val); + m_valueBuilder.MakeValue(f, types, ind, inserter.m_val); // Skip types for features without names. if (!f.ForEachNameRef(inserter)) @@ -362,28 +361,12 @@ public: } }; -template <typename FeatureInserterT> -struct FeatureInserterAdapter -{ - FeatureInserterAdapter(FeatureInserterT & inserter) : m_inserter(inserter), m_index(0) {} - - void operator()(FeatureType const & f, uint64_t pos) - { - /// @todo After VNG's refactoring the whole class should go away - /// since pos will be replaced by a feature's index. - m_inserter(f, m_index++); - } - - FeatureInserterT & m_inserter; - uint64_t m_index; -}; - void AddFeatureNameIndexPairs(FilesContainerR const & container, CategoriesHolder & categoriesHolder, StringsFile<FeatureIndexValue> & stringsFile) { feature::DataHeader header; - header.Load(container.GetReader(HEADER_FILE_TAG), version::unknownFormat); + header.Load(container.GetReader(HEADER_FILE_TAG)); FeaturesVector features(container, header); ValueBuilder<FeatureIndexValue> valueBuilder; @@ -395,8 +378,7 @@ void AddFeatureNameIndexPairs(FilesContainerR const & container, FeatureInserter<StringsFile<FeatureIndexValue>> inserter( synonyms.get(), stringsFile, categoriesHolder, header.GetScaleRange(), valueBuilder); - FeatureInserterAdapter<FeatureInserter<StringsFile<FeatureIndexValue>>> adapter(inserter); - features.ForEachOffset(adapter); + features.ForEach(inserter); } void BuildSearchIndex(FilesContainerR const & cont, CategoriesHolder const & catHolder, @@ -404,7 +386,7 @@ void BuildSearchIndex(FilesContainerR const & cont, CategoriesHolder const & cat { { feature::DataHeader header; - header.Load(cont.GetReader(HEADER_FILE_TAG), version::unknownFormat); + header.Load(cont.GetReader(HEADER_FILE_TAG)); FeaturesVector featuresV(cont, header); serial::CodingParams cp(search::GetCPForTrie(header.GetDefCodingParams())); @@ -416,7 +398,7 @@ void BuildSearchIndex(FilesContainerR const & cont, CategoriesHolder const & cat StringsFile<SerializedFeatureInfoValue> names(tmpFilePath); - featuresV.ForEachOffset(FeatureInserter<StringsFile<SerializedFeatureInfoValue>>( + featuresV.ForEach(FeatureInserter<StringsFile<SerializedFeatureInfoValue>>( synonyms.get(), names, catHolder, header.GetScaleRange(), valueBuilder)); names.EndAdding(); diff --git a/indexer/unique_index.hpp b/indexer/unique_index.hpp new file mode 100644 index 0000000000..9578045fe1 --- /dev/null +++ b/indexer/unique_index.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "../base/base.hpp" + +#include "../std/vector.hpp" + + +class CheckUniqueIndexes +{ + vector<bool> m_v; + +public: + /// Add index to the set. + /// @return true If index was absent. + bool Add(uint32_t ind) + { + if (m_v.size() <= ind) + m_v.resize(ind + 1); + bool const ret = !m_v[ind]; + m_v[ind] = true; + return ret; + } + + /// Remove index from the set. + /// @return true If index was present. + bool Remove(uint32_t ind) + { + if (m_v.size() > ind) + { + bool const ret = m_v[ind]; + m_v[ind] = false; + return ret; + } + else + return false; + } + + bool operator()(uint32_t ind) + { + return Add(ind); + } +}; diff --git a/map/framework.cpp b/map/framework.cpp index ff57c6ec2b..90b18b566f 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1340,7 +1340,7 @@ void Framework::ShowSearchResult(search::Result const & res) Index::FeaturesLoaderGuard guard(m_model.GetIndex(), id.m_mwmId); FeatureType ft; - guard.GetFeature(id.m_offset, ft); + guard.GetFeatureByIndex(id.m_ind, ft); scale = GetFeatureViewportScale(TypesHolder(ft)); center = GetCenter(ft, scale); @@ -1810,7 +1810,7 @@ bool Framework::GetVisiblePOI(m2::PointD const & pxPoint, m2::PointD & pxPivot, Index::FeaturesLoaderGuard guard(m_model.GetIndex(), ui.m_mwmID); FeatureType ft; - guard.GetFeature(ui.m_offset, ft); + guard.GetFeatureByIndex(ui.m_fID, ft); ft.ParseMetadata(); metadata = ft.GetMetadata(); @@ -1866,7 +1866,7 @@ public: Index::FeaturesLoaderGuard guard(model.GetIndex(), m_id.m_mwmId); FeatureType ft; - guard.GetFeature(m_id.m_offset, ft); + guard.GetFeatureByIndex(m_id.m_ind, ft); ft.ParseMetadata(); metadata = ft.GetMetadata(); diff --git a/map/mwm_tests/mwm_foreach_test.cpp b/map/mwm_tests/mwm_foreach_test.cpp index ce23dc7eea..f9f8c3a3f4 100644 --- a/map/mwm_tests/mwm_foreach_test.cpp +++ b/map/mwm_tests/mwm_foreach_test.cpp @@ -49,12 +49,12 @@ protected: void add(FeatureType const & f) const { TEST(f.GetID().IsValid(), ()); - m_cont.push_back(f.GetID().m_offset); + m_cont.push_back(f.GetID().m_ind); } - void add(FeatureType const &, uint32_t offset) const + void add(FeatureType const &, uint32_t ind) const { - m_cont.push_back(offset); + m_cont.push_back(ind); } public: @@ -167,10 +167,10 @@ public: { } - void operator() (FeatureType const & f, uint64_t offset) const + void operator() (FeatureType const & f, uint32_t ind) const { if (is_drawable(f) && is_intersect(f)) - add(f, offset); + add(f, ind); } }; @@ -228,20 +228,20 @@ bool compare_sequence(TCont const & etalon, TCont const & test, TCompare comp, s class FindOffset { int m_level; - uint32_t m_offset; + uint32_t m_index; public: - FindOffset(int level, uint32_t offset) - : m_level(level), m_offset(offset) + FindOffset(int level, uint32_t ind) + : m_level(level), m_index(ind) {} - void operator() (FeatureType const & f, uint64_t offset) + void operator() (FeatureType const & f, uint32_t ind) { - if (offset == m_offset) + if (ind == m_index) { TEST(IsDrawable(f, m_level), ()); - LOG(LINFO, ("Feature offset:", offset)); + LOG(LINFO, ("Feature index:", ind)); LOG(LINFO, ("Feature:", f)); } } diff --git a/render/gpu_drawer.cpp b/render/gpu_drawer.cpp index a176e14a8a..e655abc36d 100644 --- a/render/gpu_drawer.cpp +++ b/render/gpu_drawer.cpp @@ -14,7 +14,7 @@ namespace graphics::OverlayElement::UserInfo ToUserInfo(FeatureID const & id) { graphics::OverlayElement::UserInfo info; - info.m_offset = id.m_offset; + info.m_fID = id.m_ind; info.m_mwmID = id.m_mwmId; return info; } diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index 5e054a3f91..b9da490fa9 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -93,10 +93,10 @@ IRoadGraph::RoadInfo & FeaturesRoadGraph::RoadInfoCache::Find(FeatureID const & { auto itr = m_cache.find(featureId.m_mwmId); if (itr != m_cache.end()) - return itr->second->Find(featureId.m_offset, found); + return itr->second->Find(featureId.m_ind, found); itr = m_cache.insert(make_pair(featureId.m_mwmId, make_unique<TMwmFeatureCache>(kPowOfTwoForFeatureCacheSize))).first; - return itr->second->Find(featureId.m_offset, found); + return itr->second->Find(featureId.m_ind, found); } void FeaturesRoadGraph::RoadInfoCache::Clear() @@ -236,7 +236,7 @@ IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID cons FeatureType ft; Index::FeaturesLoaderGuard loader(m_index, featureId.m_mwmId); - loader.GetFeature(featureId.m_offset, ft); + loader.GetFeatureByIndex(featureId.m_ind, ft); ASSERT_EQUAL(ft.GetFeatureType(), feature::GEOM_LINE, ()); ft.ParseGeometry(FeatureType::BEST_GEOMETRY); diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index 998eddf6dd..52ca222db8 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -75,7 +75,7 @@ public: ft.ParseGeometry(FeatureType::BEST_GEOMETRY); size_t const count = ft.GetPointsCount(); - uint32_t const offset = ft.GetID().m_offset; + uint32_t const featureId = ft.GetID().m_ind; ASSERT_GREATER(count, 1, ()); for (size_t i = 1; i < count; ++i) { @@ -87,7 +87,7 @@ public: if (d < res.m_dist) { res.m_dist = d; - res.m_fid = offset; + res.m_fid = featureId; res.m_segIdx = i - 1; res.m_point = pt; } @@ -128,7 +128,7 @@ public: Index::FeaturesLoaderGuard loader(*m_pIndex, m_mwmId); FeatureType ft; - loader.GetFeature(s.m_fid, ft); + loader.GetFeatureByIndex(s.m_fid, ft); ft.ParseGeometry(FeatureType::BEST_GEOMETRY); double distMeters = 0.0; @@ -208,7 +208,7 @@ public: Index::FeaturesLoaderGuard loader(*m_pIndex, m_mwmId); FeatureType ft; - loader.GetFeature(seg.m_fid, ft); + loader.GetFeatureByIndex(seg.m_fid, ft); ft.ParseGeometry(FeatureType::BEST_GEOMETRY); // node.m_seg always forward ordered (m_pointStart < m_pointEnd) @@ -281,7 +281,7 @@ public: OsrmMappingTypes::FtSeg const & node_seg = segments[idx]; FeatureType feature; Index::FeaturesLoaderGuard loader(*m_pIndex, m_mwmId); - loader.GetFeature(node_seg.m_fid, feature); + loader.GetFeatureByIndex(node_seg.m_fid, feature); feature.ParseGeometry(FeatureType::BEST_GEOMETRY); m2::PointD const featureDirection = feature.GetPoint(node_seg.m_pointEnd) - feature.GetPoint(node_seg.m_pointStart); bool const sameDirection = (m2::DotProduct(featureDirection, m_direction) / (featureDirection.Length() * m_direction.Length()) > 0); @@ -377,7 +377,7 @@ void FindGraphNodeOffsets(size_t const nodeId, m2::PointD const & point, FeatureType ft; Index::FeaturesLoaderGuard loader(*pIndex, mapping->GetMwmId()); - loader.GetFeature(s.m_fid, ft); + loader.GetFeatureByIndex(s.m_fid, ft); Point2PhantomNode::Candidate mappedSeg; Point2PhantomNode::FindNearestSegment(ft, point, mappedSeg); @@ -768,7 +768,7 @@ OsrmRouter::ResultCode OsrmRouter::MakeTurnAnnotation(RawRoutingResult const & r FeatureType ft; Index::FeaturesLoaderGuard loader(*m_pIndex, mapping->GetMwmId()); - loader.GetFeature(seg.m_fid, ft); + loader.GetFeatureByIndex(seg.m_fid, ft); ft.ParseGeometry(FeatureType::BEST_GEOMETRY); auto startIdx = seg.m_pointStart; diff --git a/routing/routing_tests/road_graph_builder.cpp b/routing/routing_tests/road_graph_builder.cpp index 0440fcc2c3..7a61cad5ed 100644 --- a/routing/routing_tests/road_graph_builder.cpp +++ b/routing/routing_tests/road_graph_builder.cpp @@ -64,14 +64,14 @@ void RoadGraphMockSource::AddRoad(RoadInfo && ri) IRoadGraph::RoadInfo RoadGraphMockSource::GetRoadInfo(FeatureID const & featureId) const { - CHECK_LESS(featureId.m_offset, m_roads.size(), ("Invalid feature id.")); - return m_roads[featureId.m_offset]; + CHECK_LESS(featureId.m_ind, m_roads.size(), ("Invalid feature id.")); + return m_roads[featureId.m_ind]; } double RoadGraphMockSource::GetSpeedKMPH(FeatureID const & featureId) const { - CHECK_LESS(featureId.m_offset, m_roads.size(), ("Invalid feature id.")); - return m_roads[featureId.m_offset].m_speedKMPH; + CHECK_LESS(featureId.m_ind, m_roads.size(), ("Invalid feature id.")); + return m_roads[featureId.m_ind].m_speedKMPH; } double RoadGraphMockSource::GetMaxSpeedKMPH() const diff --git a/routing/turns_generator.cpp b/routing/turns_generator.cpp index f086cee707..d9bb7163fd 100644 --- a/routing/turns_generator.cpp +++ b/routing/turns_generator.cpp @@ -113,8 +113,8 @@ public: static CarModel const carModel; if (ft.GetFeatureType() != feature::GEOM_LINE || !carModel.IsRoad(ft)) return; - uint32_t const offset = ft.GetID().m_offset; - for (auto const n : m_routingMapping.m_segMapping.GetNodeIdByFid(offset)) + uint32_t const featureId = ft.GetID().m_ind; + for (auto const n : m_routingMapping.m_segMapping.GetNodeIdByFid(featureId)) n_nodeIds.push_back(n); } @@ -138,9 +138,10 @@ ftypes::HighwayClass GetOutgoingHighwayClass(NodeID outgoingNode, GetSegment(outgoingNode, routingMapping, GetFirstSegmentPointIndex); if (!seg.IsValid()) return ftypes::HighwayClass::Error; + Index::FeaturesLoaderGuard loader(index, routingMapping.GetMwmId()); FeatureType ft; - loader.GetFeature(seg.m_fid, ft); + loader.GetFeatureByIndex(seg.m_fid, ft); return ftypes::GetHighwayClass(ft); } @@ -420,7 +421,7 @@ void GetPossibleTurns(Index const & index, NodeID node, m2::PointD const & ingoi FeatureType ft; Index::FeaturesLoaderGuard loader(index, routingMapping.GetMwmId()); - loader.GetFeature(seg.m_fid, ft); + loader.GetFeatureByIndex(seg.m_fid, ft); ft.ParseGeometry(FeatureType::BEST_GEOMETRY); m2::PointD const outgoingPoint = ft.GetPoint( @@ -482,7 +483,7 @@ vector<SingleLaneInfo> GetLanesInfo(NodeID node, RoutingMapping const & routingM { FeatureType ft1; Index::FeaturesLoaderGuard loader1(index, routingMapping.GetMwmId()); - loader1.GetFeature(seg1.m_fid, ft1); + loader1.GetFeatureByIndex(seg1.m_fid, ft1); using feature::Metadata; ft1.ParseMetadata(); @@ -731,8 +732,8 @@ void GetTurnDirection(Index const & index, TurnInfo & turnInfo, TurnItem & turn) FeatureType ingoingFeature, outgoingFeature; Index::FeaturesLoaderGuard ingoingLoader(index, turnInfo.m_routeMapping.GetMwmId()); Index::FeaturesLoaderGuard outgoingLoader(index, turnInfo.m_routeMapping.GetMwmId()); - ingoingLoader.GetFeature(turnInfo.m_ingoingSegment.m_fid, ingoingFeature); - outgoingLoader.GetFeature(turnInfo.m_outgoingSegment.m_fid, outgoingFeature); + ingoingLoader.GetFeatureByIndex(turnInfo.m_ingoingSegment.m_fid, ingoingFeature); + outgoingLoader.GetFeatureByIndex(turnInfo.m_outgoingSegment.m_fid, outgoingFeature); ingoingFeature.ParseGeometry(FeatureType::BEST_GEOMETRY); outgoingFeature.ParseGeometry(FeatureType::BEST_GEOMETRY); diff --git a/search/house_detector.cpp b/search/house_detector.cpp index d1acffd598..2c74c28e11 100644 --- a/search/house_detector.cpp +++ b/search/house_detector.cpp @@ -242,7 +242,7 @@ void FeatureLoader::CreateLoader(MwmSet::MwmId const & mwmId) void FeatureLoader::Load(FeatureID const & id, FeatureType & f) { CreateLoader(id.m_mwmId); - m_pGuard->GetFeature(id.m_offset, f); + m_pGuard->GetFeatureByIndex(id.m_ind, f); } void FeatureLoader::Free() diff --git a/search/locality_finder.cpp b/search/locality_finder.cpp index 563ebf890c..16d864ef30 100644 --- a/search/locality_finder.cpp +++ b/search/locality_finder.cpp @@ -20,7 +20,7 @@ public: void operator() (uint32_t id) const { FeatureType ft; - m_loader.Get(id, ft); + m_loader.GetByIndex(id, ft); if (ft.GetFeatureType() != feature::GEOM_POINT) return; diff --git a/search/search_query.cpp b/search/search_query.cpp index 9774985a9f..a153921bf5 100644 --- a/search/search_query.cpp +++ b/search/search_query.cpp @@ -593,7 +593,7 @@ namespace impl if (m_pFV.get() == 0 || m_pFV->GetId() != id.m_mwmId) m_pFV.reset(new Index::FeaturesLoaderGuard(*m_query.m_pIndex, id.m_mwmId)); - m_pFV->GetFeature(id.m_offset, f); + m_pFV->GetFeatureByIndex(id.m_ind, f); f.SetID(id); m_query.GetBestMatchName(f, name); @@ -1680,7 +1680,7 @@ namespace impl // load feature FeatureType f; - m_vector.Get(v.m_featureId, f); + m_vector.GetByIndex(v.m_featureId, f); using namespace ftypes; |