Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvng <viktor.govako@gmail.com>2015-03-21 12:55:05 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:57:09 +0300
commit792311a255f844b940fee3ade42fda4195cbaa0f (patch)
tree58314904937f4b7fdf2ac2e4e675d84e98790203
parentb7e5bc5301e1563664028677d36711a4a0872fee (diff)
Feature index refactoring.
-rw-r--r--generator/check_model.cpp2
-rw-r--r--generator/routing_generator.cpp2
-rw-r--r--graphics/overlay_element.hpp6
-rw-r--r--indexer/data_header.cpp3
-rw-r--r--indexer/data_header.hpp4
-rw-r--r--indexer/feature_decl.cpp2
-rw-r--r--indexer/feature_decl.hpp10
-rw-r--r--indexer/feature_loader.cpp4
-rw-r--r--indexer/feature_processor.hpp2
-rw-r--r--indexer/features_offsets_table.cpp24
-rw-r--r--indexer/features_offsets_table.hpp3
-rw-r--r--indexer/features_vector.hpp58
-rw-r--r--indexer/index.cpp10
-rw-r--r--indexer/index.hpp100
-rw-r--r--indexer/indexer.pro1
-rw-r--r--indexer/indexer_tests/features_offsets_table_test.cpp19
-rw-r--r--indexer/mwm_version.hpp3
-rw-r--r--indexer/scale_index.hpp4
-rw-r--r--indexer/scale_index_builder.hpp12
-rw-r--r--indexer/search_index_builder.cpp38
-rw-r--r--indexer/unique_index.hpp42
-rw-r--r--map/framework.cpp6
-rw-r--r--map/mwm_tests/mwm_foreach_test.cpp22
-rw-r--r--render/gpu_drawer.cpp2
-rw-r--r--routing/features_road_graph.cpp6
-rw-r--r--routing/osrm_router.cpp14
-rw-r--r--routing/routing_tests/road_graph_builder.cpp8
-rw-r--r--routing/turns_generator.cpp15
-rw-r--r--search/house_detector.cpp2
-rw-r--r--search/locality_finder.cpp2
-rw-r--r--search/search_query.cpp4
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;