Review fixes.

This commit is contained in:
Vladimir Byko-Ianko 2016-07-22 10:56:39 +03:00
parent 5d4ee21e4a
commit 9879d1808a
7 changed files with 65 additions and 60 deletions

View file

@ -27,22 +27,22 @@
#include "defines.hpp"
#include "3party/succinct/elias_fano.hpp"
#include "3party/succinct/mapper.hpp"
#include "3party/succinct/rs_bit_vector.hpp"
#include "std/algorithm.hpp"
#include "std/type_traits.hpp"
#include "std/utility.hpp"
#include "std/vector.hpp"
#include "3party/succinct/elias_fano.hpp"
#include "3party/succinct/mapper.hpp"
#include "3party/succinct/rs_bit_vector.hpp"
using namespace feature;
namespace
{
using namespace routing;
TAltitudeSectionVersion constexpr kAltitudeSectionVersion = 1;
AltitudeHeader::TAltitudeSectionVersion constexpr kAltitudeSectionVersion = 1;
class SrtmGetter : public IAltitudeGetter
{
@ -151,7 +151,7 @@ uint32_t GetFileSize(string const & filePath)
uint64_t size;
if (!my::GetFileSize(filePath, size))
{
LOG(LERROR, (filePath, "size = 0"));
LOG(LERROR, (filePath, "Unable to get file size"));
return 0;
}
@ -182,8 +182,6 @@ void BuildRoadAltitudes(string const & baseDir, string const & countryName, IAlt
Processor processor(altitudeGetter);
feature::ForEachFromDat(mwmPath, processor);
processor.SortFeatureAltitudes();
Processor::TFeatureAltitudes const & featureAltitudes = processor.GetFeatureAltitudes();
if (!processor.HasAltitudeInfo())
{
@ -191,6 +189,9 @@ void BuildRoadAltitudes(string const & baseDir, string const & countryName, IAlt
return;
}
processor.SortFeatureAltitudes();
Processor::TFeatureAltitudes const & featureAltitudes = processor.GetFeatureAltitudes();
// Writing compressed bit vector with features which have altitude information.
succinct::rs_bit_vector altitudeAvailability(processor.GetAltitudeAvailability());
string const altitudeAvailabilityPath = my::JoinFoldersToPath(baseDir, "altitude_availability.bitvector");
@ -216,7 +217,7 @@ void BuildRoadAltitudes(string const & baseDir, string const & countryName, IAlt
// Writing feature altitude offsets.
CHECK(is_sorted(offsets.begin(), offsets.end()), ());
CHECK(adjacent_find(offsets.begin(), offsets.end()) == offsets.end(), ());
LOG(LINFO, ("Max altitude info offset =", offsets.back(), "offsets.size() =", offsets.size()));
LOG(LINFO, ("Max altitude info offset =", offsets.back(), "number of offsets = =", offsets.size()));
succinct::elias_fano::elias_fano_builder builder(offsets.back(), offsets.size());
for (uint32_t offset : offsets)
builder.push_back(offset);
@ -243,14 +244,14 @@ void BuildRoadAltitudes(string const & baseDir, string const & countryName, IAlt
altitudeInfoOffset + sizeof(TAltitudeSectionOffset) /* for altitude info size */);
header.Serialize(w);
// Coping parts of altitude sections to mwm.
// Copying parts of altitude sections to mwm.
MoveFileToAltitudeSection(altitudeAvailabilityPath, altitudeAvailabilitySize, w);
MoveFileToAltitudeSection(featuresTablePath, featuresTableSize, w);
MoveFileToAltitudeSection(altitudeInfoPath, altitudeInfoSize, w);
}
catch (RootException const & e)
{
LOG(LERROR, ("An exception happend while creating", ALTITUDES_FILE_TAG, "section. ", e.what()));
LOG(LERROR, ("An exception happened while creating", ALTITUDES_FILE_TAG, "section. ", e.what()));
}
}

View file

@ -134,7 +134,7 @@ void BuildMwmWithoutAltitude(vector<TRounded3DGeom> const & roadFeatures, LocalC
builder.Add(TestStreet(ConvertTo2DGeom<m2::PointD>(geom3D), string(), string()));
}
void ReadAndTestAltitudeInfo(MwmValue const * mwmValue, string const & mwmPath, MockAltitudeGetter & altitudeGetter)
void ReadAndTestAltitudeInfo(MwmValue const & mwmValue, string const & mwmPath, MockAltitudeGetter & altitudeGetter)
{
AltitudeLoader const loader(mwmValue);
@ -142,7 +142,7 @@ void ReadAndTestAltitudeInfo(MwmValue const * mwmValue, string const & mwmPath,
{
f.ParseGeometry(FeatureType::BEST_GEOMETRY);
size_t const pointsCount = f.GetPointsCount();
TAltitudes const altitudes = loader.GetAltitude(id, pointsCount);
TAltitudes const altitudes = loader.GetAltitudes(id, pointsCount);
if (!routing::IsRoad(feature::TypesHolder(f)))
{
@ -191,7 +191,7 @@ void TestAltitudeSection(vector<TRounded3DGeom> const & roadFeatures)
CHECK(mwmHandle.IsAlive(), ());
string const mwmPath = my::JoinFoldersToPath(testDirFullPath, kTestMwm + DATA_FILE_EXTENSION);
ReadAndTestAltitudeInfo(mwmHandle.GetValue<MwmValue>(), mwmPath, altitudeGetter);
ReadAndTestAltitudeInfo(*mwmHandle.GetValue<MwmValue>(), mwmPath, altitudeGetter);
}
} // namespace

View file

@ -12,46 +12,44 @@
namespace
{
void ReadBuffer(ReaderSource<FilesContainerR::TReader> & rs, vector<char> & buf)
void ReadBuffer(ReaderSource<FilesContainerR::TReader> & src, vector<char> & buf)
{
uint32_t bufSz = 0;
rs.Read(&bufSz, sizeof(bufSz));
if (bufSz > rs.Size() + rs.Pos())
src.Read(&bufSz, sizeof(bufSz));
if (bufSz > src.Size() + src.Pos())
{
ASSERT(false, ());
return;
}
buf.clear();
buf.resize(bufSz);
rs.Read(buf.data(), bufSz);
src.Read(buf.data(), bufSz);
}
} // namespace
namespace feature
{
AltitudeLoader::AltitudeLoader(MwmValue const * mwmValue)
AltitudeLoader::AltitudeLoader(MwmValue const & mwmValue)
{
if (!mwmValue || mwmValue->GetHeader().GetFormat() < version::Format::v8 )
if (mwmValue.GetHeader().GetFormat() < version::Format::v8 )
return;
if (!mwmValue->m_cont.IsExist(ALTITUDES_FILE_TAG))
if (!mwmValue.m_cont.IsExist(ALTITUDES_FILE_TAG))
return;
try
{
m_reader = make_unique<FilesContainerR::TReader>(mwmValue->m_cont.GetReader(ALTITUDES_FILE_TAG));
ReaderSource<FilesContainerR::TReader> rs(*m_reader);
m_header.Deserialize(rs);
m_reader = make_unique<FilesContainerR::TReader>(mwmValue.m_cont.GetReader(ALTITUDES_FILE_TAG));
ReaderSource<FilesContainerR::TReader> src(*m_reader);
m_header.Deserialize(src);
// Reading rs_bit_vector with altitude availability information.
ReadBuffer(rs, m_altitudeAvailabilitBuf);
m_altitudeAvailability = make_unique<succinct::rs_bit_vector>();
succinct::mapper::map(*m_altitudeAvailability, m_altitudeAvailabilitBuf.data());
// Reading src_bit_vector with altitude availability information.
ReadBuffer(src, m_altitudeAvailabilitBuf);
succinct::mapper::map(m_altitudeAvailability, m_altitudeAvailabilitBuf.data());
// Reading table with altitude ofsets for features.
ReadBuffer(rs, m_featureTableBuf);
m_featureTable = make_unique<succinct::elias_fano>();
succinct::mapper::map(*m_featureTable, m_featureTableBuf.data());
// Reading table with altitude offsets for features.
ReadBuffer(src, m_featureTableBuf);
succinct::mapper::map(m_featureTable, m_featureTableBuf.data());
}
catch (Reader::OpenException const & e)
{
@ -65,24 +63,28 @@ bool AltitudeLoader::IsAvailable() const
return m_header.minAltitude != kInvalidAltitude && m_header.altitudeInfoOffset != 0;
}
TAltitudes AltitudeLoader::GetAltitude(uint32_t featureId, size_t pointCount) const
TAltitudes const & AltitudeLoader::GetAltitudes(uint32_t featureId, size_t pointCount) const
{
if (m_header.altitudeInfoOffset == 0)
{
// The version of mwm is less then version::Format::v8 or there's no altitude section in mwm.
return TAltitudes();
return m_dummy;
}
if (!(*m_altitudeAvailability)[featureId])
auto const it = m_cache.find(featureId);
if (it != m_cache.end())
return it->second;
if (!m_altitudeAvailability[featureId])
{
LOG(LINFO, ("Feature featureId =", featureId, "does not contain any altitude information."));
return TAltitudes();
return m_cache.insert(make_pair(featureId, TAltitudes())).first->second;
}
uint64_t const r = m_altitudeAvailability->rank(featureId);
CHECK_LESS(r, m_altitudeAvailability->size(), (featureId));
uint64_t const offset = m_featureTable->select(r);
CHECK_LESS_OR_EQUAL(offset, m_featureTable->size(), (featureId));
uint64_t const r = m_altitudeAvailability.rank(featureId);
CHECK_LESS(r, m_altitudeAvailability.size(), (featureId));
uint64_t const offset = m_featureTable.select(r);
CHECK_LESS_OR_EQUAL(offset, m_featureTable.size(), (featureId));
uint64_t const altitudeInfoOffsetInSection = m_header.altitudeInfoOffset + offset;
CHECK_LESS(altitudeInfoOffsetInSection, m_reader->Size(), ());
@ -90,17 +92,16 @@ TAltitudes AltitudeLoader::GetAltitude(uint32_t featureId, size_t pointCount) co
try
{
Altitude a;
ReaderSource<FilesContainerR::TReader> rs(*m_reader);
rs.Skip(altitudeInfoOffsetInSection);
a.Deserialize(m_header.minAltitude, pointCount, rs);
ReaderSource<FilesContainerR::TReader> src(*m_reader);
src.Skip(altitudeInfoOffsetInSection);
a.Deserialize(m_header.minAltitude, pointCount, src);
// @TODO(bykoianko) Considers using move semantic for returned value here.
return a.GetAltitudes();
return m_cache.insert(make_pair(featureId, a.GetAltitudes())).first->second;
}
catch (Reader::OpenException const & e)
{
LOG(LERROR, ("Error while getting mwm data", e.Msg()));
return TAltitudes();
return m_cache.insert(make_pair(featureId, TAltitudes())).first->second;
}
}
} // namespace feature

View file

@ -2,27 +2,29 @@
#include "indexer/feature_altitude.hpp"
#include "indexer/index.hpp"
#include "3party/succinct/rs_bit_vector.hpp"
#include "std/unique_ptr.hpp"
#include "std/vector.hpp"
#include "3party/succinct/rs_bit_vector.hpp"
namespace feature
{
class AltitudeLoader
{
public:
explicit AltitudeLoader(MwmValue const * mwmValue);
explicit AltitudeLoader(MwmValue const & mwmValue);
TAltitudes GetAltitude(uint32_t featureId, size_t pointCount) const;
TAltitudes const & GetAltitudes(uint32_t featureId, size_t pointCount) const;
bool IsAvailable() const;
private:
vector<char> m_altitudeAvailabilitBuf;
vector<char> m_featureTableBuf;
unique_ptr<succinct::rs_bit_vector> m_altitudeAvailability;
unique_ptr<succinct::elias_fano> m_featureTable;
succinct::rs_bit_vector m_altitudeAvailability;
succinct::elias_fano m_featureTable;
unique_ptr<FilesContainerR::TReader> m_reader;
mutable map<uint32_t, TAltitudes> m_cache;
TAltitudes const m_dummy;
AltitudeHeader m_header;
};
} // namespace feature

View file

@ -11,13 +11,14 @@ namespace feature
{
using TAltitude = int16_t;
using TAltitudes = vector<feature::TAltitude>;
using TAltitudeSectionVersion = uint16_t;
using TAltitudeSectionOffset = uint32_t;
TAltitude constexpr kInvalidAltitude = numeric_limits<TAltitude>::min();
struct AltitudeHeader
{
using TAltitudeSectionVersion = uint16_t;
AltitudeHeader()
{
Reset();
@ -109,10 +110,10 @@ public:
private:
/// \note |m_altitudes| is a vector of feature point altitudes. There's two posibilities:
/// * |m_altitudes| is empty. It means no altitude information defines.
/// * size of |m_altitudes| is equal to feature point number. In that case every item of
/// |m_altitudes| defines altitude in meters for every feature point. If altitude is not defined
/// for some feature point corresponding vector items are equel to |kInvalidAltitude|
/// * |m_altitudes| is empty. It means there is no altitude information for this feature.
/// * size of |m_pointAlt| is equal to the number of this feature's points.
/// In this case the i'th element of |m_pointAlt| corresponds to the altitude of the
/// i'th point of the feature and is set to kInvalidAltitude when there is no information about the point.
TAltitudes m_altitudes;
};
} // namespace feature

View file

@ -268,7 +268,7 @@ void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType
ri.m_speedKMPH = speedKMPH;
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
feature::TAltitudes altitudes = value.altitudeLoader->GetAltitude(featureId.m_index, ft.GetPointsCount());
feature::TAltitudes altitudes = value.altitudeLoader->GetAltitudes(featureId.m_index, ft.GetPointsCount());
size_t const pointsCount = ft.GetPointsCount();
if (altitudes.size() != pointsCount)

View file

@ -82,7 +82,7 @@ private:
struct Value
{
Value() = default;
Value(MwmSet::MwmHandle && handle)
explicit Value(MwmSet::MwmHandle && handle)
: mwmHandle(move(handle))
{
if (!mwmHandle.IsAlive())
@ -90,7 +90,7 @@ private:
ASSERT(false, ());
return;
}
altitudeLoader = make_unique<feature::AltitudeLoader>(mwmHandle.GetValue<MwmValue>());
altitudeLoader = make_unique<feature::AltitudeLoader>(*mwmHandle.GetValue<MwmValue>());
}
bool IsAlive() const