Optimized memory allocations in read manager

This commit is contained in:
r.kuznetsov 2015-07-07 16:40:34 +03:00
parent 23fdd84701
commit 4e8d7d40e7
5 changed files with 35 additions and 47 deletions

View file

@ -15,10 +15,13 @@
namespace
{
void MarkNodesAsReaded(vector<df::FeatureInfo> & features, const vector<size_t> & indexes)
void MarkNodesAsReaded(df::TFeaturesInfo & features, vector<FeatureID> const & featuresToRead)
{
for (size_t i = 0; i < indexes.size(); ++i)
features[indexes[i]].m_isOwner = true;
for (df::FeatureInfo & info : features)
{
if (find(featuresToRead.begin(), featuresToRead.end(), info.m_id) != featuresToRead.end())
info.m_isOwner = true;
}
}
// void ResetReadedMark(vector<df::FeatureInfo> & features)
@ -143,7 +146,7 @@ namespace
class TestRoutine : public threads::IRoutine
{
public:
TestRoutine(vector<df::FeatureInfo> & features, df::MemoryFeatureIndex &index)
TestRoutine(df::TFeaturesInfo & features, df::MemoryFeatureIndex &index)
: m_features(features)
, m_index(index)
{
@ -151,17 +154,17 @@ namespace
virtual void Do()
{
vector<size_t> result;
vector<FeatureID> result;
m_index.ReadFeaturesRequest(m_features, result);
MarkNodesAsReaded(m_features, result);
}
private:
vector<df::FeatureInfo> & m_features;
df::TFeaturesInfo & m_features;
df::MemoryFeatureIndex & m_index;
};
void GenerateFeatures(vector<df::FeatureInfo> & features)
void GenerateFeatures(df::TFeaturesInfo & features)
{
for (int i = 0; i < 10000; ++i)
features.push_back(df::FeatureInfo(FeatureID(MwmSet::MwmId(), rand())));
@ -177,7 +180,7 @@ UNIT_TEST(MemoryFeatureIndex_MT_Test)
threads::ThreadPool pool(4, bind(&JoinFinishFinction, _1, ref(cond), ref(counter)));
df::MemoryFeatureIndex index;
vector<df::FeatureInfo> features[TASK_COUNT];
df::TFeaturesInfo features[TASK_COUNT];
for (int i = 0; i < TASK_COUNT; ++i)
{

View file

@ -3,7 +3,7 @@
namespace df
{
void MemoryFeatureIndex::ReadFeaturesRequest(vector<FeatureInfo> & features, vector<size_t> & indexes)
void MemoryFeatureIndex::ReadFeaturesRequest(TFeaturesInfo & features, vector<FeatureID> & featuresToRead)
{
threads::MutexGuard lock(m_mutex);
@ -13,13 +13,13 @@ void MemoryFeatureIndex::ReadFeaturesRequest(vector<FeatureInfo> & features, vec
ASSERT(m_features.find(info.m_id) != m_features.end() || !info.m_isOwner,());
if (!info.m_isOwner && m_features.insert(info.m_id).second)
{
indexes.push_back(i);
featuresToRead.push_back(info.m_id);
info.m_isOwner = true;
}
}
}
void MemoryFeatureIndex::RemoveFeatures(vector<FeatureInfo> & features)
void MemoryFeatureIndex::RemoveFeatures(TFeaturesInfo & features)
{
threads::MutexGuard lock(m_mutex);

View file

@ -1,6 +1,8 @@
#pragma once
#include "indexer/feature_decl.hpp"
#include "base/buffer_vector.hpp"
#include "base/mutex.hpp"
#include "std/set.hpp"
@ -13,6 +15,9 @@ namespace df
struct FeatureInfo
{
FeatureInfo()
: m_isOwner(false) {}
FeatureInfo(FeatureID const & id)
: m_id(id), m_isOwner(false) {}
@ -28,11 +33,14 @@ struct FeatureInfo
bool m_isOwner;
};
size_t const AverageFeaturesCount = 2048;
using TFeaturesInfo = buffer_vector<FeatureInfo, AverageFeaturesCount>;
class MemoryFeatureIndex : private noncopyable
{
public:
void ReadFeaturesRequest(vector<FeatureInfo> & features, vector<size_t> & indexes);
void RemoveFeatures(vector<FeatureInfo> & features);
void ReadFeaturesRequest(TFeaturesInfo & features, vector<FeatureID> & featuresToRead);
void RemoveFeatures(TFeaturesInfo & features);
private:
threads::Mutex m_mutex;

View file

@ -7,39 +7,18 @@
#include "indexer/scales.hpp"
#include "base/scope_guard.hpp"
#include "base/logging.hpp"
#include "std/bind.hpp"
namespace
{
struct IDsAccumulator
{
IDsAccumulator(vector<FeatureID> & ids, vector<df::FeatureInfo> const & src)
: m_ids(ids)
, m_src(src)
{
}
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<df::FeatureInfo> const & m_src;
};
} // namespace
namespace df
{
TileInfo::TileInfo(drape_ptr<EngineContext> && context)
: m_context(move(context))
, m_isCanceled(false)
{}
{
}
m2::RectD TileInfo::GetGlobalRect() const
{
@ -69,14 +48,12 @@ void TileInfo::ReadFeatures(MapDataProvider const & model,
ReadFeatureIndex(model);
CheckCanceled();
vector<size_t> indexes;
RequestFeatures(memIndex, indexes);
vector<FeatureID> featuresToRead;
featuresToRead.reserve(AverageFeaturesCount);
RequestFeatures(memIndex, featuresToRead);
if (!indexes.empty())
if (!featuresToRead.empty())
{
vector<FeatureID> featuresToRead;
for_each(indexes.begin(), indexes.end(), IDsAccumulator(featuresToRead, m_featureInfo));
RuleDrawer drawer(bind(&TileInfo::InitStylist, this, _1 ,_2), make_ref(m_context));
model.ReadFeatures(bind<void>(ref(drawer), _1), featuresToRead);
}
@ -108,10 +85,10 @@ bool TileInfo::DoNeedReadIndex() const
return m_featureInfo.empty();
}
void TileInfo::RequestFeatures(MemoryFeatureIndex & memIndex, vector<size_t> & featureIndexes)
void TileInfo::RequestFeatures(MemoryFeatureIndex & memIndex, vector<FeatureID> & featuresToRead)
{
lock_guard<mutex> lock(m_mutex);
memIndex.ReadFeaturesRequest(m_featureInfo, featureIndexes);
memIndex.ReadFeaturesRequest(m_featureInfo, featuresToRead);
}
void TileInfo::CheckCanceled() const

View file

@ -39,7 +39,7 @@ private:
void ReadFeatureIndex(MapDataProvider const & model);
void ProcessID(FeatureID const & id);
void InitStylist(FeatureType const & f, Stylist & s);
void RequestFeatures(MemoryFeatureIndex & memIndex, vector<size_t> & featureIndexes);
void RequestFeatures(MemoryFeatureIndex & memIndex, vector<FeatureID> & featuresToRead);
void CheckCanceled() const;
bool DoNeedReadIndex() const;
@ -47,7 +47,7 @@ private:
private:
drape_ptr<EngineContext> m_context;
vector<FeatureInfo> m_featureInfo;
TFeaturesInfo m_featureInfo;
atomic<bool> m_isCanceled;
mutex m_mutex;