[routing] VarUint coding of Node2FtSeg control array.

This commit is contained in:
vng 2014-09-21 01:30:19 +03:00 committed by Alex Zolotarev
parent ac26a6eac8
commit a8bb81606c
8 changed files with 96 additions and 30 deletions

View file

@ -118,19 +118,23 @@ void FilesMappingContainer::Open(string const & fName)
Close();
{
FileReader reader(fName, 10, 1);
FileReader reader(fName);
ReadInfo(reader);
}
m_fd = open(fName.c_str(), O_RDONLY | O_NONBLOCK);
if (m_fd == -1)
MYTHROW(Reader::OpenException, ("Can't open file:", fName));
m_name = fName;
}
void FilesMappingContainer::Close()
{
if (m_fd != -1)
close(m_fd);
m_name.clear();
}
FilesMappingContainer::Handle FilesMappingContainer::Map(Tag const & tag) const
@ -159,6 +163,17 @@ FilesMappingContainer::Handle FilesMappingContainer::Map(Tag const & tag) const
return Handle();
}
FileReader FilesMappingContainer::GetReader(Tag const & tag) const
{
Info const * p = GetInfo(tag);
if (p)
return FileReader(m_name).SubReader(p->m_offset, p->m_size);
else
MYTHROW(Reader::OpenException, ("Can't find section:", tag));
return FileReader("xxx");
}
/////////////////////////////////////////////////////////////////////////////
// FilesMappingContainer::Handle
/////////////////////////////////////////////////////////////////////////////
@ -340,7 +355,7 @@ void FilesContainerW::Write(ModelReaderPtr reader, Tag const & tag)
ReaderSource<ModelReaderPtr> src(reader);
FileWriter writer = GetWriter(tag);
rw::ReadAndWrite(src, writer, 4*1024);
rw::ReadAndWrite(src, writer);
}
void FilesContainerW::Write(vector<char> const & buffer, Tag const & tag)

View file

@ -125,6 +125,7 @@ class FilesMappingContainer : public FilesContainerBase
public:
FilesMappingContainer();
explicit FilesMappingContainer(string const & fName);
~FilesMappingContainer();
void Open(string const & fName);
@ -175,8 +176,12 @@ public:
};
Handle Map(Tag const & tag) const;
FileReader GetReader(Tag const & tag) const;
string const & GetName() const { return m_name; }
private:
string m_name;
int m_fd;
};

View file

@ -40,6 +40,19 @@ void FileWriter::Write(void const * p, size_t size)
m_pFileData->Write(p, size);
}
void FileWriter::WritePadding(size_t factor)
{
ASSERT(factor > 1, ());
uint64_t sz = Size();
sz = ((sz + factor - 1) / factor) * factor - sz;
if (sz > 0)
{
vector<uint8_t> buffer(sz);
Write(buffer.data(), sz);
}
}
string FileWriter::GetName() const
{
return m_pFileData->GetName();

View file

@ -35,6 +35,8 @@ public:
int64_t Pos() const;
void Write(void const * p, size_t size);
void WritePadding(size_t factor);
uint64_t Size() const;
void Flush();

View file

@ -2,6 +2,8 @@
#include "../defines.hpp"
#include "../coding/varint.hpp"
#include "../base/assert.hpp"
#include "../base/logging.hpp"
#include "../base/math.hpp"
@ -81,8 +83,15 @@ string DebugPrint(OsrmFtSegMapping::FtSeg const & seg)
{
stringstream ss;
ss << "{ fID = " << seg.m_fid <<
"; pStart = " << seg.m_pointStart <<
"; pEnd = " << seg.m_pointEnd << " }";
", pStart = " << seg.m_pointStart <<
", pEnd = " << seg.m_pointEnd << " }";
return ss.str();
}
string DebugPrint(OsrmFtSegMapping::SegOffset const & off)
{
stringstream ss;
ss << "{ " << off.m_nodeId << ", " << off.m_offset << " }";
return ss.str();
}
@ -97,14 +106,16 @@ void OsrmFtSegMapping::Load(FilesMappingContainer & cont)
{
Clear();
/// @todo To reduce memory pressure we can use regular Reader to load m_offsets.
/// Also we can try to do mapping here.
FilesMappingContainer::Handle h = cont.Map(ROUTING_NODEIND_TO_FTSEGIND_FILE_TAG);
SegOffset const * p = h.GetData<SegOffset>();
m_offsets.assign(p, p + h.GetDataCount<SegOffset>());
h.Unmap();
{
ReaderSource<FileReader> src = cont.GetReader(ROUTING_NODEIND_TO_FTSEGIND_FILE_TAG);
uint32_t const count = ReadVarUint<uint32_t>(src);
m_offsets.resize(count);
for (uint32_t i = 0; i < count; ++i)
{
m_offsets[i].m_nodeId = ReadVarUint<OsrmNodeIdT>(src);
m_offsets[i].m_offset = ReadVarUint<uint32_t>(src);
}
}
m_handle.Assign(cont.Map(ROUTING_FTSEG_FILE_TAG));
ASSERT(m_handle.IsValid(), ());
@ -214,7 +225,7 @@ OsrmFtSegMappingBuilder::OsrmFtSegMappingBuilder()
{
}
void OsrmFtSegMappingBuilder::Append(OsrmNodeIdT osrmNodeId, FtSegVectorT const & data)
void OsrmFtSegMappingBuilder::Append(OsrmNodeIdT nodeId, FtSegVectorT const & data)
{
size_t const count = data.size();
@ -233,14 +244,24 @@ void OsrmFtSegMappingBuilder::Append(OsrmNodeIdT osrmNodeId, FtSegVectorT const
uint32_t const off = static_cast<uint32_t>(m_lastOffset);
CHECK_EQUAL(m_lastOffset, off, ());
m_offsets.push_back(SegOffset(osrmNodeId, off));
m_offsets.push_back(SegOffset(nodeId, off));
}
}
void OsrmFtSegMappingBuilder::Save(FilesContainerW & cont) const
{
cont.GetWriter(ROUTING_NODEIND_TO_FTSEGIND_FILE_TAG).Write(
m_offsets.data(), sizeof(SegOffset) * m_offsets.size());
{
FileWriter writer = cont.GetWriter(ROUTING_NODEIND_TO_FTSEGIND_FILE_TAG);
uint32_t const count = static_cast<uint32_t>(m_offsets.size());
WriteVarUint(writer, count);
for (uint32_t i = 0; i < count; ++i)
{
WriteVarUint(writer, m_offsets[i].m_nodeId);
WriteVarUint(writer, m_offsets[i].m_offset);
}
// Write padding to make next elias_fano start address multiple of 4.
writer.WritePadding(4);
}
string const fName = cont.GetFileName() + "." ROUTING_FTSEG_FILE_TAG;

View file

@ -58,6 +58,8 @@ public:
: m_nodeId(nodeId), m_offset(offset)
{
}
friend string DebugPrint(SegOffset const & off);
};
#pragma pack (pop)
@ -110,7 +112,7 @@ public:
typedef vector<FtSeg> FtSegVectorT;
void Append(OsrmNodeIdT osrmNodeId, FtSegVectorT const & data);
void Append(OsrmNodeIdT nodeId, FtSegVectorT const & data);
void Save(FilesContainerW & cont) const;
private:

View file

@ -19,7 +19,8 @@
namespace routing
{
#define FACADE_READ_ZOOM_LEVEL 13
namespace
{
class Point2PhantomNode
{
@ -110,8 +111,8 @@ public:
}
};
}
// ----------------
OsrmRouter::OsrmRouter(Index const * index, CountryFileFnT const & fn)
: m_countryFn(fn), m_pIndex(index)
@ -172,27 +173,28 @@ void OsrmRouter::CalculateRoute(m2::PointD const & startingPt, ReadyCallback con
return;
}
if (m_lastMwmName != fName)
string const fPath = GetPlatform().WritablePathForFile(fName + DATA_FILE_EXTENSION + ROUTING_FILE_EXTENSION);
if (NeedReload(fPath))
{
LOG(LDEBUG, ("Load routing index for file:", fName));
LOG(LDEBUG, ("Load routing index for file:", fPath));
try
{
// need to clear while m_fd is valid for handlers
// Clear data while m_container is valid.
m_dataFacade.Clear();
m_mapping.Clear();
m_container.Open(GetPlatform().WritablePathForFile(fName + DATA_FILE_EXTENSION + ROUTING_FILE_EXTENSION));
m_container.Open(fPath);
m_dataFacade.Load(m_container);
m_mapping.Load(m_container);
}
catch(Reader::Exception const & e)
catch (Reader::Exception const & e)
{
LOG(LERROR, ("Error while loading container", fName, e.Msg()));
LOG(LERROR, ("Error while loading routing index:", fPath, e.Msg()));
resGuard.SetErrorMsg("Routing index absent or incorrect.");
return;
}
m_lastMwmName = fName;
}
SearchEngineData engineData;
@ -281,6 +283,7 @@ void OsrmRouter::CalculateRoute(m2::PointD const & startingPt, ReadyCallback con
Index::FeaturesLoaderGuard loader(*m_pIndex, mwmIdStart);
loader.GetFeature(seg.m_fid, ft);
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
auto startIdx = seg.m_pointStart;
auto endIdx = seg.m_pointEnd;
@ -321,4 +324,9 @@ bool OsrmRouter::FindPhantomNode(m2::PointD const & pt, PhantomNode & resultNode
return getter.MakeResult(resultNode, mwmId, seg, segPt);
}
bool OsrmRouter::NeedReload(string const & fPath) const
{
return (m_container.GetName() != fPath);
}
}

View file

@ -8,6 +8,7 @@
#include "../3party/osrm/osrm-backend/DataStructures/QueryEdge.h"
class Index;
struct PhantomNode;
@ -32,6 +33,7 @@ public:
protected:
bool FindPhantomNode(m2::PointD const & pt, PhantomNode & resultNode, uint32_t & mwmId,
OsrmFtSegMapping::FtSeg & seg, m2::PointD & segPt);
bool NeedReload(string const & fPath) const;
private:
Index const * m_pIndex;
@ -39,10 +41,8 @@ private:
typedef OsrmDataFacade<QueryEdge::EdgeData> DataFacadeT;
DataFacadeT m_dataFacade;
OsrmFtSegMapping m_mapping;
string m_lastMwmName;
FilesMappingContainer m_container;
};
}