[drape] not store MemoryFeatureIndex and FeaturesFetcher in TileInfo

reading feature geometry
This commit is contained in:
ExMix 2014-01-21 23:21:05 +03:00 committed by Alex Zolotarev
parent c16751396d
commit 4afa6a1aef
9 changed files with 195 additions and 125 deletions

View file

@ -12,15 +12,8 @@
namespace df
{
namespace
{
void CancelTaskFn(shared_ptr<TileInfo> tinfo)
{
tinfo->Cancel();
}
struct LessCoverageCell
{
bool operator()(shared_ptr<TileInfo> const & l, TileKey const & r) const
@ -38,7 +31,6 @@ TileKey TileInfoPtrToTileKey(shared_ptr<TileInfo> const & p)
{
return p->GetTileKey();
}
}
ReadManager::ReadManager(double visualScale, int w, int h,
@ -66,7 +58,7 @@ void ReadManager::UpdateCoverage(const ScreenBase & screen, CoverageUpdateDescri
if (MustDropAllTiles(screen))
{
for_each(m_tileInfos.begin(), m_tileInfos.end(), &CancelTaskFn);
for_each(m_tileInfos.begin(), m_tileInfos.end(), bind(&ReadManager::CancelTileInfo, this, _1));
m_tileInfos.clear();
for_each(tiles.begin(), tiles.end(), bind(&ReadManager::PushTaskBackForTileKey, this, _1));
@ -75,7 +67,6 @@ void ReadManager::UpdateCoverage(const ScreenBase & screen, CoverageUpdateDescri
}
else
{
// Find rects that go out from viewport
buffer_vector<tileinfo_ptr, 8> outdatedTiles;
set_difference(m_tileInfos.begin(), m_tileInfos.end(),
@ -109,7 +100,7 @@ void ReadManager::Resize(const m2::RectI & rect)
void ReadManager::Stop()
{
for_each(m_tileInfos.begin(), m_tileInfos.end(), &CancelTaskFn);
for_each(m_tileInfos.begin(), m_tileInfos.end(), bind(&ReadManager::CancelTileInfo, this, _1));
m_tileInfos.clear();
m_pool->Stop();
@ -161,21 +152,25 @@ bool ReadManager::MustDropAllTiles(ScreenBase const & screen) const
void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey)
{
tileinfo_ptr tileInfo(new TileInfo(tileKey, m_model, m_memIndex));
tileinfo_ptr tileInfo(new TileInfo(tileKey));
m_tileInfos.insert(tileInfo);
m_pool->PushBack(new ReadMWMTask(tileInfo, m_context));
m_pool->PushBack(new ReadMWMTask(tileInfo, m_memIndex, m_model, m_context));
}
void ReadManager::PushTaskFront(ReadManager::tileinfo_ptr const & tileToReread)
void ReadManager::PushTaskFront(tileinfo_ptr const & tileToReread)
{
m_pool->PushFront(new ReadMWMTask(tileToReread, m_context));
m_pool->PushFront(new ReadMWMTask(tileToReread, m_memIndex, m_model, m_context));
}
void ReadManager::ClearTileInfo(ReadManager::tileinfo_ptr & tileToClear)
void ReadManager::CancelTileInfo(tileinfo_ptr tileToCancel)
{
tileToClear->Cancel();
tileToCancel->Cancel(m_memIndex);
}
void ReadManager::ClearTileInfo(tileinfo_ptr & tileToClear)
{
CancelTileInfo(tileToClear);
m_tileInfos.erase(tileToClear);
}
}

View file

@ -19,55 +19,55 @@
namespace df
{
class CoverageUpdateDescriptor;
class CoverageUpdateDescriptor;
class ReadManager
{
typedef shared_ptr<TileInfo> tileinfo_ptr;
public:
ReadManager(double visualScale, int w, int h,
EngineContext & context,
model::FeaturesFetcher & model);
void UpdateCoverage(ScreenBase const & screen, CoverageUpdateDescriptor & updateDescr);
void Resize(m2::RectI const & rect);
void Stop();
static size_t ReadCount();
private:
void OnTaskFinished(threads::IRoutine * task);
void GetTileKeys(set<TileKey> & out, const ScreenBase & screen) const;
bool MustDropAllTiles(ScreenBase const & screen) const;
void PushTaskBackForTileKey(TileKey const & tileKey);
void PushTaskFront(tileinfo_ptr const & tileToReread);
private:
MemoryFeatureIndex m_memIndex;
EngineContext & m_context;
model::FeaturesFetcher & m_model;
ScalesProcessor m_scalesProcessor;
MasterPointer<threads::ThreadPool> m_pool;
ScreenBase m_currentViewport;
struct LessByTileKey
class ReadManager
{
bool operator ()(tileinfo_ptr const & l, tileinfo_ptr const & r) const
public:
ReadManager(double visualScale, int w, int h,
EngineContext & context,
model::FeaturesFetcher & model);
void UpdateCoverage(ScreenBase const & screen, CoverageUpdateDescriptor & updateDescr);
void Resize(m2::RectI const & rect);
void Stop();
static size_t ReadCount();
private:
void OnTaskFinished(threads::IRoutine * task);
void GetTileKeys(set<TileKey> & out, const ScreenBase & screen) const;
bool MustDropAllTiles(ScreenBase const & screen) const;
void PushTaskBackForTileKey(TileKey const & tileKey);
void PushTaskFront(tileinfo_ptr const & tileToReread);
private:
MemoryFeatureIndex m_memIndex;
EngineContext & m_context;
model::FeaturesFetcher & m_model;
ScalesProcessor m_scalesProcessor;
MasterPointer<threads::ThreadPool> m_pool;
ScreenBase m_currentViewport;
struct LessByTileKey
{
return *l < *r;
}
bool operator ()(tileinfo_ptr const & l, tileinfo_ptr const & r) const
{
return *l < *r;
}
};
set<tileinfo_ptr, LessByTileKey> m_tileInfos;
void CancelTileInfo(tileinfo_ptr tileToCancel);
void ClearTileInfo(tileinfo_ptr & tileToClear);
};
set<tileinfo_ptr, LessByTileKey> m_tileInfos;
void ClearTileInfo(tileinfo_ptr & tileToClear);
};
}

View file

@ -5,8 +5,13 @@
namespace df
{
ReadMWMTask::ReadMWMTask(weak_ptr<TileInfo> const & tileInfo, EngineContext & context)
ReadMWMTask::ReadMWMTask(weak_ptr<TileInfo> const & tileInfo,
MemoryFeatureIndex & memIndex,
model::FeaturesFetcher & model,
EngineContext & context)
: m_tileInfo(tileInfo)
, m_memIndex(memIndex)
, m_model(model)
, m_context(context)
{
}
@ -19,8 +24,8 @@ namespace df
try
{
tileInfo->ReadFeatureIndex();
tileInfo->ReadFeatures(m_context);
tileInfo->ReadFeatureIndex(m_model);
tileInfo->ReadFeatures(m_model, m_memIndex, m_context);
}
catch (TileInfo::ReadCanceledException & ex)
{

View file

@ -17,13 +17,19 @@ namespace df
class ReadMWMTask : public threads::IRoutine
{
public:
ReadMWMTask(weak_ptr<TileInfo> const & tileInfo, EngineContext & context);
ReadMWMTask(weak_ptr<TileInfo> const & tileInfo,
MemoryFeatureIndex & memIndex,
model::FeaturesFetcher & model,
EngineContext & context);
virtual void Do();
private:
weak_ptr<TileInfo> m_tileInfo;
MemoryFeatureIndex & m_memIndex;
model::FeaturesFetcher & m_model;
EngineContext & m_context;
#ifdef DEBUG
dbg::ObjectTracker m_objTracker;
#endif

View file

@ -63,10 +63,8 @@ namespace
namespace df
{
TileInfo::TileInfo(TileKey const & key, model::FeaturesFetcher & model, MemoryFeatureIndex & memIndex)
TileInfo::TileInfo(TileKey const & key)
: m_key(key)
, m_model(model)
, m_memIndex(memIndex)
{}
m2::RectD TileInfo::GetGlobalRect() const
@ -83,64 +81,62 @@ m2::RectD TileInfo::GetGlobalRect() const
return tileRect;
}
bool TileInfo::DoNeedReadIndex() const
void TileInfo::ReadFeatureIndex(model::FeaturesFetcher const & model)
{
return m_featureInfo.empty();
}
void TileInfo::Cancel()
{
m_isCanceled = true;
threads::MutexGuard guard(m_mutex);
m_memIndex.RemoveFeatures(m_featureInfo);
}
void TileInfo::RequestFeatures(vector<size_t> & featureIndexes)
if (DoNeedReadIndex())
{
threads::MutexGuard guard(m_mutex);
m_memIndex.ReadFeaturesRequest(m_featureInfo, featureIndexes);
CheckCanceled();
model.ForEachFeatureID(GetGlobalRect(), *this, m_key.m_zoomLevel);
sort(m_featureInfo.begin(), m_featureInfo.end());
}
}
void TileInfo::CheckCanceled()
{
if (m_isCanceled)
MYTHROW(ReadCanceledException, ());
}
void TileInfo::ReadFeatureIndex()
{
if (DoNeedReadIndex())
namespace
{
threads::MutexGuard guard(m_mutex);
CheckCanceled();
m_model.ForEachFeatureID(GetGlobalRect(), *this, m_key.m_zoomLevel);
}
struct IDsAccumulator
{
IDsAccumulator(vector<FeatureID> & ids, vector<FeatureInfo> const & src)
: m_ids(ids)
, m_src(src)
{
}
void TileInfo::ReadFeatures(EngineContext & context)
void operator()(size_t index)
{
ASSERT_LESS(index, m_src.size(), ());
m_ids.push_back(m_src[index].m_id);
}
vector<FeatureID> & m_ids;
vector<FeatureInfo> const & m_src;
};
}
void TileInfo::ReadFeatures(model::FeaturesFetcher const & model,
MemoryFeatureIndex & memIndex,
EngineContext & context)
{
CheckCanceled();
vector<size_t> indexes;
RequestFeatures(indexes);
RequestFeatures(memIndex, indexes);
for (size_t i = 0; i < indexes.size(); ++i)
{
CheckCanceled();
LOG(LINFO, ("Trying to read", indexes[i]));
vector<FeatureID> featuresToRead;
for_each(indexes.begin(), indexes.end(), IDsAccumulator(featuresToRead, m_featureInfo));
model.ReadFeatures(*this, featuresToRead);
}
if (!indexes.empty() && m_key == TileKey(0,0,3))
void TileInfo::Cancel(MemoryFeatureIndex & memIndex)
{
context.BeginReadTile(m_key);
{
context.InsertShape(m_key, MovePointer<MapShape>(CreateFakeShape1()));
context.InsertShape(m_key, MovePointer<MapShape>(CreateFakeShape2()));
context.InsertShape(m_key, MovePointer<MapShape>(CreateFakeLine1()));
context.InsertShape(m_key, MovePointer<MapShape>(CreateFakeLine2()));
}
context.EndReadTile(m_key);
m_isCanceled = true;
threads::MutexGuard guard(m_mutex);
memIndex.RemoveFeatures(m_featureInfo);
}
bool TileInfo::operator ()(FeatureType const & f)
{
return true;
}
void TileInfo::operator ()(FeatureID const & id)
@ -149,4 +145,22 @@ void TileInfo::operator ()(FeatureID const & id)
CheckCanceled();
}
//====================================================//
bool TileInfo::DoNeedReadIndex() const
{
return m_featureInfo.empty();
}
void TileInfo::RequestFeatures(MemoryFeatureIndex & memIndex, vector<size_t> & featureIndexes)
{
threads::MutexGuard guard(m_mutex);
memIndex.ReadFeaturesRequest(m_featureInfo, featureIndexes);
}
void TileInfo::CheckCanceled()
{
if (m_isCanceled)
MYTHROW(ReadCanceledException, ());
}
}

View file

@ -15,6 +15,8 @@
namespace model { class FeaturesFetcher; }
class FeatureType;
namespace df
{
class EngineContext;
@ -51,36 +53,33 @@ public:
class TileInfo : private noncopyable
{
public:
DECLARE_EXCEPTION(ReadCanceledException, RootException);
TileInfo(TileKey const & key, model::FeaturesFetcher & model, MemoryFeatureIndex & memIndex);
TileInfo(TileKey const & key);
void ReadFeatureIndex();
void ReadFeatures(EngineContext & context);
void ReadFeatureIndex(model::FeaturesFetcher const & model);
void ReadFeatures(model::FeaturesFetcher const & model,
MemoryFeatureIndex & memIndex,
EngineContext & context);
void Cancel(MemoryFeatureIndex & memIndex);
m2::RectD GetGlobalRect() const;
TileKey const & GetTileKey() const { return m_key; }
void Cancel();
void operator ()(const FeatureID & id);
bool operator < (const TileInfo & other) const { return m_key < other.m_key; }
void operator ()(FeatureID const & id);
bool operator ()(FeatureType const & f);
bool operator <(TileInfo const & other) const { return m_key < other.m_key; }
private:
void RequestFeatures(vector<size_t> & featureIndexes);
void RequestFeatures(MemoryFeatureIndex & memIndex, vector<size_t> & featureIndexes);
void CheckCanceled();
bool DoNeedReadIndex() const;
private:
TileKey m_key;
vector<FeatureInfo> m_featureInfo;
model::FeaturesFetcher & m_model;
MemoryFeatureIndex & m_memIndex;
bool m_isCanceled;
threads::Mutex m_mutex;
};
}

View file

@ -12,6 +12,7 @@
#include "../std/vector.hpp"
#include "../std/unordered_set.hpp"
#include "../std/algorithm.hpp"
class MwmValue : public MwmSet::MwmValueBase
@ -223,6 +224,17 @@ public:
ForEachInIntervals(implFunctor, covering::FullCover, m2::RectD::GetInfiniteRect(), scale);
}
template <typename F>
void ReadFeatures(F & f, vector<FeatureID> const & features) const
{
if (features.empty())
return;
size_t currentIndex = 0;
while (currentIndex < features.size())
currentIndex = ReadFeatureRange(f, features, currentIndex);
}
/// Guard for loading features from particular MWM by demand.
class FeaturesLoaderGuard
{
@ -241,6 +253,38 @@ public:
private:
template <typename F>
size_t ReadFeatureRange(F & f, vector<FeatureID> const & features, size_t index) const
{
ASSERT_LESS(index, features.size(), ());
size_t result = index;
MwmId id = features[index].m_mwm;
MwmLock lock(*this, id);
MwmValue * pValue = lock.GetValue();
if (pValue)
{
FeaturesVector featureReader(pValue->m_cont, pValue->GetHeader());
while (result < features.size() && id == features[result].m_mwm)
{
FeatureID const & featureId = features[result];
FeatureType featureType;
featureReader.Get(featureId.m_offset, featureType);
featureType.SetID(featureId);
f(featureType);
++result;
}
}
else
{
result = distance(features.begin(),
lower_bound(features.begin(), features.end(), FeatureID(id + 1, 0)));
}
return result;
}
template <typename F>
void ForEachInIntervals(F & f, covering::CoveringMode mode,
m2::RectD const & rect, uint32_t scale) const

View file

@ -78,6 +78,12 @@ namespace model
m_multiIndex.ForEachFeatureIDInRect(toDo, rect, scale);
}
template <class ToDo>
void ReadFeatures(ToDo & toDo, vector<FeatureID> const & features) const
{
m_multiIndex.ReadFeatures(toDo, features);
}
//@}
Index const & GetIndex() const { return m_multiIndex; }

View file

@ -38,6 +38,7 @@ using std::transform;
using std::push_heap;
using std::pop_heap;
using std::sort_heap;
using std::distance;
using std::remove_copy_if;
#ifdef DEBUG_NEW