Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
187
libs/indexer/centers_table.cpp
Normal file
187
libs/indexer/centers_table.cpp
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
#include "indexer/centers_table.hpp"
|
||||
#include "indexer/feature_processor.hpp"
|
||||
|
||||
#include "coding/files_container.hpp"
|
||||
#include "coding/geometry_coding.hpp"
|
||||
#include "coding/point_coding.hpp"
|
||||
#include "coding/reader.hpp"
|
||||
#include "coding/succinct_mapper.hpp"
|
||||
#include "coding/varint.hpp"
|
||||
#include "coding/write_to_sink.hpp"
|
||||
#include "coding/writer.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/checked_cast.hpp"
|
||||
|
||||
namespace search
|
||||
{
|
||||
|
||||
void CentersTable::Header::Read(Reader & reader)
|
||||
{
|
||||
NonOwningReaderSource source(reader);
|
||||
m_version = static_cast<Version>(ReadPrimitiveFromSource<uint8_t>(source));
|
||||
CHECK_EQUAL(static_cast<uint8_t>(m_version), static_cast<uint8_t>(Version::V1), ());
|
||||
m_geometryParamsOffset = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_geometryParamsSize = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_centersOffset = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
m_centersSize = ReadPrimitiveFromSource<uint32_t>(source);
|
||||
}
|
||||
|
||||
bool CentersTable::Get(uint32_t id, m2::PointD & center)
|
||||
{
|
||||
m2::PointU pointu;
|
||||
if (!m_map->Get(id, pointu))
|
||||
return false;
|
||||
|
||||
if (m_version == Version::V0)
|
||||
center = PointUToPointD(pointu, m_codingParams.GetCoordBits());
|
||||
else if (m_version == Version::V1)
|
||||
center = PointUToPointD(pointu, m_codingParams.GetCoordBits(), m_limitRect);
|
||||
else
|
||||
CHECK(false, ("Unknown CentersTable format."));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// CentersTable ------------------------------------------------------------------------------------
|
||||
// static
|
||||
std::unique_ptr<CentersTable> CentersTable::LoadV0(Reader & reader, serial::GeometryCodingParams const & codingParams)
|
||||
{
|
||||
auto table = std::make_unique<CentersTable>();
|
||||
table->m_version = Version::V0;
|
||||
if (!table->Init(reader, codingParams, {} /* limitRect */))
|
||||
return {};
|
||||
return table;
|
||||
}
|
||||
|
||||
std::unique_ptr<CentersTable> CentersTable::LoadV1(Reader & reader)
|
||||
{
|
||||
auto table = std::make_unique<CentersTable>();
|
||||
table->m_version = Version::V1;
|
||||
|
||||
Header header;
|
||||
header.Read(reader);
|
||||
|
||||
NonOwningReaderSource src(reader, header.m_geometryParamsOffset,
|
||||
header.m_geometryParamsOffset + header.m_geometryParamsSize);
|
||||
|
||||
serial::GeometryCodingParams codingParams;
|
||||
codingParams.Load(src);
|
||||
auto minX = ReadPrimitiveFromSource<uint32_t>(src);
|
||||
auto minY = ReadPrimitiveFromSource<uint32_t>(src);
|
||||
auto maxX = ReadPrimitiveFromSource<uint32_t>(src);
|
||||
auto maxY = ReadPrimitiveFromSource<uint32_t>(src);
|
||||
m2::RectD limitRect(PointUToPointD({minX, minY}, kPointCoordBits), PointUToPointD({maxX, maxY}, kPointCoordBits));
|
||||
|
||||
table->m_centersSubreader = reader.CreateSubReader(header.m_centersOffset, header.m_centersSize);
|
||||
if (!table->m_centersSubreader)
|
||||
return {};
|
||||
if (!table->Init(*(table->m_centersSubreader), codingParams, limitRect))
|
||||
return {};
|
||||
return table;
|
||||
}
|
||||
|
||||
bool CentersTable::Init(Reader & reader, serial::GeometryCodingParams const & codingParams, m2::RectD const & limitRect)
|
||||
{
|
||||
m_codingParams = codingParams;
|
||||
m_limitRect = limitRect;
|
||||
// Decodes block encoded by writeBlockCallback from CentersTableBuilder::Freeze.
|
||||
auto const readBlockCallback =
|
||||
[&](NonOwningReaderSource & source, uint32_t blockSize, std::vector<m2::PointU> & values)
|
||||
{
|
||||
values.reserve(blockSize);
|
||||
|
||||
auto prev = m_codingParams.GetBasePoint();
|
||||
while (source.Size() > 0)
|
||||
{
|
||||
auto const pt = coding::DecodePointDeltaFromUint(ReadVarUint<uint64_t>(source), prev);
|
||||
values.push_back(pt);
|
||||
prev = pt;
|
||||
}
|
||||
};
|
||||
|
||||
m_map = Map::Load(reader, readBlockCallback);
|
||||
return m_map != nullptr;
|
||||
}
|
||||
|
||||
// CentersTableBuilder -----------------------------------------------------------------------------
|
||||
void CentersTableBuilder::SetGeometryParams(m2::RectD const & limitRect, double pointAccuracy)
|
||||
{
|
||||
CHECK(limitRect.IsValid(), (limitRect));
|
||||
auto const coordBits = GetCoordBits(limitRect, pointAccuracy);
|
||||
m_codingParams = serial::GeometryCodingParams(coordBits, limitRect.Center());
|
||||
m_limitRect = limitRect;
|
||||
}
|
||||
|
||||
void CentersTableBuilder::Put(uint32_t featureId, m2::PointD const & center)
|
||||
{
|
||||
m_builder.Put(featureId, PointDToPointU(center, m_codingParams.GetCoordBits(), m_limitRect));
|
||||
}
|
||||
|
||||
// Each center is encoded as delta from some prediction.
|
||||
// For the first center in the block map base point is used as a prediction, for all other
|
||||
// centers in the block previous center is used as a prediction.
|
||||
void CentersTableBuilder::WriteBlock(Writer & w, std::vector<m2::PointU>::const_iterator begin,
|
||||
std::vector<m2::PointU>::const_iterator end) const
|
||||
{
|
||||
uint64_t delta = coding::EncodePointDeltaAsUint(*begin, m_codingParams.GetBasePoint());
|
||||
WriteVarUint(w, delta);
|
||||
auto prevIt = begin;
|
||||
for (auto it = begin + 1; it != end; ++it)
|
||||
{
|
||||
delta = coding::EncodePointDeltaAsUint(*it, *prevIt);
|
||||
WriteVarUint(w, delta);
|
||||
prevIt = it;
|
||||
}
|
||||
}
|
||||
|
||||
void CentersTableBuilder::Freeze(Writer & writer) const
|
||||
{
|
||||
uint64_t const startOffset = writer.Pos();
|
||||
CHECK(coding::IsAlign8(startOffset), ());
|
||||
|
||||
CentersTable::Header header;
|
||||
header.Serialize(writer);
|
||||
|
||||
uint64_t bytesWritten = writer.Pos();
|
||||
coding::WritePadding(writer, bytesWritten);
|
||||
|
||||
header.m_geometryParamsOffset = base::asserted_cast<uint32_t>(writer.Pos() - startOffset);
|
||||
m_codingParams.Save(writer);
|
||||
auto leftBottom = PointDToPointU(m_limitRect.LeftBottom(), kPointCoordBits);
|
||||
WriteToSink(writer, leftBottom.x);
|
||||
WriteToSink(writer, leftBottom.y);
|
||||
auto rightTop = PointDToPointU(m_limitRect.RightTop(), kPointCoordBits);
|
||||
WriteToSink(writer, rightTop.x);
|
||||
WriteToSink(writer, rightTop.y);
|
||||
header.m_geometryParamsSize =
|
||||
base::asserted_cast<uint32_t>(writer.Pos() - header.m_geometryParamsOffset - startOffset);
|
||||
|
||||
bytesWritten = writer.Pos();
|
||||
coding::WritePadding(writer, bytesWritten);
|
||||
|
||||
header.m_centersOffset = base::asserted_cast<uint32_t>(writer.Pos() - startOffset);
|
||||
m_builder.Freeze(writer, [&](auto & w, auto begin, auto end) { WriteBlock(w, begin, end); });
|
||||
header.m_centersSize = base::asserted_cast<uint32_t>(writer.Pos() - header.m_centersOffset - startOffset);
|
||||
|
||||
auto const endOffset = writer.Pos();
|
||||
writer.Seek(startOffset);
|
||||
header.Serialize(writer);
|
||||
writer.Seek(endOffset);
|
||||
}
|
||||
|
||||
void CentersTableBuilder::SetGeometryCodingParamsV0ForTests(serial::GeometryCodingParams const & codingParams)
|
||||
{
|
||||
m_codingParams = codingParams;
|
||||
}
|
||||
|
||||
void CentersTableBuilder::PutV0ForTests(uint32_t featureId, m2::PointD const & center)
|
||||
{
|
||||
m_builder.Put(featureId, PointDToPointU(center, m_codingParams.GetCoordBits()));
|
||||
}
|
||||
|
||||
void CentersTableBuilder::FreezeV0ForTests(Writer & writer) const
|
||||
{
|
||||
m_builder.Freeze(writer, [&](auto & w, auto begin, auto end) { WriteBlock(w, begin, end); });
|
||||
}
|
||||
} // namespace search
|
||||
Loading…
Add table
Add a link
Reference in a new issue