Add MwmValue for storing in MwmSet cache => read feature::DataHeader once.

This commit is contained in:
vng 2011-09-22 21:37:45 +03:00 committed by Alex Zolotarev
parent b0382314df
commit fa6b163e8f
6 changed files with 128 additions and 76 deletions

View file

@ -15,7 +15,7 @@ namespace feature
/// This info is created once.
class SharedLoadInfo
{
FilesContainerR m_cont;
FilesContainerR const & m_cont;
DataHeader const & m_header;
typedef FilesContainerR::ReaderT ReaderT;

View file

@ -3,27 +3,40 @@
#include "../platform/platform.hpp"
#include "../std/bind.hpp"
namespace
{
FilesContainerR * CreateFileContainer(string const & fileName)
{
return new FilesContainerR(GetPlatform().GetReader(fileName));
}
} // unnamed namespace
Index::Index() : MwmSet(bind(&Index::FillInMwmInfo, this, _1, _2), &CreateFileContainer)
MwmValue::MwmValue(string const & name)
: m_cont(GetPlatform().GetReader(name))
{
m_factory.Load(m_cont);
}
void Index::FillInMwmInfo(string const & fileName, MwmInfo & info)
void Index::GetInfo(string const & name, MwmInfo & info) const
{
IndexFactory factory;
factory.Load(FilesContainerR(GetPlatform().GetReader(fileName)));
MwmValue value(name);
feature::DataHeader const & h = factory.GetHeader();
feature::DataHeader const & h = value.GetHeader();
info.m_limitRect = h.GetBounds();
pair<int, int> const scaleR = h.GetScaleRange();
info.m_minScale = static_cast<uint8_t>(scaleR.first);
info.m_maxScale = static_cast<uint8_t>(scaleR.second);
}
MwmValue * Index::CreateValue(string const & name) const
{
return new MwmValue(name);
}
void Index::DestroyValue(MwmValue * p) const
{
delete p;
}
Index::Index()
{
}
Index::~Index()
{
Cleanup();
}

View file

@ -4,18 +4,36 @@
#include "feature_covering.hpp"
#include "features_vector.hpp"
#include "scale_index.hpp"
#include "mwm_set.hpp"
#include "../coding/file_container.hpp"
#include "../../defines.hpp"
#include "data_factory.hpp"
#include "mwm_set.hpp"
#include "../std/unordered_set.hpp"
#include "../std/vector.hpp"
class Index : public MwmSet
class MwmValue
{
public:
FilesContainerR m_cont;
IndexFactory m_factory;
MwmValue(string const & name);
feature::DataHeader const & GetHeader() const { return m_factory.GetHeader(); }
};
class Index : public MwmSet
{
protected:
virtual void GetInfo(string const & name, MwmInfo & info) const;
virtual MwmValue * CreateValue(string const & name) const;
virtual void DestroyValue(MwmValue *) const;
public:
Index();
~Index();
template <typename F>
void ForEachInRect(F & f, m2::RectD const & rect, uint32_t scale) const
@ -77,13 +95,12 @@ private:
rect.IsIntersect(mwm[id].m_limitRect))
{
MwmLock lock(*this, id);
FilesContainerR * pContainer = lock.GetFileContainer();
if (pContainer)
MwmValue * pValue = lock.GetValue();
if (pValue)
{
IndexFactory factory;
factory.Load(*pContainer);
FeaturesVector fv(*pContainer, factory.GetHeader());
ScaleIndex<ModelReaderPtr> index(pContainer->GetReader(INDEX_FILE_TAG), factory);
FeaturesVector fv(pValue->m_cont, pValue->GetHeader());
ScaleIndex<ModelReaderPtr> index(pValue->m_cont.GetReader(INDEX_FILE_TAG), pValue->m_factory);
unordered_set<uint32_t> offsets;
ReadFeatureFunctor<F> f1(fv, f, offsets);
for (size_t i = 0; i < intervals.size(); ++i)
@ -94,7 +111,4 @@ private:
}
}
}
void FillInMwmInfo(string const & path, MwmInfo & info);
};

View file

@ -1,25 +1,43 @@
#include "../../testing/testing.hpp"
#include "../mwm_set.hpp"
#include "../../coding/file_container.hpp"
#include "../../platform/platform.hpp"
class MwmValue
{
FilesContainerR m_cont;
public:
MwmValue(string const & name) : m_cont(name) {}
};
namespace
{
void SetMwmInfoForTest(string const & path, MwmInfo & info)
{
int n = path[0] - '0';
info.m_maxScale = n;
}
FilesContainerR * CreateFileContainerForTest(string const &)
{
return new FilesContainerR(GetPlatform().WritablePathForFile("minsk-pass.mwm"));
}
class TestMwmSet : public MwmSet
{
protected:
virtual void GetInfo(string const & path, MwmInfo & info) const
{
int n = path[0] - '0';
info.m_maxScale = n;
}
virtual MwmValue * CreateValue(string const &) const
{
return new MwmValue(GetPlatform().WritablePathForFile("minsk-pass.mwm"));
}
virtual void DestroyValue(MwmValue * p) const
{
delete p;
}
};
} // unnamed namespace
UNIT_TEST(MwmSetSmokeTest)
{
MwmSet mwmSet(&SetMwmInfoForTest, &CreateFileContainerForTest);
TestMwmSet mwmSet;
vector<MwmInfo> info;
mwmSet.Add("0");
@ -36,8 +54,8 @@ UNIT_TEST(MwmSetSmokeTest)
{
MwmSet::MwmLock lock0(mwmSet, 0);
MwmSet::MwmLock lock1(mwmSet, 1);
TEST(lock0.GetFileContainer() != NULL, ());
TEST(lock1.GetFileContainer() == NULL, ());
TEST(lock0.GetValue() != NULL, ());
TEST(lock1.GetValue() == NULL, ());
}
mwmSet.Add("3");
@ -52,7 +70,7 @@ UNIT_TEST(MwmSetSmokeTest)
{
MwmSet::MwmLock lock(mwmSet, 1);
TEST(lock.GetFileContainer() != NULL, ());
TEST(lock.GetValue() != NULL, ());
mwmSet.Remove("3");
mwmSet.Add("4");
}

View file

@ -1,15 +1,18 @@
#include "mwm_set.hpp"
#include "../coding/file_container.hpp"
#include "../base/logging.hpp"
#include "../base/macros.hpp"
#include "../std/algorithm.hpp"
namespace
{
struct MwmIdIsEqualTo
{
MwmSet::MwmId m_id;
explicit MwmIdIsEqualTo(MwmSet::MwmId id) : m_id(id) {}
bool operator() (pair<MwmSet::MwmId, FilesContainerR *> const & p) const
bool operator() (pair<MwmSet::MwmId, MwmValue *> const & p) const
{
return p.first == m_id;
}
@ -17,7 +20,7 @@ namespace
} // unnamed namespace
MwmSet::MwmLock::MwmLock(MwmSet const & mwmSet, MwmId mwmId)
: m_mwmSet(mwmSet), m_id(mwmId), m_pFileContainer(mwmSet.LockContainer(mwmId))
: m_mwmSet(mwmSet), m_id(mwmId), m_pValue(mwmSet.LockValue(mwmId))
{
//LOG(LINFO, ("MwmLock::MwmLock()", m_id));
}
@ -25,25 +28,22 @@ MwmSet::MwmLock::MwmLock(MwmSet const & mwmSet, MwmId mwmId)
MwmSet::MwmLock::~MwmLock()
{
//LOG(LINFO, ("MwmLock::~MwmLock()", m_id));
if (m_pFileContainer)
m_mwmSet.UnlockContainer(m_id, m_pFileContainer);
}
FilesContainerR * MwmSet::MwmLock::GetFileContainer() const
{
return m_pFileContainer;
if (m_pValue)
m_mwmSet.UnlockValue(m_id, m_pValue);
}
MwmSet::MwmSet(function<void (string const &, MwmInfo &)> const & fnGetMwmInfo,
function<FilesContainerR * (string const &)> const & fnCreateContainer,
size_t cacheSize)
: m_cacheSize(cacheSize), m_fnGetMwmInfo(fnGetMwmInfo), m_fnCreateContainer(fnCreateContainer)
MwmSet::MwmSet(size_t cacheSize)
: m_cacheSize(cacheSize)
{
//LOG(LINFO, ("MwmSet::MwmSet()"));
}
MwmSet::~MwmSet()
{
}
void MwmSet::Cleanup()
{
threads::MutexGuard mutexGuard(m_lock);
UNUSED_VALUE(mutexGuard);
@ -108,7 +108,7 @@ bool MwmSet::Add(string const & fileName)
MwmId const id = GetFreeId();
m_name[id] = fileName;
memset(&m_info[id], 0, sizeof(MwmInfo));
m_fnGetMwmInfo(fileName, m_info[id]);
GetInfo(fileName, m_info[id]);
m_info[id].m_lockCount = 0;
m_info[id].m_status = MwmInfo::STATUS_ACTIVE;
return true;
@ -146,7 +146,7 @@ void MwmSet::GetMwmInfo(vector<MwmInfo> & info) const
info = m_info;
}
FilesContainerR * MwmSet::LockContainer(MwmId id) const
MwmValue * MwmSet::LockValue(MwmId id) const
{
threads::MutexGuard mutexGuard(m_lock);
UNUSED_VALUE(mutexGuard);
@ -168,24 +168,24 @@ FilesContainerR * MwmSet::LockContainer(MwmId id) const
{
if (it->first == id)
{
FilesContainerR * result = it->second;
MwmValue * result = it->second;
m_cache.erase(it);
return result;
}
}
return m_fnCreateContainer(m_name[id]);
return CreateValue(m_name[id]);
}
void MwmSet::UnlockContainer(MwmId id, FilesContainerR * pContainer) const
void MwmSet::UnlockValue(MwmId id, MwmValue * p) const
{
threads::MutexGuard mutexGuard(m_lock);
UNUSED_VALUE(mutexGuard);
//LOG(LINFO, ("MwmSet::UnlockContainer()", id));
ASSERT(pContainer, (id));
ASSERT(p, (id));
ASSERT_LESS(id, m_info.size(), ());
if (id >= m_info.size() || !pContainer)
if (id >= m_info.size() || p == 0)
return;
ASSERT_GREATER(m_info[id].m_lockCount, 0, ());
@ -195,16 +195,16 @@ void MwmSet::UnlockContainer(MwmId id, FilesContainerR * pContainer) const
if (m_info[id].m_status == MwmInfo::STATUS_ACTIVE)
{
m_cache.push_back(make_pair(id, pContainer));
m_cache.push_back(make_pair(id, p));
if (m_cache.size() > m_cacheSize)
{
ASSERT_EQUAL(m_cache.size(), m_cacheSize + 1, ());
delete m_cache.front().second;
DestroyValue(m_cache.front().second);
m_cache.pop_front();
}
}
else
delete pContainer;
DestroyValue(p);
}
void MwmSet::ClearCache()
@ -218,6 +218,6 @@ void MwmSet::ClearCache()
void MwmSet::ClearCacheImpl(CacheType::iterator beg, CacheType::iterator end)
{
for (CacheType::iterator it = beg; it != end; ++it)
delete it->second;
DestroyValue(it->second);
m_cache.erase(beg, end);
}

View file

@ -1,12 +1,14 @@
#pragma once
#include "../geometry/rect2d.hpp"
#include "../base/mutex.hpp"
#include "../std/deque.hpp"
#include "../std/function.hpp"
#include "../std/string.hpp"
#include "../std/utility.hpp"
#include "../std/vector.hpp"
class FilesContainerR;
// Information about stored mwm.
struct MwmInfo
@ -25,16 +27,22 @@ private:
uint8_t m_status; //
};
class MwmValue;
class MwmSet
{
public:
protected:
virtual void GetInfo(string const & name, MwmInfo & info) const = 0;
virtual MwmValue * CreateValue(string const & name) const = 0;
virtual void DestroyValue(MwmValue * p) const = 0;
void Cleanup();
public:
typedef size_t MwmId;
explicit MwmSet(function<void (string const &, MwmInfo &)> const & fnGetMwmInfo,
function<FilesContainerR * (string const &)> const & fnCreateContainer,
size_t cacheSize = 5);
~MwmSet();
explicit MwmSet(size_t cacheSize = 5);
virtual ~MwmSet() = 0;
// Mwm lock, which is used to lock mwm when its FileContainer is used.
class MwmLock
@ -43,11 +51,12 @@ public:
MwmLock(MwmSet const & mwmSet, MwmId mwmId);
~MwmLock();
FilesContainerR * GetFileContainer() const;
inline MwmValue * GetValue() const { return m_pValue; }
private:
MwmSet const & m_mwmSet;
MwmId m_id;
FilesContainerR * m_pFileContainer;
MwmValue * m_pValue;
};
// Add new mwm. Returns false, if mwm with given fileName already exists.
@ -67,13 +76,13 @@ private:
static const MwmId INVALID_MWM_ID = static_cast<MwmId>(-1);
typedef deque<pair<MwmId, FilesContainerR *> > CacheType;
typedef deque<pair<MwmId, MwmValue *> > CacheType;
// Update given MwmInfo.
inline static void UpdateMwmInfo(MwmInfo & info);
FilesContainerR * LockContainer(MwmId id) const;
void UnlockContainer(MwmId id, FilesContainerR * pContainer) const;
MwmValue * LockValue(MwmId id) const;
void UnlockValue(MwmId id, MwmValue * p) const;
// Find first removed mwm or add a new one.
MwmId GetFreeId();
@ -88,7 +97,5 @@ private:
mutable vector<string> m_name;
mutable CacheType m_cache;
size_t m_cacheSize;
function<void (string const &, MwmInfo &)> const m_fnGetMwmInfo;
function<FilesContainerR * (string const &)> const m_fnCreateContainer;
mutable threads::Mutex m_lock;
};