[core] Refactoring of FilesMappingContainer Handle: using move semantics to control ownership.

This commit is contained in:
Denis Koronchik 2014-09-19 12:54:38 +03:00 committed by Alex Zolotarev
parent 4cc394fb71
commit 8150a4c98d
6 changed files with 101 additions and 54 deletions

View file

@ -205,6 +205,34 @@ UNIT_TEST(FilesContainer_RewriteExisting)
FileWriter::DeleteFileX(fName);
}
UNIT_TEST(FilesMappingContainer_Handle)
{
string const fName = "file_container.tmp";
string const tag = "dummy";
{
FilesContainerW writer(fName);
FileWriter w = writer.GetWriter(tag);
w.Write(tag.c_str(), tag.size());
}
{
FilesMappingContainer cont(fName);
FilesMappingContainer::Handle h1 = cont.Map(tag);
TEST(h1.IsValid(), ());
FilesMappingContainer::Handle h2;
TEST(!h2.IsValid(), ());
h2.Assign(std::move(h1));
TEST(!h1.IsValid(), ());
TEST(h2.IsValid(), ());
}
FileWriter::DeleteFileX(fName);
}
UNIT_TEST(FilesMappingContainer_Smoke)
{
string const fName = "file_container.tmp";
@ -228,10 +256,12 @@ UNIT_TEST(FilesMappingContainer_Smoke)
{
FilesMappingContainer reader(fName);
for (size_t i = 0; i < ARRAY_SIZE(key); ++i)
{
FilesMappingContainer::Handle h = reader.Map(key[i]);
uint32_t const * data = reinterpret_cast<uint32_t const *>(h.GetData());
uint32_t const * data = h.GetData<uint32_t>();
for (uint32_t j = 0; j < count; ++j)
{
TEST_EQUAL(j + i, *data, ());
@ -274,19 +304,16 @@ UNIT_TEST(FilesMappingContainer_PageSize)
for (size_t i = 0; i < sz; ++i)
{
handle[i] = reader.Map(key[i]);
handle[i].Assign(reader.Map(key[i]));
TEST_EQUAL(handle[i].GetSize(), count[i], ());
}
for (size_t i = 0; i < sz; ++i)
{
char const * data = handle[i].GetData();
char const * data = handle[i].GetData<char>();
for (size_t j = 0; j < count[i]; ++j)
TEST_EQUAL(*data++, byte[j % ARRAY_SIZE(byte)], ());
}
for (size_t i = 0; i < sz; ++i)
handle[i].Unmap();
}
FileWriter::DeleteFileX(fName);

View file

@ -126,11 +126,11 @@ FilesMappingContainer::Handle FilesMappingContainer::Map(Tag const & tag) const
uint64_t const length = p->m_size + (p->m_offset - offset);
ASSERT_GREATER_OR_EQUAL(length, p->m_size, ());
char const * data = reinterpret_cast<char const *>(mmap(0, length, PROT_READ, MAP_SHARED, m_fd, offset));
if (data == reinterpret_cast<char const *>(-1))
void * pMap = mmap(0, length, PROT_READ, MAP_SHARED, m_fd, offset);
if (pMap == MAP_FAILED)
MYTHROW(Reader::OpenException, ("Can't map section:", tag, "with [offset, size]:", *p));
char const * data = reinterpret_cast<char const *>(pMap);
char const * d = data + (p->m_offset - offset);
return Handle(d, data, p->m_size, length);
}
@ -140,18 +140,40 @@ FilesMappingContainer::Handle FilesMappingContainer::Map(Tag const & tag) const
return Handle();
}
/////////////////////////////////////////////////////////////////////////////
// FilesMappingContainer::Handle
/////////////////////////////////////////////////////////////////////////////
FilesMappingContainer::Handle::~Handle()
{
// CHECK(!IsValid(), ());
Unmap();
}
void FilesMappingContainer::Handle::Assign(Handle && h)
{
Unmap();
m_base = h.m_base;
m_origBase = h.m_origBase;
m_size = h.m_size;
m_origSize = h.m_origSize;
h.Reset();
}
void FilesMappingContainer::Handle::Unmap()
{
ASSERT(IsValid(), ());
VERIFY(0 == munmap((void*)m_origBase, m_origSize), ());
if (IsValid())
{
VERIFY(0 == munmap((void*)m_origBase, m_origSize), ());
Reset();
}
}
m_origBase = m_base = 0;
m_origSize = m_size = 0;
void FilesMappingContainer::Handle::Reset()
{
m_base = m_origBase = 0;
m_size = m_origSize = 0;
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -4,6 +4,7 @@
#include "../std/vector.hpp"
#include "../std/string.hpp"
#include "../std/noncopyable.hpp"
class FilesContainerBase
@ -119,26 +120,42 @@ public:
explicit FilesMappingContainer(string const & fName);
~FilesMappingContainer();
class Handle
class Handle : private noncopyable
{
void Reset();
public:
Handle()
: m_base(0), m_origBase(0), m_size(0), m_origSize(0)
{
}
Handle(char const * base, char const * alignBase, uint64_t size, uint64_t origSize)
: m_base(base), m_origBase(alignBase), m_size(size), m_origSize(origSize)
{
}
Handle(Handle && h)
{
Assign(std::move(h));
}
~Handle();
void Assign(Handle && h);
void Unmap();
bool IsValid() const { return (m_base != 0 && m_size > 0); }
bool IsValid() const { return (m_base != 0); }
uint64_t GetSize() const { return m_size; }
char const * GetData() const { return m_base; }
template <class T> T const * GetData() const
{
ASSERT_EQUAL(m_size % sizeof(T), 0, ());
return reinterpret_cast<T const *>(m_base);
}
template <class T> size_t GetDataCount() const
{
ASSERT_EQUAL(m_size % sizeof(T), 0, ());
return (m_size / sizeof(T));
}
private:
char const * m_base;

View file

@ -73,40 +73,31 @@ string DebugPrint(OsrmFtSegMapping::FtSeg const & seg)
}
OsrmFtSegMapping::~OsrmFtSegMapping()
{
if (m_handle.IsValid())
m_handle.Unmap();
}
void OsrmFtSegMapping::Clear()
{
m_offsets.clear();
if (m_handle.IsValid())
m_handle.Unmap();
m_handle.Unmap();
}
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 = reinterpret_cast<SegOffset const *>(h.GetData());
ASSERT_EQUAL(h.GetSize() % sizeof(SegOffset), 0, ());
m_offsets.assign(p, p + h.GetSize() / sizeof(SegOffset));
SegOffset const * p = h.GetData<SegOffset>();
m_offsets.assign(p, p + h.GetDataCount<SegOffset>());
h.Unmap();
m_handle = cont.Map(ROUTING_FTSEG_FILE_TAG);
m_handle.Assign(cont.Map(ROUTING_FTSEG_FILE_TAG));
}
size_t OsrmFtSegMapping::GetSegmentsCount() const
{
ASSERT_EQUAL(m_handle.GetSize() % sizeof(FtSeg), 0, ());
return m_handle.GetSize() / sizeof(FtSeg);
return m_handle.GetDataCount<FtSeg>();
}
pair<OsrmFtSegMapping::FtSeg const *, size_t> OsrmFtSegMapping::GetSegVector(OsrmNodeIdT nodeId) const

View file

@ -61,8 +61,6 @@ public:
};
#pragma pack (pop)
~OsrmFtSegMapping();
void Clear();
void Load(FilesMappingContainer & cont);
@ -80,7 +78,7 @@ public:
pair<size_t, size_t> GetSegmentsRange(uint32_t nodeId) const;
OsrmNodeIdT GetNodeId(size_t segInd) const;
FtSeg const * GetSegments() const { return reinterpret_cast<FtSeg const *>(m_handle.GetData()); }
FtSeg const * GetSegments() const { return m_handle.GetData<FtSeg>(); }
size_t GetSegmentsCount() const;
//@}

View file

@ -40,33 +40,25 @@ public:
OsrmDataFacade(FilesMappingContainer const & container)
: m_container(container)
{
m_handleEdgeData = m_container.Map(ROUTING_EDGEDATA_FILE_TAG);
m_handleEdgeData.Assign(m_container.Map(ROUTING_EDGEDATA_FILE_TAG));
ASSERT(m_handleEdgeData.IsValid(), ());
succinct::mapper::map(m_edgeData, m_handleEdgeData.GetData());
succinct::mapper::map(m_edgeData, m_handleEdgeData.GetData<char>());
m_handleEdgeId = m_container.Map(ROUTING_EDGEID_FILE_TAG);
m_handleEdgeId.Assign(m_container.Map(ROUTING_EDGEID_FILE_TAG));
ASSERT(m_handleEdgeId.IsValid(), ());
succinct::mapper::map(m_edgeId, m_handleEdgeId.GetData());
succinct::mapper::map(m_edgeId, m_handleEdgeId.GetData<char>());
m_handleShortcuts = m_container.Map(ROUTING_SHORTCUTS_FILE_TAG);
m_handleShortcuts.Assign(m_container.Map(ROUTING_SHORTCUTS_FILE_TAG));
ASSERT(m_handleShortcuts.IsValid(), ());
succinct::mapper::map(m_shortcuts, m_handleShortcuts.GetData());
succinct::mapper::map(m_shortcuts, m_handleShortcuts.GetData<char>());
m_handleFanoMatrix = m_container.Map(ROUTING_MATRIX_FILE_TAG);
m_handleFanoMatrix.Assign(m_container.Map(ROUTING_MATRIX_FILE_TAG));
ASSERT(m_handleFanoMatrix.IsValid(), ());
succinct::mapper::map(m_fanoMatrix, m_handleFanoMatrix.GetData());
succinct::mapper::map(m_fanoMatrix, m_handleFanoMatrix.GetData<char>());
m_numberOfNodes = (unsigned)sqrt(m_fanoMatrix.size() / 2) + 1;
}
~OsrmDataFacade()
{
m_handleEdgeData.Unmap();
m_handleEdgeId.Unmap();
m_handleFanoMatrix.Unmap();
m_handleShortcuts.Unmap();
}
unsigned GetNumberOfNodes() const
{