diff options
author | vng <viktor.govako@gmail.com> | 2015-07-16 14:31:31 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:57:12 +0300 |
commit | 8fdd97d52366659ec16cf4d4edf3ab98f96b0874 (patch) | |
tree | 1381c0061d93b5ee60b658df1659f3fa265312d0 /indexer | |
parent | 0dc6675aa5d9cc8e19f1ec02a927eae826d97944 (diff) |
Minor refactoring to store feature’s offsets table once for every cache value in mwm set.
Diffstat (limited to 'indexer')
-rw-r--r-- | indexer/data_factory.cpp | 7 | ||||
-rw-r--r-- | indexer/data_factory.hpp | 1 | ||||
-rw-r--r-- | indexer/feature_processor.hpp | 9 | ||||
-rw-r--r-- | indexer/features_offsets_table.cpp | 57 | ||||
-rw-r--r-- | indexer/features_offsets_table.hpp | 23 | ||||
-rw-r--r-- | indexer/features_vector.cpp | 41 | ||||
-rw-r--r-- | indexer/features_vector.hpp | 58 | ||||
-rw-r--r-- | indexer/index.cpp | 41 | ||||
-rw-r--r-- | indexer/index.hpp | 27 | ||||
-rw-r--r-- | indexer/index_builder.cpp | 9 | ||||
-rw-r--r-- | indexer/index_builder.hpp | 4 | ||||
-rw-r--r-- | indexer/indexer.pro | 1 | ||||
-rw-r--r-- | indexer/indexer_tests/features_offsets_table_test.cpp | 43 | ||||
-rw-r--r-- | indexer/indexer_tests/index_builder_test.cpp | 7 | ||||
-rw-r--r-- | indexer/indexer_tests/test_mwm_set.hpp | 27 | ||||
-rw-r--r-- | indexer/mwm_set.cpp | 18 | ||||
-rw-r--r-- | indexer/mwm_set.hpp | 11 | ||||
-rw-r--r-- | indexer/scale_index_builder.hpp | 5 | ||||
-rw-r--r-- | indexer/search_index_builder.cpp | 18 |
19 files changed, 236 insertions, 171 deletions
diff --git a/indexer/data_factory.cpp b/indexer/data_factory.cpp index bec67e9a92..e1fd15b847 100644 --- a/indexer/data_factory.cpp +++ b/indexer/data_factory.cpp @@ -1,5 +1,3 @@ -#include "base/SRC_FIRST.hpp" - #include "indexer/data_factory.hpp" #include "indexer/interval_index.hpp" #include "indexer/old/interval_index_101.hpp" @@ -10,11 +8,8 @@ #include "coding/file_reader.hpp" #include "coding/file_container.hpp" -namespace -{ -using FHeaderT = feature::DataHeader; -} // namespace +using FHeaderT = feature::DataHeader; void LoadMapHeader(FilesContainerR const & cont, FHeaderT & header) { diff --git a/indexer/data_factory.hpp b/indexer/data_factory.hpp index ff30b639e2..1026496563 100644 --- a/indexer/data_factory.hpp +++ b/indexer/data_factory.hpp @@ -22,4 +22,5 @@ public: IntervalIndexIFace * CreateIndex(ModelReaderPtr reader); }; +void LoadMapHeader(FilesContainerR const & cont, feature::DataHeader & header); void LoadMapHeader(ModelReaderPtr const & reader, feature::DataHeader & header); diff --git a/indexer/feature_processor.hpp b/indexer/feature_processor.hpp index d524a94940..91710f04cc 100644 --- a/indexer/feature_processor.hpp +++ b/indexer/feature_processor.hpp @@ -16,13 +16,8 @@ namespace feature template <class ToDo> void ForEachFromDat(ModelReaderPtr reader, ToDo & toDo) { - FilesContainerR container(reader); - - DataHeader header; - header.Load(container.GetReader(HEADER_FILE_TAG)); - - FeaturesVector featureSource(container, header); - featureSource.ForEach(ref(toDo)); + FeaturesVectorTest featuresV((FilesContainerR(reader))); + featuresV.GetVector().ForEach(ref(toDo)); } template <class ToDo> diff --git a/indexer/features_offsets_table.cpp b/indexer/features_offsets_table.cpp index e541cd12e0..7ef0f64bf7 100644 --- a/indexer/features_offsets_table.cpp +++ b/indexer/features_offsets_table.cpp @@ -1,17 +1,21 @@ #include "indexer/features_offsets_table.hpp" - -#include "indexer/data_header.hpp" #include "indexer/features_vector.hpp" + #include "platform/local_country_file.hpp" +#include "platform/local_country_file_utils.hpp" #include "platform/platform.hpp" -#include "coding/file_writer.hpp" + +#include "coding/file_container.hpp" #include "coding/internal/file_data.hpp" + #include "base/assert.hpp" #include "base/logging.hpp" -#include "base/scope_guard.hpp" + #include "std/string.hpp" +using namespace platform; + namespace feature { void FeaturesOffsetsTable::Builder::PushOffset(uint32_t const offset) @@ -25,9 +29,9 @@ namespace feature { } - FeaturesOffsetsTable::FeaturesOffsetsTable(string const & fileName) + FeaturesOffsetsTable::FeaturesOffsetsTable(string const & filePath) { - m_pReader.reset(new MmapReader(fileName)); + m_pReader.reset(new MmapReader(filePath)); succinct::mapper::map(m_table, reinterpret_cast<char const *>(m_pReader->Data())); } @@ -46,49 +50,58 @@ namespace feature return unique_ptr<FeaturesOffsetsTable>(new FeaturesOffsetsTable(elias_fano_builder)); } - unique_ptr<FeaturesOffsetsTable> FeaturesOffsetsTable::LoadImpl(string const & fileName) + unique_ptr<FeaturesOffsetsTable> FeaturesOffsetsTable::LoadImpl(string const & filePath) { - return unique_ptr<FeaturesOffsetsTable>(new FeaturesOffsetsTable(fileName)); + return unique_ptr<FeaturesOffsetsTable>(new FeaturesOffsetsTable(filePath)); } // static - unique_ptr<FeaturesOffsetsTable> FeaturesOffsetsTable::Load(string const & fileName) + unique_ptr<FeaturesOffsetsTable> FeaturesOffsetsTable::Load(string const & filePath) { uint64_t size; - if (!GetPlatform().GetFileSizeByFullPath(fileName, size)) + if (!GetPlatform().GetFileSizeByFullPath(filePath, size)) return unique_ptr<FeaturesOffsetsTable>(); - return LoadImpl(fileName); + return LoadImpl(filePath); } // static unique_ptr<FeaturesOffsetsTable> FeaturesOffsetsTable::CreateIfNotExistsAndLoad( - string const & fileName, platform::LocalCountryFile const & localFile) + LocalCountryFile const & localFile) { + string const offsetsFilePath = CountryIndexes::GetPath(localFile, CountryIndexes::Index::Offsets); + uint64_t size; - if (GetPlatform().GetFileSizeByFullPath(fileName, size)) - return LoadImpl(fileName); + if (GetPlatform().GetFileSizeByFullPath(offsetsFilePath, size)) + return LoadImpl(offsetsFilePath); + + LOG(LINFO, ("Creating features offset table file", offsetsFilePath)); - LOG(LINFO, ("Creating features offset table file", fileName)); + VERIFY(CountryIndexes::PreparePlaceOnDisk(localFile), ()); - FilesContainerR mwmFileContainer(localFile.GetPath(TMapOptions::EMap)); + FilesContainerR cont(localFile.GetPath(TMapOptions::EMap)); Builder builder; - FeaturesVector::ForEachOffset(mwmFileContainer.GetReader(DATA_FILE_TAG), [&builder] (uint32_t offset) + FeaturesVector::ForEachOffset(cont.GetReader(DATA_FILE_TAG), [&builder] (uint32_t offset) { builder.PushOffset(offset); }); unique_ptr<FeaturesOffsetsTable> table(Build(builder)); - table->Save(fileName); + table->Save(offsetsFilePath); return table; } - void FeaturesOffsetsTable::Save(string const & fileName) + unique_ptr<FeaturesOffsetsTable> FeaturesOffsetsTable::CreateIfNotExistsAndLoad(FilesContainerR const & cont) + { + return CreateIfNotExistsAndLoad((LocalCountryFile::MakeTemporary(cont.GetFileName()))); + } + + void FeaturesOffsetsTable::Save(string const & filePath) { - LOG(LINFO, ("Saving features offsets table to ", fileName)); - string const fileNameTmp = fileName + EXTENSION_TMP; + LOG(LINFO, ("Saving features offsets table to ", filePath)); + string const fileNameTmp = filePath + EXTENSION_TMP; succinct::mapper::freeze(m_table, fileNameTmp.c_str()); - my::RenameFileX(fileNameTmp, fileName); + my::RenameFileX(fileNameTmp, filePath); } uint32_t FeaturesOffsetsTable::GetFeatureOffset(size_t index) const diff --git a/indexer/features_offsets_table.hpp b/indexer/features_offsets_table.hpp index b34f7073d5..f962619949 100644 --- a/indexer/features_offsets_table.hpp +++ b/indexer/features_offsets_table.hpp @@ -1,13 +1,18 @@ #pragma once #include "coding/mmap_reader.hpp" + #include "defines.hpp" + #include "std/cstdint.hpp" #include "std/unique_ptr.hpp" #include "std/vector.hpp" + #include "3party/succinct/elias_fano.hpp" #include "3party/succinct/mapper.hpp" + +class FilesContainerR; namespace platform { class LocalCountryFile; @@ -54,10 +59,10 @@ namespace feature /// mapped to the memory and used by internal structures of /// FeaturesOffsetsTable. /// - /// \param fileName a full path of the file to load or store data + /// \param filePath a full path of the file to load or store data /// \return a pointer to an instance of FeaturesOffsetsTable or nullptr /// when it's not possible to load FeaturesOffsetsTable. - static unique_ptr<FeaturesOffsetsTable> Load(string const & fileName); + static unique_ptr<FeaturesOffsetsTable> Load(string const & filePath); /// Loads FeaturesOffsetsTable from FilesMappingContainer. Note /// that some part of a file referenced by container will be @@ -68,19 +73,21 @@ namespace feature /// /// \warning May take a lot of time if there is no precomputed section /// - /// \param fileName a full path of the file to load or store data /// \param localFile Representation of the map files with features data ( uses only if we need to construct them) /// \return a pointer to an instance of FeaturesOffsetsTable or nullptr /// when it's not possible to create FeaturesOffsetsTable. - static unique_ptr<FeaturesOffsetsTable> CreateIfNotExistsAndLoad(string const & fileName, platform::LocalCountryFile const & localFile); + static unique_ptr<FeaturesOffsetsTable> CreateIfNotExistsAndLoad(platform::LocalCountryFile const & localFile); + + /// @todo The easiest solution for now. Need to be removed in future. + static unique_ptr<FeaturesOffsetsTable> CreateIfNotExistsAndLoad(FilesContainerR const & cont); FeaturesOffsetsTable(FeaturesOffsetsTable const &) = delete; FeaturesOffsetsTable const & operator=(FeaturesOffsetsTable const &) = delete; /// Serializes current instance to a section in container. /// - /// \param fileName a full path of the file to store data - void Save(string const & fileName); + /// \param filePath a full path of the file to store data + void Save(string const & filePath); /// \param index index of a feature /// \return offset a feature @@ -100,9 +107,9 @@ namespace feature private: FeaturesOffsetsTable(succinct::elias_fano::elias_fano_builder & builder); - FeaturesOffsetsTable(string const & fileName); + FeaturesOffsetsTable(string const & filePath); - static unique_ptr<FeaturesOffsetsTable> LoadImpl(string const & fileName); + static unique_ptr<FeaturesOffsetsTable> LoadImpl(string const & filePath); succinct::elias_fano m_table; diff --git a/indexer/features_vector.cpp b/indexer/features_vector.cpp new file mode 100644 index 0000000000..a070f6286b --- /dev/null +++ b/indexer/features_vector.cpp @@ -0,0 +1,41 @@ +#include "features_vector.hpp" +#include "features_offsets_table.hpp" +#include "mwm_version.hpp" +#include "data_factory.hpp" + + +void FeaturesVector::GetByIndex(uint32_t ind, FeatureType & ft) const +{ + uint32_t offset = 0, size = 0; + m_RecordReader.ReadRecord(m_table ? m_table->GetFeatureOffset(ind) : ind, m_buffer, offset, size); + ft.Deserialize(m_LoadInfo.GetLoader(), &m_buffer[offset]); +} + + +FeaturesVectorTest::FeaturesVectorTest(string const & filePath) + : m_cont(filePath), m_initializer(this), m_vector(m_cont, m_header, 0) +{ + Init(); +} + +FeaturesVectorTest::FeaturesVectorTest(FilesContainerR const & cont) + : m_cont(cont), m_initializer(this), m_vector(m_cont, m_header, 0) +{ + Init(); +} + +FeaturesVectorTest::Initializer::Initializer(FeaturesVectorTest * p) +{ + LoadMapHeader(p->m_cont, p->m_header); +} + +void FeaturesVectorTest::Init() +{ + if (m_header.GetFormat() >= version::v5) + m_vector.m_table = feature::FeaturesOffsetsTable::CreateIfNotExistsAndLoad(m_cont).release(); +} + +FeaturesVectorTest::~FeaturesVectorTest() +{ + delete m_vector.m_table; +} diff --git a/indexer/features_vector.hpp b/indexer/features_vector.hpp index b858f33925..2b90b6efeb 100644 --- a/indexer/features_vector.hpp +++ b/indexer/features_vector.hpp @@ -1,41 +1,26 @@ #pragma once #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" +#include "std/noncopyable.hpp" + + +namespace feature { class FeaturesOffsetsTable; } /// 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) + FeaturesVector(FilesContainerR const & cont, feature::DataHeader const & header, + feature::FeaturesOffsetsTable const * table) + : m_LoadInfo(cont, header), m_RecordReader(m_LoadInfo.GetDataReader(), 256), m_table(table) { - 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 GetByIndex(uint32_t ind, FeatureType & ft) const - { - uint32_t offset = 0, size = 0; - m_RecordReader.ReadRecord(m_table ? m_table->GetFeatureOffset(ind) : ind, m_buffer, offset, size); - ft.Deserialize(m_LoadInfo.GetLoader(), &m_buffer[offset]); - } + void GetByIndex(uint32_t ind, FeatureType & ft) const; template <class ToDo> void ForEach(ToDo toDo) const { @@ -61,4 +46,31 @@ private: feature::SharedLoadInfo m_LoadInfo; VarRecordReader<FilesContainerR::ReaderT, &VarRecordSizeReaderVarint> m_RecordReader; mutable vector<char> m_buffer; + + friend class FeaturesVectorTest; + feature::FeaturesOffsetsTable const * m_table; +}; + +/// Test features vector (reader) that combines all the needed data for stand-alone work. +class FeaturesVectorTest : private noncopyable +{ + FilesContainerR m_cont; + feature::DataHeader m_header; + + struct Initializer + { + Initializer(FeaturesVectorTest * p); + } m_initializer; + + FeaturesVector m_vector; + + void Init(); + +public: + explicit FeaturesVectorTest(string const & filePath); + explicit FeaturesVectorTest(FilesContainerR const & cont); + ~FeaturesVectorTest(); + + feature::DataHeader const & GetHeader() const { return m_header; } + FeaturesVector const & GetVector() const { return m_vector; } }; diff --git a/indexer/index.cpp b/indexer/index.cpp index ac01d91f14..560e38aac2 100644 --- a/indexer/index.cpp +++ b/indexer/index.cpp @@ -17,38 +17,51 @@ using platform::LocalCountryFile; MwmValue::MwmValue(LocalCountryFile const & localFile) : m_cont(GetPlatform().GetCountryReader(localFile, TMapOptions::EMap)), - m_countryFile(localFile.GetCountryFile()) + m_countryFile(localFile.GetCountryFile()), m_table(0) { m_factory.Load(m_cont); } +void MwmValue::SetTable(MwmInfoEx & info) +{ + if (GetHeader().GetFormat() >= version::v5) + { + if (!info.m_table) + info.m_table = feature::FeaturesOffsetsTable::CreateIfNotExistsAndLoad(m_cont); + m_table = info.m_table.get(); + } +} + ////////////////////////////////////////////////////////////////////////////////// // Index implementation ////////////////////////////////////////////////////////////////////////////////// -bool Index::GetVersion(LocalCountryFile const & localFile, MwmInfo & info) const +MwmInfoEx * Index::CreateInfo(platform::LocalCountryFile const & localFile) const { MwmValue value(localFile); feature::DataHeader const & h = value.GetHeader(); if (!h.IsMWMSuitable()) - return false; + return nullptr; - info.m_limitRect = h.GetBounds(); + MwmInfoEx * info = new MwmInfoEx(); + info->m_limitRect = h.GetBounds(); pair<int, int> const scaleR = h.GetScaleRange(); - info.m_minScale = static_cast<uint8_t>(scaleR.first); - info.m_maxScale = static_cast<uint8_t>(scaleR.second); - info.m_version = value.GetMwmVersion(); + info->m_minScale = static_cast<uint8_t>(scaleR.first); + info->m_maxScale = static_cast<uint8_t>(scaleR.second); + info->m_version = value.GetMwmVersion(); - return true; + return info; } -MwmSet::TMwmValueBasePtr Index::CreateValue(LocalCountryFile const & localFile) const +MwmValue * Index::CreateValue(MwmInfo & info) const { - TMwmValueBasePtr p(new MwmValue(localFile)); - ASSERT(static_cast<MwmValue &>(*p.get()).GetHeader().IsMWMSuitable(), ()); - return p; + unique_ptr<MwmValue> p(new MwmValue(info.GetLocalFile())); + p->SetTable(dynamic_cast<MwmInfoEx &>(info)); + ASSERT(p->GetHeader().IsMWMSuitable(), ()); + + return p.release(); } pair<MwmSet::MwmHandle, MwmSet::RegResult> Index::RegisterMap(LocalCountryFile const & localFile) @@ -77,7 +90,9 @@ void Index::OnMwmDeregistered(LocalCountryFile const & localFile) Index::FeaturesLoaderGuard::FeaturesLoaderGuard(Index const & parent, MwmId id) : m_handle(const_cast<Index &>(parent), id), /// @note This guard is suitable when mwm is loaded - m_vector(m_handle.GetValue<MwmValue>()->m_cont, m_handle.GetValue<MwmValue>()->GetHeader()) + m_vector(m_handle.GetValue<MwmValue>()->m_cont, + m_handle.GetValue<MwmValue>()->GetHeader(), + m_handle.GetValue<MwmValue>()->m_table) { } diff --git a/indexer/index.hpp b/indexer/index.hpp index 7eae88fe9b..2c390db385 100644 --- a/indexer/index.hpp +++ b/indexer/index.hpp @@ -2,6 +2,7 @@ #include "indexer/cell_id.hpp" #include "indexer/data_factory.hpp" #include "indexer/feature_covering.hpp" +#include "indexer/features_offsets_table.hpp" #include "indexer/features_vector.hpp" #include "indexer/mwm_set.hpp" #include "indexer/scale_index.hpp" @@ -16,18 +17,26 @@ #include "std/algorithm.hpp" #include "std/limits.hpp" -#include "std/unordered_set.hpp" #include "std/utility.hpp" #include "std/vector.hpp" + +class MwmInfoEx : public MwmInfo +{ +public: + unique_ptr<feature::FeaturesOffsetsTable> m_table; +}; + class MwmValue : public MwmSet::MwmValueBase { public: FilesContainerR m_cont; IndexFactory m_factory; platform::CountryFile const m_countryFile; + feature::FeaturesOffsetsTable const * m_table; explicit MwmValue(platform::LocalCountryFile const & localFile); + void SetTable(MwmInfoEx & info); inline feature::DataHeader const & GetHeader() const { return m_factory.GetHeader(); } inline version::MwmVersion const & GetMwmVersion() const { return m_factory.GetMwmVersion(); } @@ -38,10 +47,14 @@ public: class Index : public MwmSet { protected: - // MwmSet overrides: - bool GetVersion(platform::LocalCountryFile const & localFile, MwmInfo & info) const override; - TMwmValueBasePtr CreateValue(platform::LocalCountryFile const & localFile) const override; + /// @name MwmSet overrides. + //@{ + MwmInfoEx * CreateInfo(platform::LocalCountryFile const & localFile) const override; + + MwmValue * CreateValue(MwmInfo & info) const override; + void OnMwmDeregistered(platform::LocalCountryFile const & localFile) override; + //@} public: /// An Observer interface to MwmSet. Note that these functions can @@ -61,8 +74,6 @@ public: virtual void OnMapDeregistered(platform::LocalCountryFile const & localFile) {} }; - Index() = default; - ~Index() override = default; /// Registers a new map. WARN_UNUSED_RESULT pair<MwmHandle, RegResult> RegisterMap( @@ -104,7 +115,7 @@ private: covering::IntervalsT const & interval = cov.Get(lastScale); // prepare features reading - FeaturesVector fv(pValue->m_cont, header); + FeaturesVector fv(pValue->m_cont, header, pValue->m_table); ScaleIndex<ModelReaderPtr> index(pValue->m_cont.GetReader(INDEX_FILE_TAG), pValue->m_factory); @@ -254,7 +265,7 @@ private: MwmValue * const pValue = handle.GetValue<MwmValue>(); if (pValue) { - FeaturesVector featureReader(pValue->m_cont, pValue->GetHeader()); + FeaturesVector featureReader(pValue->m_cont, pValue->GetHeader(), pValue->m_table); while (result < features.size() && id == features[result].m_mwmId) { FeatureID const & featureId = features[result]; diff --git a/indexer/index_builder.cpp b/indexer/index_builder.cpp index 5ae2fb326e..984ff530c0 100644 --- a/indexer/index_builder.cpp +++ b/indexer/index_builder.cpp @@ -14,15 +14,10 @@ namespace indexer { string const idxFileName(tmpFile + GEOM_INDEX_TMP_EXT); { - FilesContainerR readCont(datFile); - - feature::DataHeader header; - header.Load(readCont.GetReader(HEADER_FILE_TAG)); - - FeaturesVector featuresVector(readCont, header); + FeaturesVectorTest featuresV(datFile); FileWriter writer(idxFileName); - BuildIndex(header, featuresVector, writer, tmpFile); + BuildIndex(featuresV.GetHeader(), featuresV.GetVector(), writer, tmpFile); } FilesContainerW(datFile, FileWriter::OP_WRITE_EXISTING).Write(idxFileName, INDEX_FILE_TAG); diff --git a/indexer/index_builder.hpp b/indexer/index_builder.hpp index dedfdc4192..364c81a02c 100644 --- a/indexer/index_builder.hpp +++ b/indexer/index_builder.hpp @@ -6,14 +6,14 @@ namespace indexer { template <class TFeaturesVector, typename TWriter> -void BuildIndex(feature::DataHeader const & header, TFeaturesVector const & featuresVector, +void BuildIndex(feature::DataHeader const & header, TFeaturesVector const & featuresV, TWriter & writer, string const & tmpFilePrefix) { LOG(LINFO, ("Building scale index.")); uint64_t indexSize; { SubWriter<TWriter> subWriter(writer); - covering::IndexScales(header, featuresVector, subWriter, tmpFilePrefix); + covering::IndexScales(header, featuresV, subWriter, tmpFilePrefix); indexSize = subWriter.Size(); } LOG(LINFO, ("Built scale index. Size =", indexSize)); diff --git a/indexer/indexer.pro b/indexer/indexer.pro index 48399e8d7e..5bbb1c88f4 100644 --- a/indexer/indexer.pro +++ b/indexer/indexer.pro @@ -46,6 +46,7 @@ SOURCES += \ search_index_builder.cpp \ search_string_utils.cpp \ types_mapping.cpp \ + features_vector.cpp \ HEADERS += \ categories_holder.hpp \ diff --git a/indexer/indexer_tests/features_offsets_table_test.cpp b/indexer/indexer_tests/features_offsets_table_test.cpp index 677cf88dd2..996a2d48c2 100644 --- a/indexer/indexer_tests/features_offsets_table_test.cpp +++ b/indexer/indexer_tests/features_offsets_table_test.cpp @@ -8,12 +8,16 @@ #include "platform/platform.hpp" #include "coding/file_container.hpp" + #include "base/scope_guard.hpp" + +#include "defines.hpp" + #include "std/bind.hpp" #include "std/string.hpp" -#include "defines.hpp" -using platform::CountryIndexes; + +using namespace platform; namespace feature { @@ -63,23 +67,18 @@ namespace feature UNIT_TEST(FeaturesOffsetsTable_CreateIfNotExistsAndLoad) { string const testFileName = "minsk-pass"; - Platform & p = GetPlatform(); - platform::CountryFile country(testFileName); - platform::LocalCountryFile localFile(GetPlatform().WritableDir(), country, 0 /* version */); - localFile.SyncWithDisk(); - FilesContainerR baseContainer(p.GetReader(testFileName + DATA_FILE_EXTENSION)); - CountryIndexes::PreparePlaceOnDisk(localFile); - const string indexFile = CountryIndexes::GetPath(localFile, CountryIndexes::Index::Offsets); + + LocalCountryFile localFile = LocalCountryFile::MakeForTesting(testFileName); + string const indexFile = CountryIndexes::GetPath(localFile, CountryIndexes::Index::Offsets); FileWriter::DeleteFileX(indexFile); - unique_ptr<FeaturesOffsetsTable> table(FeaturesOffsetsTable::CreateIfNotExistsAndLoad(indexFile, localFile)); + + unique_ptr<FeaturesOffsetsTable> table = FeaturesOffsetsTable::CreateIfNotExistsAndLoad(localFile); MY_SCOPE_GUARD(deleteTestFileIndexGuard, bind(&FileWriter::DeleteFileX, cref(indexFile))); TEST(table.get(), ()); - feature::DataHeader header; - header.Load(baseContainer.GetReader(HEADER_FILE_TAG)); - uint64_t builderSize = 0; - FeaturesVector(baseContainer, header).ForEach([&builderSize](FeatureType const & /*ft*/, uint32_t /*ind*/) + FilesContainerR cont(GetPlatform().GetReader(testFileName + DATA_FILE_EXTENSION)); + FeaturesVectorTest(cont).GetVector().ForEach([&builderSize](FeatureType const &, uint32_t) { ++builderSize; }); @@ -93,12 +92,13 @@ namespace feature UNIT_TEST(FeaturesOffsetsTable_ReadWrite) { string const testFileName = "test_file"; - Platform & p = GetPlatform(); - platform::CountryFile country("minsk-pass"); - platform::LocalCountryFile localFile(p.WritableDir(), country, 0 /* version */); - localFile.SyncWithDisk(); - FilesContainerR baseContainer(p.GetReader("minsk-pass" DATA_FILE_EXTENSION)); - const string indexFile = CountryIndexes::GetPath(localFile, CountryIndexes::Index::Offsets); + Platform & pl = GetPlatform(); + + FilesContainerR baseContainer(pl.GetReader("minsk-pass" DATA_FILE_EXTENSION)); + + LocalCountryFile localFile = LocalCountryFile::MakeForTesting(testFileName); + string const indexFile = CountryIndexes::GetPath(localFile, CountryIndexes::Index::Offsets); + FileWriter::DeleteFileX(indexFile); FeaturesOffsetsTable::Builder builder; FeaturesVector::ForEachOffset(baseContainer.GetReader(DATA_FILE_TAG), [&builder](uint64_t offset) @@ -110,7 +110,7 @@ namespace feature TEST(table.get(), ()); TEST_EQUAL(builder.size(), table->size(), ()); - string const testFile = p.WritablePathForFile(testFileName + DATA_FILE_EXTENSION); + string const testFile = pl.WritablePathForFile(testFileName + DATA_FILE_EXTENSION); MY_SCOPE_GUARD(deleteTestFileGuard, bind(&FileWriter::DeleteFileX, cref(testFile))); MY_SCOPE_GUARD(deleteTestFileIndexGuard, bind(&FileWriter::DeleteFileX, cref(indexFile))); @@ -130,7 +130,6 @@ namespace feature // Load table from the temporary data file. { - MY_SCOPE_GUARD(testTableGuard, bind(&FileWriter::DeleteFileX, cref(indexFile))); unique_ptr<FeaturesOffsetsTable> loadedTable(FeaturesOffsetsTable::Load(indexFile)); TEST(loadedTable.get(), ()); diff --git a/indexer/indexer_tests/index_builder_test.cpp b/indexer/indexer_tests/index_builder_test.cpp index 1ebfe9c068..6fe4bd68a5 100644 --- a/indexer/indexer_tests/index_builder_test.cpp +++ b/indexer/indexer_tests/index_builder_test.cpp @@ -26,13 +26,10 @@ UNIT_TEST(BuildIndexTest) // Build index. vector<char> serialIndex; { - feature::DataHeader header; - header.Load(originalContainer.GetReader(HEADER_FILE_TAG)); - - FeaturesVector featuresVector(originalContainer, header); + FeaturesVectorTest featuresV(originalContainer); MemWriter<vector<char> > serialWriter(serialIndex); - indexer::BuildIndex(header, featuresVector, serialWriter, "build_index_test"); + indexer::BuildIndex(featuresV.GetHeader(), featuresV.GetVector(), serialWriter, "build_index_test"); } // Create a new mwm file. diff --git a/indexer/indexer_tests/test_mwm_set.hpp b/indexer/indexer_tests/test_mwm_set.hpp index 337b03e0ab..8206465f7c 100644 --- a/indexer/indexer_tests/test_mwm_set.hpp +++ b/indexer/indexer_tests/test_mwm_set.hpp @@ -10,29 +10,26 @@ using platform::LocalCountryFile; namespace tests { -class MwmValue : public MwmSet::MwmValueBase -{ -}; class TestMwmSet : public MwmSet { protected: - // MwmSet overrides: - bool GetVersion(LocalCountryFile const & localFile, MwmInfo & info) const override + /// @name MwmSet overrides + //@{ + MwmInfo * CreateInfo(platform::LocalCountryFile const & localFile) const override { int const n = localFile.GetCountryName()[0] - '0'; - info.m_maxScale = n; - info.m_limitRect = m2::RectD(0, 0, 1, 1); - info.m_version.format = version::lastFormat; - return true; + MwmInfo * info = new MwmInfo(); + info->m_maxScale = n; + info->m_limitRect = m2::RectD(0, 0, 1, 1); + info->m_version.format = version::lastFormat; + return info; } - - TMwmValueBasePtr CreateValue(LocalCountryFile const &) const override + MwmValueBase * CreateValue(MwmInfo &) const override { - return TMwmValueBasePtr(new MwmValue()); + return new MwmValueBase(); } - -public: - ~TestMwmSet() override = default; + //@} }; + } // namespace diff --git a/indexer/mwm_set.cpp b/indexer/mwm_set.cpp index 292f7b64b4..389354f314 100644 --- a/indexer/mwm_set.cpp +++ b/indexer/mwm_set.cpp @@ -75,16 +75,6 @@ MwmSet::MwmHandle & MwmSet::MwmHandle::operator=(MwmHandle && handle) return *this; } -MwmSet::MwmSet(size_t cacheSize) - : m_cacheSize(cacheSize) -{ -} - -MwmSet::~MwmSet() -{ - Clear(); - ASSERT(m_cache.empty(), ()); -} MwmSet::MwmId MwmSet::GetMwmIdByCountryFileImpl(CountryFile const & countryFile) const { @@ -131,10 +121,9 @@ pair<MwmSet::MwmHandle, MwmSet::RegResult> MwmSet::Register(LocalCountryFile con pair<MwmSet::MwmHandle, MwmSet::RegResult> MwmSet::RegisterImpl(LocalCountryFile const & localFile) { - shared_ptr<MwmInfo> info(new MwmInfo()); - // This function can throw an exception for a bad mwm file. - if (!GetVersion(localFile, *info)) + shared_ptr<MwmInfo> info(CreateInfo(localFile)); + if (!info) return make_pair(MwmHandle(), RegResult::UnsupportedFileFormat); info->m_file = localFile; @@ -227,7 +216,8 @@ MwmSet::TMwmValueBasePtr MwmSet::LockValueImpl(MwmId const & id) return result; } } - return CreateValue(info->GetLocalFile()); + + return TMwmValueBasePtr(CreateValue(*info)); } void MwmSet::UnlockValue(MwmId const & id, TMwmValueBasePtr p) diff --git a/indexer/mwm_set.hpp b/indexer/mwm_set.hpp index 3195955529..a5663da83b 100644 --- a/indexer/mwm_set.hpp +++ b/indexer/mwm_set.hpp @@ -40,6 +40,7 @@ public: }; MwmInfo(); + virtual ~MwmInfo() = default; m2::RectD m_limitRect; ///< Limit rect of mwm. uint8_t m_minScale; ///< Min zoom level of mwm. @@ -104,13 +105,13 @@ public: }; public: - explicit MwmSet(size_t cacheSize = 5); - virtual ~MwmSet() = 0; + explicit MwmSet(size_t cacheSize = 5) : m_cacheSize(cacheSize) {} + virtual ~MwmSet() = default; class MwmValueBase { public: - virtual ~MwmValueBase() {} + virtual ~MwmValueBase() = default; }; using TMwmValueBasePtr = shared_ptr<MwmValueBase>; @@ -210,8 +211,8 @@ public: protected: /// @return True when file format version was successfully read to MwmInfo. - virtual bool GetVersion(platform::LocalCountryFile const & localFile, MwmInfo & info) const = 0; - virtual TMwmValueBasePtr CreateValue(platform::LocalCountryFile const & localFile) const = 0; + virtual MwmInfo * CreateInfo(platform::LocalCountryFile const & localFile) const = 0; + virtual MwmValueBase * CreateValue(MwmInfo & info) const = 0; private: typedef deque<pair<MwmId, TMwmValueBasePtr>> CacheType; diff --git a/indexer/scale_index_builder.hpp b/indexer/scale_index_builder.hpp index a2b7103bd5..b644ea6d6c 100644 --- a/indexer/scale_index_builder.hpp +++ b/indexer/scale_index_builder.hpp @@ -193,7 +193,7 @@ private: }; template <class TFeaturesVector, class TWriter> -void IndexScales(feature::DataHeader const & header, TFeaturesVector const & featuresVector, +void IndexScales(feature::DataHeader const & header, TFeaturesVector const & featuresV, TWriter & writer, string const & tmpFilePrefix) { // TODO: Make scale bucketing dynamic. @@ -212,8 +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.ForEach( - FeatureCoverer<TSorter>(header, sorter, featuresInBucket, cellsInBucket)); + featuresV.ForEach(FeatureCoverer<TSorter>(header, sorter, featuresInBucket, cellsInBucket)); sorter.SortAndFinish(); for (uint32_t bucket = 0; bucket < bucketsCount; ++bucket) diff --git a/indexer/search_index_builder.cpp b/indexer/search_index_builder.cpp index 50afaf92e8..b4d2b5a110 100644 --- a/indexer/search_index_builder.cpp +++ b/indexer/search_index_builder.cpp @@ -365,9 +365,8 @@ void AddFeatureNameIndexPairs(FilesContainerR const & container, CategoriesHolder & categoriesHolder, StringsFile<FeatureIndexValue> & stringsFile) { - feature::DataHeader header; - header.Load(container.GetReader(HEADER_FILE_TAG)); - FeaturesVector features(container, header); + FeaturesVectorTest featuresV(container); + feature::DataHeader const & header = featuresV.GetHeader(); ValueBuilder<FeatureIndexValue> valueBuilder; @@ -375,19 +374,16 @@ void AddFeatureNameIndexPairs(FilesContainerR const & container, if (header.GetType() == feature::DataHeader::world) synonyms.reset(new SynonymsHolder(GetPlatform().WritablePathForFile(SYNONYMS_FILE))); - FeatureInserter<StringsFile<FeatureIndexValue>> inserter( - synonyms.get(), stringsFile, categoriesHolder, header.GetScaleRange(), valueBuilder); - - features.ForEach(inserter); + featuresV.GetVector().ForEach(FeatureInserter<StringsFile<FeatureIndexValue>>( + synonyms.get(), stringsFile, categoriesHolder, header.GetScaleRange(), valueBuilder)); } void BuildSearchIndex(FilesContainerR const & cont, CategoriesHolder const & catHolder, Writer & writer, string const & tmpFilePath) { { - feature::DataHeader header; - header.Load(cont.GetReader(HEADER_FILE_TAG)); - FeaturesVector featuresV(cont, header); + FeaturesVectorTest featuresV(cont); + feature::DataHeader const & header = featuresV.GetHeader(); serial::CodingParams cp(search::GetCPForTrie(header.GetDefCodingParams())); ValueBuilder<SerializedFeatureInfoValue> valueBuilder(cp); @@ -398,7 +394,7 @@ void BuildSearchIndex(FilesContainerR const & cont, CategoriesHolder const & cat StringsFile<SerializedFeatureInfoValue> names(tmpFilePath); - featuresV.ForEach(FeatureInserter<StringsFile<SerializedFeatureInfoValue>>( + featuresV.GetVector().ForEach(FeatureInserter<StringsFile<SerializedFeatureInfoValue>>( synonyms.get(), names, catHolder, header.GetScaleRange(), valueBuilder)); names.EndAdding(); |