forked from organicmaps/organicmaps
Fixed MwmSet::Register() signature.
This commit is contained in:
parent
25f7a7f2f3
commit
9e5ac4ef2a
36 changed files with 490 additions and 333 deletions
|
@ -14,10 +14,10 @@ namespace my
|
|||
#define ARRAY_SIZE(X) sizeof(::my::impl::ArraySize(X))
|
||||
|
||||
// Make class noncopyable.
|
||||
#define NONCOPYABLE(class_name) \
|
||||
private: \
|
||||
class_name const & operator = (class_name const &); \
|
||||
class_name(class_name const &);
|
||||
#define NONCOPYABLE(class_name) \
|
||||
private: \
|
||||
class_name const & operator=(class_name const &) = delete; \
|
||||
class_name(class_name const &) = delete
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
#define TO_STRING_IMPL(x) #x
|
||||
|
@ -72,3 +72,9 @@ private: \
|
|||
className(className &&) = delete; \
|
||||
className & operator=(const className &) = delete; \
|
||||
className & operator=(className &&) = delete;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
#else
|
||||
#define WARN_UNUSED_RESULT
|
||||
#endif // defined(__GNUC__)
|
||||
|
|
|
@ -60,11 +60,15 @@ string FormatCurrentTime()
|
|||
return s;
|
||||
}
|
||||
|
||||
uint32_t GenerateTimestamp(int year, int month, int day) {
|
||||
return (year - 100) * 10000 + (month + 1) * 100 + day;
|
||||
}
|
||||
|
||||
uint32_t TodayAsYYMMDD()
|
||||
{
|
||||
time_t rawTime = time(NULL);
|
||||
tm * pTm = gmtime(&rawTime);
|
||||
return (pTm->tm_year - 100) * 10000 + (pTm->tm_mon + 1) * 100 + pTm->tm_mday;
|
||||
return GenerateTimestamp(pTm->tm_year, pTm->tm_mon, pTm->tm_mday);
|
||||
}
|
||||
|
||||
namespace
|
||||
|
|
|
@ -25,6 +25,14 @@ public:
|
|||
};
|
||||
|
||||
string FormatCurrentTime();
|
||||
|
||||
/// Generates timestamp for a specified day.
|
||||
/// \param year The number of years since 1900.
|
||||
/// \param month The number of month since January, in the range 0 to 11.
|
||||
/// \param day The day of the month, in the range 1 to 31.
|
||||
/// \return Timestamp.
|
||||
uint32_t GenerateTimestamp(int year, int month, int day);
|
||||
|
||||
uint32_t TodayAsYYMMDD();
|
||||
|
||||
/// Always creates strings in UTC time: 1997-07-16T07:30:15Z
|
||||
|
|
|
@ -32,8 +32,7 @@ DrapeSurface::DrapeSurface()
|
|||
Platform & pl = GetPlatform();
|
||||
pl.GetFilesByExt(pl.WritableDir(), DATA_FILE_EXTENSION, maps);
|
||||
|
||||
feature::DataHeader::Version version;
|
||||
for_each(maps.begin(), maps.end(), bind(&model::FeaturesFetcher::RegisterMap, &m_model, _1, version));
|
||||
for_each(maps.begin(), maps.end(), bind(&model::FeaturesFetcher::RegisterMap, &m_model, _1));
|
||||
///}
|
||||
///
|
||||
m_navigator.LoadState();
|
||||
|
|
|
@ -118,7 +118,7 @@ namespace feature
|
|||
// write version information
|
||||
{
|
||||
FileWriter w = m_writer.GetWriter(VERSION_FILE_TAG);
|
||||
ver::WriteVersion(w);
|
||||
version::WriteVersion(w);
|
||||
}
|
||||
|
||||
// write own mwm header
|
||||
|
|
|
@ -24,8 +24,9 @@ UNIT_TEST(CheckMWM_LoadAll)
|
|||
{
|
||||
try
|
||||
{
|
||||
feature::DataHeader::Version version;
|
||||
m.RegisterMap(s, version);
|
||||
pair<MwmSet::MwmLock, bool> p = m.RegisterMap(s);
|
||||
TEST(p.first.IsLocked(), ());
|
||||
TEST(p.second, ());
|
||||
}
|
||||
catch (RootException const & ex)
|
||||
{
|
||||
|
|
|
@ -10,20 +10,21 @@
|
|||
#include "../coding/file_reader.hpp"
|
||||
#include "../coding/file_container.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
typedef feature::DataHeader FHeaderT;
|
||||
using FHeaderT = feature::DataHeader;
|
||||
|
||||
} // namespace
|
||||
|
||||
void LoadMapHeader(FilesContainerR const & cont, FHeaderT & header)
|
||||
{
|
||||
ModelReaderPtr headerReader = cont.GetReader(HEADER_FILE_TAG);
|
||||
version::MwmVersion version;
|
||||
|
||||
if (!cont.IsExist(VERSION_FILE_TAG))
|
||||
header.LoadVer1(headerReader);
|
||||
if (version::ReadVersion(cont, version))
|
||||
header.Load(headerReader, version.format);
|
||||
else
|
||||
{
|
||||
ModelReaderPtr verReader = cont.GetReader(VERSION_FILE_TAG);
|
||||
header.Load(headerReader, static_cast<FHeaderT::Version>(ver::ReadVersion(verReader)));
|
||||
}
|
||||
header.LoadV1(headerReader);
|
||||
}
|
||||
|
||||
void LoadMapHeader(ModelReaderPtr const & reader, FHeaderT & header)
|
||||
|
@ -33,23 +34,13 @@ void LoadMapHeader(ModelReaderPtr const & reader, FHeaderT & header)
|
|||
|
||||
void IndexFactory::Load(FilesContainerR const & cont)
|
||||
{
|
||||
ReadVersion(cont, m_version);
|
||||
LoadMapHeader(cont, m_header);
|
||||
}
|
||||
|
||||
IntervalIndexIFace * IndexFactory::CreateIndex(ModelReaderPtr reader)
|
||||
{
|
||||
IntervalIndexIFace * p;
|
||||
|
||||
switch (m_header.GetVersion())
|
||||
{
|
||||
case FHeaderT::v1:
|
||||
p = new old_101::IntervalIndex<uint32_t, ModelReaderPtr>(reader);
|
||||
break;
|
||||
|
||||
default:
|
||||
p = new IntervalIndex<ModelReaderPtr>(reader);
|
||||
break;
|
||||
}
|
||||
|
||||
return p;
|
||||
if (m_version.format == version::v1)
|
||||
return new old_101::IntervalIndex<uint32_t, ModelReaderPtr>(reader);
|
||||
return new IntervalIndex<ModelReaderPtr>(reader);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "data_header.hpp"
|
||||
#include "mwm_version.hpp"
|
||||
|
||||
#include "../coding/reader.hpp"
|
||||
|
||||
|
@ -9,11 +10,13 @@ class IntervalIndexIFace;
|
|||
|
||||
class IndexFactory
|
||||
{
|
||||
version::MwmVersion m_version;
|
||||
feature::DataHeader m_header;
|
||||
|
||||
public:
|
||||
void Load(FilesContainerR const & cont);
|
||||
|
||||
inline version::MwmVersion const & GetMwmVersion() const { return m_version; }
|
||||
inline feature::DataHeader const & GetHeader() const { return m_header; }
|
||||
|
||||
IntervalIndexIFace * CreateIndex(ModelReaderPtr reader);
|
||||
|
|
|
@ -93,7 +93,8 @@ namespace feature
|
|||
WriteVarInt(w, static_cast<int32_t>(m_type));
|
||||
}
|
||||
|
||||
void DataHeader::Load(ModelReaderPtr const & r, Version ver /*= unknownVersion*/)
|
||||
void DataHeader::Load(ModelReaderPtr const & r,
|
||||
version::Format format /* = version::unknownFormat */)
|
||||
{
|
||||
ReaderSource<ModelReaderPtr> src(r);
|
||||
m_codingParams.Load(src);
|
||||
|
@ -105,7 +106,7 @@ namespace feature
|
|||
LoadBytes(src, m_langs);
|
||||
|
||||
m_type = static_cast<MapType>(ReadVarInt<int32_t>(src));
|
||||
m_ver = ver;
|
||||
m_format = format;
|
||||
|
||||
if (!IsMWMSuitable())
|
||||
{
|
||||
|
@ -117,7 +118,7 @@ namespace feature
|
|||
// Place all new serializable staff here.
|
||||
}
|
||||
|
||||
void DataHeader::LoadVer1(ModelReaderPtr const & r)
|
||||
void DataHeader::LoadV1(ModelReaderPtr const & r)
|
||||
{
|
||||
ReaderSource<ModelReaderPtr> src(r);
|
||||
int64_t const base = ReadPrimitiveFromSource<int64_t>(src);
|
||||
|
@ -132,6 +133,6 @@ namespace feature
|
|||
|
||||
m_type = country;
|
||||
|
||||
m_ver = v1;
|
||||
m_format = version::v1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "coding_params.hpp"
|
||||
#include "mwm_version.hpp"
|
||||
|
||||
#include "../geometry/rect2d.hpp"
|
||||
|
||||
|
@ -59,24 +60,15 @@ namespace feature
|
|||
|
||||
pair<int, int> GetScaleRange() const;
|
||||
|
||||
enum Version
|
||||
{
|
||||
unknownVersion = -1,
|
||||
v1 = 0, // April 2011
|
||||
v2, // November 2011 (store type index, instead of raw type in mwm)
|
||||
v3, // March 2013 (store type index, instead of raw type in search data)
|
||||
lastVersion = v3
|
||||
};
|
||||
|
||||
inline Version GetVersion() const { return m_ver; }
|
||||
inline bool IsMWMSuitable() const { return (m_ver <= lastVersion); }
|
||||
inline version::Format GetFormat() const { return m_format; }
|
||||
inline bool IsMWMSuitable() const { return m_format <= version::lastFormat; }
|
||||
|
||||
/// @name Serialization
|
||||
//@{
|
||||
void Save(FileWriter & w) const;
|
||||
|
||||
void Load(ModelReaderPtr const & r, Version ver = unknownVersion);
|
||||
void LoadVer1(ModelReaderPtr const & r);
|
||||
void Load(ModelReaderPtr const & r, version::Format format = version::unknownFormat);
|
||||
void LoadV1(ModelReaderPtr const & r);
|
||||
//@}
|
||||
|
||||
enum MapType
|
||||
|
@ -90,7 +82,7 @@ namespace feature
|
|||
inline MapType GetType() const { return m_type; }
|
||||
|
||||
private:
|
||||
Version m_ver;
|
||||
version::Format m_format;
|
||||
MapType m_type;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -56,19 +56,12 @@ SharedLoadInfo::ReaderT SharedLoadInfo::GetTrianglesReader(int ind) const
|
|||
|
||||
void SharedLoadInfo::CreateLoader()
|
||||
{
|
||||
switch (m_header.GetVersion())
|
||||
{
|
||||
case DataHeader::v1:
|
||||
if (m_header.GetFormat() == version::v1)
|
||||
m_pLoader = new old_101::feature::LoaderImpl(*this);
|
||||
break;
|
||||
|
||||
default:
|
||||
else
|
||||
m_pLoader = new LoaderCurrent(*this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// LoaderBase implementation.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -26,22 +26,11 @@ string MwmValue::GetFileName() const
|
|||
return s;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Index::MwmLock implementation
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
string Index::MwmLock::GetFileName() const
|
||||
{
|
||||
MwmValue * p = GetValue();
|
||||
return (p ? p->GetFileName() : string());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Index implementation
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Index::GetVersion(string const & name, MwmInfo & info,
|
||||
feature::DataHeader::Version & version) const
|
||||
bool Index::GetVersion(string const & name, MwmInfo & info)
|
||||
{
|
||||
MwmValue value(name);
|
||||
|
||||
|
@ -54,8 +43,8 @@ bool Index::GetVersion(string const & name, MwmInfo & info,
|
|||
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);
|
||||
info.m_version = value.GetMwmVersion();
|
||||
|
||||
version = h.GetVersion();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -104,30 +93,28 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
bool Index::RegisterMap(string const & fileName, m2::RectD & rect,
|
||||
feature::DataHeader::Version & version)
|
||||
pair<MwmSet::MwmLock, bool> Index::RegisterMap(string const & fileName)
|
||||
{
|
||||
if (GetPlatform().IsFileExistsByFullPath(GetFullPath(fileName + READY_FILE_EXTENSION)))
|
||||
{
|
||||
UpdateStatus status = UpdateMap(fileName, rect, version);
|
||||
switch (status)
|
||||
pair<MwmSet::MwmLock, UpdateStatus> updateResult = UpdateMap(fileName);
|
||||
switch (updateResult.second)
|
||||
{
|
||||
case UPDATE_STATUS_OK:
|
||||
return true;
|
||||
return make_pair(move(updateResult.first), true);
|
||||
case UPDATE_STATUS_BAD_FILE:
|
||||
return false;
|
||||
return make_pair(move(updateResult.first), false);
|
||||
case UPDATE_STATUS_UPDATE_DELAYED:
|
||||
// Not dangerous, but it's strange when adding existing maps.
|
||||
ASSERT(false, ());
|
||||
version = feature::DataHeader::v3;
|
||||
return true;
|
||||
return make_pair(move(updateResult.first), true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Register(fileName, rect, version))
|
||||
return false;
|
||||
m_observers.ForEach(&Observer::OnMapRegistered, fileName);
|
||||
return true;
|
||||
pair<MwmSet::MwmLock, bool> result = Register(fileName);
|
||||
if (result.second)
|
||||
m_observers.ForEach(&Observer::OnMapRegistered, fileName);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Index::DeleteMap(string const & fileName)
|
||||
|
@ -154,10 +141,11 @@ bool Index::RemoveObserver(Observer & observer)
|
|||
return m_observers.Remove(observer);
|
||||
}
|
||||
|
||||
Index::UpdateStatus Index::UpdateMap(string const & fileName, m2::RectD & rect,
|
||||
feature::DataHeader::Version & version)
|
||||
pair<MwmSet::MwmLock, Index::UpdateStatus> Index::UpdateMap(string const & fileName)
|
||||
{
|
||||
UpdateStatus status = UPDATE_STATUS_OK;
|
||||
pair<MwmSet::MwmLock, UpdateStatus> result;
|
||||
result.second = UPDATE_STATUS_BAD_FILE;
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(m_lock);
|
||||
|
||||
|
@ -165,19 +153,24 @@ Index::UpdateStatus Index::UpdateMap(string const & fileName, m2::RectD & rect,
|
|||
if (id != INVALID_MWM_ID && m_info[id].m_lockCount > 0)
|
||||
{
|
||||
m_info[id].SetStatus(MwmInfo::STATUS_PENDING_UPDATE);
|
||||
status = UPDATE_STATUS_UPDATE_DELAYED;
|
||||
result.first = GetLock(id);
|
||||
result.second = UPDATE_STATUS_UPDATE_DELAYED;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplaceFileWithReady(fileName);
|
||||
status = RegisterImpl(fileName, rect, version) ? UPDATE_STATUS_OK : UPDATE_STATUS_BAD_FILE;
|
||||
pair<MwmSet::MwmLock, bool> registerResult = RegisterImpl(fileName);
|
||||
if (registerResult.second) {
|
||||
result.first = move(registerResult.first);
|
||||
result.second = UPDATE_STATUS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (status != UPDATE_STATUS_BAD_FILE)
|
||||
if (result.second != UPDATE_STATUS_BAD_FILE)
|
||||
m_observers.ForEach(&Observer::OnMapUpdateIsReady, fileName);
|
||||
if (status == UPDATE_STATUS_OK)
|
||||
if (result.second == UPDATE_STATUS_OK)
|
||||
m_observers.ForEach(&Observer::OnMapUpdated, fileName);
|
||||
return status;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Index::UpdateMwmInfo(MwmId id)
|
||||
|
@ -214,19 +207,26 @@ void Index::UpdateMwmInfo(MwmId id)
|
|||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Index::FeaturesLoaderGuard::FeaturesLoaderGuard(Index const & parent, MwmId id)
|
||||
: m_lock(parent, id),
|
||||
/// @note This guard is suitable when mwm is loaded
|
||||
m_vector(m_lock.GetValue()->m_cont, m_lock.GetValue()->GetHeader())
|
||||
: m_lock(const_cast<Index &>(parent), id),
|
||||
/// @note This guard is suitable when mwm is loaded
|
||||
m_vector(m_lock.GetValue<MwmValue>()->m_cont, m_lock.GetValue<MwmValue>()->GetHeader())
|
||||
{
|
||||
}
|
||||
|
||||
string Index::FeaturesLoaderGuard::GetFileName() const
|
||||
{
|
||||
if (!m_lock.IsLocked())
|
||||
return string();
|
||||
return m_lock.GetValue<MwmValue>()->GetFileName();
|
||||
}
|
||||
|
||||
bool Index::FeaturesLoaderGuard::IsWorld() const
|
||||
{
|
||||
return (m_lock.GetValue()->GetHeader().GetType() == feature::DataHeader::world);
|
||||
return m_lock.GetValue<MwmValue>()->GetHeader().GetType() == feature::DataHeader::world;
|
||||
}
|
||||
|
||||
void Index::FeaturesLoaderGuard::GetFeature(uint32_t offset, FeatureType & ft)
|
||||
{
|
||||
m_vector.Get(offset, ft);
|
||||
ft.SetID(FeatureID(m_lock.GetID(), offset));
|
||||
ft.SetID(FeatureID(m_lock.GetId(), offset));
|
||||
}
|
||||
|
|
|
@ -10,10 +10,12 @@
|
|||
|
||||
#include "../defines.hpp"
|
||||
|
||||
#include "../base/macros.hpp"
|
||||
#include "../base/observer_list.hpp"
|
||||
|
||||
#include "../std/algorithm.hpp"
|
||||
#include "../std/unordered_set.hpp"
|
||||
#include "../std/utility.hpp"
|
||||
#include "../std/vector.hpp"
|
||||
|
||||
class MwmValue : public MwmSet::MwmValueBase
|
||||
|
@ -25,6 +27,7 @@ public:
|
|||
explicit MwmValue(string const & name);
|
||||
|
||||
inline feature::DataHeader const & GetHeader() const { return m_factory.GetHeader(); }
|
||||
inline version::MwmVersion const & GetMwmVersion() const { return m_factory.GetMwmVersion(); }
|
||||
|
||||
/// @return MWM file name without extension.
|
||||
string GetFileName() const;
|
||||
|
@ -34,8 +37,7 @@ class Index : public MwmSet
|
|||
{
|
||||
protected:
|
||||
// MwmSet overrides:
|
||||
bool GetVersion(string const & name, MwmInfo & info,
|
||||
feature::DataHeader::Version & version) const override;
|
||||
bool GetVersion(string const & name, MwmInfo & info) override;
|
||||
MwmValue * CreateValue(string const & name) const override;
|
||||
void UpdateMwmInfo(MwmId id) override;
|
||||
|
||||
|
@ -72,43 +74,28 @@ public:
|
|||
Index();
|
||||
~Index();
|
||||
|
||||
class MwmLock : public MwmSet::MwmLock
|
||||
{
|
||||
typedef MwmSet::MwmLock BaseT;
|
||||
public:
|
||||
MwmLock(Index const & index, MwmId mwmId)
|
||||
: BaseT(const_cast<Index &>(index), mwmId) {}
|
||||
|
||||
inline MwmValue * GetValue() const
|
||||
{
|
||||
return static_cast<MwmValue *>(BaseT::GetValue());
|
||||
}
|
||||
|
||||
/// @return MWM file name without extension.
|
||||
/// If value is 0, an empty string returned.
|
||||
string GetFileName() const;
|
||||
};
|
||||
|
||||
/// Registers new map.
|
||||
///
|
||||
/// \return True if map was successfully registered. In this case
|
||||
/// version is set to the file format version. Otherwise
|
||||
/// returns false and version is not modified. This means
|
||||
/// that file isn't suitable, for example, because of
|
||||
/// greater version.
|
||||
bool RegisterMap(string const & fileName, m2::RectD & rect,
|
||||
feature::DataHeader::Version & version);
|
||||
/// \return A pair of MwmLock and a flag. MwmLock is locked iff map
|
||||
/// with fileName was created or already exists. Flag is
|
||||
/// set when a new map was registered. Thus, there are
|
||||
/// three main cases:
|
||||
/// * map already exists - returns active lock and unset flag
|
||||
/// * a new map was registered - returns active lock and set flag
|
||||
/// * can't register new map - returns inactive lock and unset flag
|
||||
WARN_UNUSED_RESULT pair<MwmLock, bool> RegisterMap(string const & fileName);
|
||||
|
||||
/// Replaces map file corresponding to fileName with a new one, when
|
||||
/// it's possible - no clients of the map file. Otherwise, update
|
||||
/// will be delayed.
|
||||
///
|
||||
/// \return UPDATE_STATUS_OK, when map file have updated, as a side effect
|
||||
/// sets version to an mwm format version.
|
||||
/// UPDATE_STATUS_BAD_FILE when file isn't suitable for update.
|
||||
/// UPDATE_STATUS_UPDATE_DELAYED when update is delayed.
|
||||
UpdateStatus UpdateMap(string const & fileName, m2::RectD & rect,
|
||||
feature::DataHeader::Version & version);
|
||||
/// \return * map file have been updated - returns active lock and
|
||||
/// UPDATE_STATUS_OK
|
||||
/// * update is delayed because map is busy - returns active lock and
|
||||
/// UPDATE_STATUS_UPDATE_DELAYED
|
||||
/// * file isn't suitable for update - returns inactive lock and
|
||||
/// UPDATE_STATUS_BAD_FILE
|
||||
WARN_UNUSED_RESULT pair<MwmLock, UpdateStatus> UpdateMap(string const & fileName);
|
||||
|
||||
/// Deletes map both from file system and internal tables, also,
|
||||
/// deletes all files related to the map. If map was successfully
|
||||
|
@ -161,7 +148,7 @@ private:
|
|||
|
||||
void operator() (MwmLock const & lock, covering::CoveringGetter & cov, uint32_t scale) const
|
||||
{
|
||||
MwmValue * pValue = lock.GetValue();
|
||||
MwmValue * pValue = lock.GetValue<MwmValue>();
|
||||
if (pValue)
|
||||
{
|
||||
feature::DataHeader const & header = pValue->GetHeader();
|
||||
|
@ -181,7 +168,7 @@ private:
|
|||
pValue->m_factory);
|
||||
|
||||
// iterate through intervals
|
||||
ImplFunctor implF(fv, m_f, lock.GetID());
|
||||
ImplFunctor implF(fv, m_f, lock.GetId());
|
||||
for (size_t i = 0; i < interval.size(); ++i)
|
||||
index.ForEachInIntervalAndScale(implF, interval[i].first, interval[i].second, scale);
|
||||
}
|
||||
|
@ -217,7 +204,7 @@ private:
|
|||
|
||||
void operator() (MwmLock const & lock, covering::CoveringGetter & cov, uint32_t scale) const
|
||||
{
|
||||
MwmValue * pValue = lock.GetValue();
|
||||
MwmValue * pValue = lock.GetValue<MwmValue>();
|
||||
if (pValue)
|
||||
{
|
||||
feature::DataHeader const & header = pValue->GetHeader();
|
||||
|
@ -234,7 +221,7 @@ private:
|
|||
pValue->m_factory);
|
||||
|
||||
// iterate through intervals
|
||||
ImplFunctor implF(m_f, lock.GetID());
|
||||
ImplFunctor implF(m_f, lock.GetId());
|
||||
for (size_t i = 0; i < interval.size(); ++i)
|
||||
index.ForEachInIntervalAndScale(implF, interval[i].first, interval[i].second, scale);
|
||||
}
|
||||
|
@ -286,17 +273,17 @@ public:
|
|||
/// Guard for loading features from particular MWM by demand.
|
||||
class FeaturesLoaderGuard
|
||||
{
|
||||
MwmLock m_lock;
|
||||
FeaturesVector m_vector;
|
||||
|
||||
public:
|
||||
FeaturesLoaderGuard(Index const & parent, MwmId id);
|
||||
|
||||
inline MwmSet::MwmId GetID() const { return m_lock.GetID(); }
|
||||
inline string GetFileName() const { return m_lock.GetFileName(); }
|
||||
|
||||
inline MwmSet::MwmId GetId() const { return m_lock.GetId(); }
|
||||
string GetFileName() const;
|
||||
bool IsWorld() const;
|
||||
void GetFeature(uint32_t offset, FeatureType & ft);
|
||||
|
||||
private:
|
||||
MwmLock m_lock;
|
||||
FeaturesVector m_vector;
|
||||
};
|
||||
|
||||
MwmId GetMwmIdByName(string const & name) const
|
||||
|
@ -320,8 +307,8 @@ public:
|
|||
{
|
||||
if (id != INVALID_MWM_ID)
|
||||
{
|
||||
MwmLock lock(*this, id);
|
||||
if (lock.GetValue())
|
||||
MwmLock lock(const_cast<Index &>(*this), id);
|
||||
if (lock.IsLocked())
|
||||
{
|
||||
covering::CoveringGetter cov(rect, covering::ViewportWithLowLevels);
|
||||
ReadMWMFunctor<F> fn(f);
|
||||
|
@ -339,8 +326,8 @@ private:
|
|||
ASSERT_LESS(index, features.size(), ());
|
||||
size_t result = index;
|
||||
MwmId id = features[index].m_mwm;
|
||||
MwmLock lock(*this, id);
|
||||
MwmValue * pValue = lock.GetValue();
|
||||
MwmLock lock(const_cast<Index &>(*this), id);
|
||||
MwmValue * pValue = lock.GetValue<MwmValue>();
|
||||
if (pValue)
|
||||
{
|
||||
FeaturesVector featureReader(pValue->m_cont, pValue->GetHeader());
|
||||
|
@ -386,7 +373,7 @@ private:
|
|||
{
|
||||
case MwmInfo::COUNTRY:
|
||||
{
|
||||
MwmLock lock(*this, id);
|
||||
MwmLock lock(const_cast<Index &>(*this), id);
|
||||
f(lock, cov, scale);
|
||||
}
|
||||
break;
|
||||
|
@ -404,13 +391,13 @@ private:
|
|||
|
||||
if (worldID[0] < count)
|
||||
{
|
||||
MwmLock lock(*this, worldID[0]);
|
||||
MwmLock lock(const_cast<Index &>(*this), worldID[0]);
|
||||
f(lock, cov, scale);
|
||||
}
|
||||
|
||||
if (worldID[1] < count)
|
||||
{
|
||||
MwmLock lock(*this, worldID[1]);
|
||||
MwmLock lock(const_cast<Index &>(*this), worldID[1]);
|
||||
f(lock, cov, scale);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,10 +75,7 @@ private:
|
|||
UNIT_TEST(Index_Parse)
|
||||
{
|
||||
Index index;
|
||||
|
||||
m2::RectD dummyRect;
|
||||
feature::DataHeader::Version dummyVersion;
|
||||
index.RegisterMap("minsk-pass" DATA_FILE_EXTENSION, dummyRect, dummyVersion);
|
||||
index.RegisterMap("minsk-pass" DATA_FILE_EXTENSION);
|
||||
|
||||
// Make sure that index is actually parsed.
|
||||
NoopFunctor fn;
|
||||
|
@ -102,31 +99,49 @@ UNIT_TEST(Index_MwmStatusNotifications)
|
|||
index.AddObserver(observer);
|
||||
|
||||
TEST_EQUAL(0, observer.map_registered_calls(), ());
|
||||
m2::RectD dummyRect;
|
||||
feature::DataHeader::Version dummyVersion;
|
||||
|
||||
// Check that observers are triggered after map registration.
|
||||
TEST(index.RegisterMap(testMapName, dummyRect, dummyVersion), ());
|
||||
TEST_EQUAL(1, observer.map_registered_calls(), ());
|
||||
{
|
||||
pair<MwmSet::MwmLock, bool> p = index.RegisterMap(testMapName);
|
||||
TEST(p.first.IsLocked(), ());
|
||||
TEST(p.second, ());
|
||||
TEST_EQUAL(1, observer.map_registered_calls(), ());
|
||||
}
|
||||
|
||||
// Check that map can't registered twice and observers aren't
|
||||
// triggered.
|
||||
TEST(!index.RegisterMap(testMapName, dummyRect, dummyVersion), ());
|
||||
TEST_EQUAL(1, observer.map_registered_calls(), ());
|
||||
{
|
||||
pair<MwmSet::MwmLock, bool> p = index.RegisterMap(testMapName);
|
||||
TEST(p.first.IsLocked(), ());
|
||||
TEST(!p.second, ());
|
||||
TEST_EQUAL(1, observer.map_registered_calls(), ());
|
||||
}
|
||||
|
||||
TEST(my::CopyFileX(testMapPath, testMapUpdatePath), ());
|
||||
MY_SCOPE_GUARD(testMapUpdateGuard, bind(&CheckedDeleteFile, testMapUpdatePath));
|
||||
|
||||
// Check that observers are notified when map is deleted.
|
||||
TEST_EQUAL(0, observer.map_update_is_ready_calls(), ());
|
||||
TEST_EQUAL(0, observer.map_updated_calls(), ());
|
||||
TEST_EQUAL(Index::UPDATE_STATUS_OK, index.UpdateMap(testMapName, dummyRect, dummyVersion), ());
|
||||
TEST_EQUAL(1, observer.map_update_is_ready_calls(), ());
|
||||
TEST_EQUAL(1, observer.map_updated_calls(), ());
|
||||
{
|
||||
TEST_EQUAL(0, observer.map_update_is_ready_calls(), ());
|
||||
TEST_EQUAL(0, observer.map_updated_calls(), ());
|
||||
pair<MwmSet::MwmLock, Index::UpdateStatus> p = index.UpdateMap(testMapName);
|
||||
TEST(p.first.IsLocked(), ());
|
||||
TEST_EQUAL(Index::UPDATE_STATUS_OK, p.second, ());
|
||||
TEST_EQUAL(1, observer.map_update_is_ready_calls(), ());
|
||||
TEST_EQUAL(1, observer.map_updated_calls(), ());
|
||||
}
|
||||
|
||||
// Check that observers are notified when map is deleted.
|
||||
TEST_EQUAL(0, observer.map_deleted_calls(), ());
|
||||
TEST(index.DeleteMap(testMapName), ());
|
||||
// Try to delete map in presence of active lock. Map should be
|
||||
// marked "to be removed" but can't be deleted.
|
||||
{
|
||||
MwmSet::MwmLock lock(index, testMapName);
|
||||
TEST(lock.IsLocked(), ());
|
||||
|
||||
TEST(!index.DeleteMap(testMapName), ());
|
||||
TEST_EQUAL(0, observer.map_deleted_calls(), ());
|
||||
}
|
||||
|
||||
// Check that observers are notified when lock is destroyed.
|
||||
TEST_EQUAL(1, observer.map_deleted_calls(), ());
|
||||
|
||||
index.RemoveObserver(observer);
|
||||
|
|
|
@ -11,15 +11,15 @@ namespace
|
|||
class TestMwmSet : public MwmSet
|
||||
{
|
||||
protected:
|
||||
virtual bool GetVersion(string const & path, MwmInfo & info,
|
||||
feature::DataHeader::Version & version) const
|
||||
virtual bool GetVersion(string const & path, MwmInfo & info)
|
||||
{
|
||||
int n = path[0] - '0';
|
||||
info.m_maxScale = n;
|
||||
info.m_limitRect = m2::RectD(0, 0, 1, 1);
|
||||
version = feature::DataHeader::lastVersion;
|
||||
info.m_version.format = version::lastFormat;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual MwmValue * CreateValue(string const &) const
|
||||
{
|
||||
return new MwmValue();
|
||||
|
@ -53,8 +53,8 @@ UNIT_TEST(MwmSetSmokeTest)
|
|||
{
|
||||
MwmSet::MwmLock lock0(mwmSet, 0);
|
||||
MwmSet::MwmLock lock1(mwmSet, 1);
|
||||
TEST(lock0.GetValue() != NULL, ());
|
||||
TEST(lock1.GetValue() == NULL, ());
|
||||
TEST(lock0.IsLocked(), ());
|
||||
TEST(!lock1.IsLocked(), ());
|
||||
}
|
||||
|
||||
mwmSet.Register("3");
|
||||
|
@ -69,7 +69,7 @@ UNIT_TEST(MwmSetSmokeTest)
|
|||
|
||||
{
|
||||
MwmSet::MwmLock lock(mwmSet, 1);
|
||||
TEST(lock.GetValue() != NULL, ());
|
||||
TEST(lock.IsLocked(), ());
|
||||
mwmSet.Deregister("3");
|
||||
mwmSet.Register("4");
|
||||
}
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
|
||||
#include "../defines.hpp"
|
||||
|
||||
#include "../base/assert.hpp"
|
||||
#include "../base/logging.hpp"
|
||||
#include "../base/macros.hpp"
|
||||
#include "../base/stl_add.hpp"
|
||||
|
||||
#include "../std/algorithm.hpp"
|
||||
|
||||
// static
|
||||
MwmSet::MwmId const MwmSet::INVALID_MWM_ID = static_cast<MwmSet::MwmId>(-1);
|
||||
|
||||
MwmInfo::MwmInfo() : m_lockCount(0), m_status(STATUS_DEREGISTERED)
|
||||
{
|
||||
// Important: STATUS_DEREGISTERED - is the default value.
|
||||
|
@ -23,17 +26,54 @@ MwmInfo::MwmTypeT MwmInfo::GetType() const
|
|||
return COASTS;
|
||||
}
|
||||
|
||||
MwmSet::MwmLock::MwmLock() : m_mwmSet(nullptr), m_mwmId(MwmSet::INVALID_MWM_ID), m_value(nullptr) {}
|
||||
|
||||
MwmSet::MwmLock::MwmLock(MwmSet & mwmSet, MwmId mwmId)
|
||||
: m_mwmSet(mwmSet), m_id(mwmId), m_pValue(mwmSet.LockValue(mwmId))
|
||||
: m_mwmSet(&mwmSet), m_mwmId(mwmId), m_value(m_mwmSet->LockValue(m_mwmId))
|
||||
{
|
||||
}
|
||||
|
||||
MwmSet::MwmLock::MwmLock(MwmSet & mwmSet, string const & fileName)
|
||||
: m_mwmSet(&mwmSet), m_mwmId(MwmSet::INVALID_MWM_ID), m_value(nullptr)
|
||||
{
|
||||
lock_guard<mutex> lock(m_mwmSet->m_lock);
|
||||
m_mwmId = m_mwmSet->GetIdByName(fileName);
|
||||
if (m_mwmId != MwmSet::INVALID_MWM_ID)
|
||||
m_value = m_mwmSet->LockValueImpl(m_mwmId);
|
||||
}
|
||||
|
||||
MwmSet::MwmLock::MwmLock(MwmSet & mwmSet, MwmId mwmId, MwmValueBase * value)
|
||||
: m_mwmSet(&mwmSet), m_mwmId(mwmId), m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
MwmSet::MwmLock::MwmLock(MwmLock && lock)
|
||||
: m_mwmSet(lock.m_mwmSet), m_mwmId(lock.m_mwmId), m_value(lock.m_value)
|
||||
{
|
||||
lock.m_mwmId = 0;
|
||||
lock.m_mwmId = MwmSet::INVALID_MWM_ID;
|
||||
lock.m_value = 0;
|
||||
}
|
||||
|
||||
MwmSet::MwmLock::~MwmLock()
|
||||
{
|
||||
if (m_pValue)
|
||||
m_mwmSet.UnlockValue(m_id, m_pValue);
|
||||
if (m_mwmSet && m_value)
|
||||
m_mwmSet->UnlockValue(m_mwmId, m_value);
|
||||
}
|
||||
|
||||
MwmInfo const & MwmSet::MwmLock::GetInfo() const
|
||||
{
|
||||
ASSERT(IsLocked(), ("MwmLock is not active."));
|
||||
return m_mwmSet->GetMwmInfo(m_mwmId);
|
||||
}
|
||||
|
||||
MwmSet::MwmLock & MwmSet::MwmLock::operator=(MwmLock && lock)
|
||||
{
|
||||
swap(m_mwmSet, lock.m_mwmSet);
|
||||
swap(m_mwmId, lock.m_mwmId);
|
||||
swap(m_value, lock.m_value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MwmSet::MwmSet(size_t cacheSize)
|
||||
: m_cacheSize(cacheSize)
|
||||
|
@ -102,8 +142,7 @@ MwmSet::MwmId MwmSet::GetIdByName(string const & name)
|
|||
return INVALID_MWM_ID;
|
||||
}
|
||||
|
||||
bool MwmSet::Register(string const & fileName, m2::RectD & rect,
|
||||
feature::DataHeader::Version & version)
|
||||
pair<MwmSet::MwmLock, bool> MwmSet::Register(string const & fileName)
|
||||
{
|
||||
lock_guard<mutex> lock(m_lock);
|
||||
|
||||
|
@ -114,20 +153,18 @@ bool MwmSet::Register(string const & fileName, m2::RectD & rect,
|
|||
LOG(LWARNING, ("Trying to add already registered map", fileName));
|
||||
else
|
||||
m_info[id].SetStatus(MwmInfo::STATUS_UP_TO_DATE);
|
||||
|
||||
return false;
|
||||
return make_pair(GetLock(id), false);
|
||||
}
|
||||
|
||||
return RegisterImpl(fileName, rect, version);
|
||||
return RegisterImpl(fileName);
|
||||
}
|
||||
|
||||
bool MwmSet::RegisterImpl(string const & fileName, m2::RectD & rect,
|
||||
feature::DataHeader::Version & version)
|
||||
pair<MwmSet::MwmLock, bool> MwmSet::RegisterImpl(string const & fileName)
|
||||
{
|
||||
// this function can throw an exception for bad mwm file
|
||||
MwmInfo info;
|
||||
if (!GetVersion(fileName, info, version))
|
||||
return false;
|
||||
if (!GetVersion(fileName, info))
|
||||
return make_pair(MwmLock(), false);
|
||||
|
||||
info.SetStatus(MwmInfo::STATUS_UP_TO_DATE);
|
||||
|
||||
|
@ -135,9 +172,7 @@ bool MwmSet::RegisterImpl(string const & fileName, m2::RectD & rect,
|
|||
m_name[id] = fileName;
|
||||
m_info[id] = info;
|
||||
|
||||
rect = info.m_limitRect;
|
||||
ASSERT(rect.IsValid(), ());
|
||||
return true;
|
||||
return make_pair(GetLock(id), true);
|
||||
}
|
||||
|
||||
bool MwmSet::DeregisterImpl(MwmId id)
|
||||
|
@ -207,10 +242,21 @@ void MwmSet::GetMwmInfo(vector<MwmInfo> & info) const
|
|||
info = m_info;
|
||||
}
|
||||
|
||||
MwmInfo const & MwmSet::GetMwmInfo(MwmId id) const
|
||||
{
|
||||
MwmSet * p = const_cast<MwmSet *>(this);
|
||||
lock_guard<mutex> lock(p->m_lock);
|
||||
return m_info[id];
|
||||
}
|
||||
|
||||
MwmSet::MwmValueBase * MwmSet::LockValue(MwmId id)
|
||||
{
|
||||
lock_guard<mutex> lock(m_lock);
|
||||
return LockValueImpl(id);
|
||||
}
|
||||
|
||||
MwmSet::MwmValueBase * MwmSet::LockValueImpl(MwmId id)
|
||||
{
|
||||
ASSERT_LESS(id, m_info.size(), ());
|
||||
if (id >= m_info.size())
|
||||
return NULL;
|
||||
|
@ -237,7 +283,11 @@ MwmSet::MwmValueBase * MwmSet::LockValue(MwmId id)
|
|||
void MwmSet::UnlockValue(MwmId id, MwmValueBase * p)
|
||||
{
|
||||
lock_guard<mutex> lock(m_lock);
|
||||
UnlockValueImpl(id, p);
|
||||
}
|
||||
|
||||
void MwmSet::UnlockValueImpl(MwmId id, MwmValueBase * p)
|
||||
{
|
||||
ASSERT(p, (id));
|
||||
ASSERT_LESS(id, m_info.size(), ());
|
||||
if (id >= m_info.size() || p == 0)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "data_header.hpp"
|
||||
#include "mwm_version.hpp"
|
||||
|
||||
#include "../geometry/rect2d.hpp"
|
||||
|
||||
#include "../base/macros.hpp"
|
||||
|
||||
#include "../std/deque.hpp"
|
||||
#include "../std/mutex.hpp"
|
||||
#include "../std/string.hpp"
|
||||
|
@ -31,10 +33,11 @@ public:
|
|||
|
||||
MwmInfo();
|
||||
|
||||
m2::RectD m_limitRect; ///< Limit rect of mwm.
|
||||
uint8_t m_minScale; ///< Min zoom level of mwm.
|
||||
uint8_t m_maxScale; ///< Max zoom level of mwm.
|
||||
uint8_t m_lockCount; ///< Number of locks.
|
||||
m2::RectD m_limitRect; ///< Limit rect of mwm.
|
||||
uint8_t m_minScale; ///< Min zoom level of mwm.
|
||||
uint8_t m_maxScale; ///< Max zoom level of mwm.
|
||||
uint8_t m_lockCount; ///< Number of locks.
|
||||
version::MwmVersion m_version; ///< Mwm file version.
|
||||
|
||||
inline bool IsRegistered() const
|
||||
{
|
||||
|
@ -58,6 +61,8 @@ class MwmSet
|
|||
public:
|
||||
typedef size_t MwmId;
|
||||
|
||||
static const MwmId INVALID_MWM_ID;
|
||||
|
||||
explicit MwmSet(size_t cacheSize = 5);
|
||||
virtual ~MwmSet() = 0;
|
||||
|
||||
|
@ -71,42 +76,54 @@ public:
|
|||
class MwmLock
|
||||
{
|
||||
public:
|
||||
MwmLock();
|
||||
MwmLock(MwmSet & mwmSet, MwmId mwmId);
|
||||
~MwmLock();
|
||||
MwmLock(MwmSet & mwmSet, string const & fileName);
|
||||
MwmLock(MwmLock && lock);
|
||||
virtual ~MwmLock();
|
||||
|
||||
inline MwmValueBase * GetValue() const { return m_pValue; }
|
||||
inline MwmId GetID() const { return m_id; }
|
||||
template <typename T>
|
||||
inline T * GetValue() const
|
||||
{
|
||||
return static_cast<T *>(m_value);
|
||||
}
|
||||
inline bool IsLocked() const { return m_value; }
|
||||
inline MwmId GetId() const { return m_mwmId; }
|
||||
MwmInfo const & GetInfo() const;
|
||||
|
||||
MwmLock & operator=(MwmLock && lock);
|
||||
|
||||
private:
|
||||
MwmSet & m_mwmSet;
|
||||
MwmId m_id;
|
||||
MwmValueBase * m_pValue;
|
||||
friend class MwmSet;
|
||||
|
||||
MwmLock(MwmSet & mwmSet, MwmId mwmId, MwmValueBase * value);
|
||||
|
||||
MwmSet * m_mwmSet;
|
||||
MwmId m_mwmId;
|
||||
MwmValueBase * m_value;
|
||||
|
||||
NONCOPYABLE(MwmLock);
|
||||
};
|
||||
|
||||
/// Registers new map in the set.
|
||||
/// @param[in] fileName File name (without full path) of country.
|
||||
/// @param[out] rect Limit rect of country.
|
||||
/// @param[out] version Version of the file.
|
||||
///
|
||||
/// @return True when map is registered, false otherwise - map already
|
||||
/// exists or it's not possible to get mwm's version.
|
||||
/// \param fileName File name (without full path) of country.
|
||||
///
|
||||
/// \return A pair of MwmLock and a flag. MwmLock is locked iff map
|
||||
/// with fileName was created or already exists. Flag is
|
||||
/// set when a new map was registered. Thus, there are
|
||||
/// three main cases:
|
||||
/// * map already exists - returns active lock and unset flag
|
||||
/// * a new map was registered - returns active lock and set flag
|
||||
/// * can't register new map - returns inactive lock and unset flag
|
||||
//@{
|
||||
protected:
|
||||
bool RegisterImpl(string const & fileName, m2::RectD & rect,
|
||||
feature::DataHeader::Version & version);
|
||||
WARN_UNUSED_RESULT pair<MwmLock, bool> RegisterImpl(string const & fileName);
|
||||
|
||||
public:
|
||||
bool Register(string const & fileName, m2::RectD & rect, feature::DataHeader::Version & version);
|
||||
WARN_UNUSED_RESULT pair<MwmLock, bool> Register(string const & fileName);
|
||||
//@}
|
||||
|
||||
/// Used in unit tests only.
|
||||
inline void Register(string const & fileName)
|
||||
{
|
||||
m2::RectD dummyRect;
|
||||
feature::DataHeader::Version dummyVersion;
|
||||
CHECK(Register(fileName, dummyRect, dummyVersion), ());
|
||||
}
|
||||
|
||||
/// @name Remove mwm.
|
||||
//@{
|
||||
protected:
|
||||
|
@ -130,14 +147,17 @@ public:
|
|||
/// In that case, LockValue returns NULL.
|
||||
void GetMwmInfo(vector<MwmInfo> & info) const;
|
||||
|
||||
/// \return A reference to an MwmInfo corresponding to id. Id must
|
||||
/// be a valid Mwm id.
|
||||
MwmInfo const & GetMwmInfo(MwmId id) const;
|
||||
|
||||
// Clear caches.
|
||||
void ClearCache();
|
||||
|
||||
protected:
|
||||
/// @return True when it's possible to get file format version - in
|
||||
/// this case version is set to the file format version.
|
||||
virtual bool GetVersion(string const & name, MwmInfo & info,
|
||||
feature::DataHeader::Version & version) const = 0;
|
||||
virtual bool GetVersion(string const & name, MwmInfo & info) = 0;
|
||||
virtual MwmValueBase * CreateValue(string const & name) const = 0;
|
||||
|
||||
void Cleanup();
|
||||
|
@ -146,7 +166,9 @@ private:
|
|||
typedef deque<pair<MwmId, MwmValueBase *> > CacheType;
|
||||
|
||||
MwmValueBase * LockValue(MwmId id);
|
||||
MwmValueBase * LockValueImpl(MwmId id);
|
||||
void UnlockValue(MwmId id, MwmValueBase * p);
|
||||
void UnlockValueImpl(MwmId id, MwmValueBase * p);
|
||||
|
||||
/// Find first removed mwm or add a new one.
|
||||
/// @precondition This function is always called under mutex m_lock.
|
||||
|
@ -160,8 +182,6 @@ private:
|
|||
size_t m_cacheSize;
|
||||
|
||||
protected:
|
||||
static const MwmId INVALID_MWM_ID = static_cast<MwmId>(-1);
|
||||
|
||||
/// Find mwm with a given name.
|
||||
/// @precondition This function is always called under mutex m_lock.
|
||||
MwmId GetIdByName(string const & name);
|
||||
|
@ -169,6 +189,12 @@ protected:
|
|||
/// @precondition This function is always called under mutex m_lock.
|
||||
void ClearCache(MwmId id);
|
||||
|
||||
/// @precondition This function is always called under mutex m_lock.
|
||||
WARN_UNUSED_RESULT inline MwmLock GetLock(MwmId id)
|
||||
{
|
||||
return MwmLock(*this, id, LockValueImpl(id));
|
||||
}
|
||||
|
||||
/// Update given MwmInfo.
|
||||
/// @precondition This function is always called under mutex m_lock.
|
||||
virtual void UpdateMwmInfo(MwmId id);
|
||||
|
|
|
@ -1,54 +1,79 @@
|
|||
#include "mwm_version.hpp"
|
||||
#include "data_header.hpp"
|
||||
|
||||
#include "../coding/file_container.hpp"
|
||||
#include "../coding/reader_wrapper.hpp"
|
||||
#include "../coding/varint.hpp"
|
||||
#include "../coding/writer.hpp"
|
||||
#include "../coding/reader_wrapper.hpp"
|
||||
|
||||
#include "../base/logging.hpp"
|
||||
#include "../base/timer.hpp"
|
||||
|
||||
#include "../defines.hpp"
|
||||
|
||||
namespace ver {
|
||||
#include "../std/ctime.hpp"
|
||||
|
||||
namespace version
|
||||
{
|
||||
namespace
|
||||
{
|
||||
typedef feature::DataHeader FHeaderT;
|
||||
|
||||
char MWM_PROLOG[] = "MWM";
|
||||
char const MWM_PROLOG[] = "MWM";
|
||||
|
||||
void WriteVersion(Writer & w)
|
||||
{
|
||||
w.Write(MWM_PROLOG, ARRAY_SIZE(MWM_PROLOG));
|
||||
|
||||
// write inner data version
|
||||
WriteVarUint(w, static_cast<uint32_t>(FHeaderT::lastVersion));
|
||||
|
||||
// static is used for equal time stamp for all "mwm" files in one generation process
|
||||
static uint32_t generatorStartTime = my::TodayAsYYMMDD();
|
||||
WriteVarUint(w, generatorStartTime);
|
||||
}
|
||||
|
||||
template <class TSource> uint32_t ReadVersionT(TSource & src)
|
||||
template <class TSource>
|
||||
void ReadVersionT(TSource & src, MwmVersion & version)
|
||||
{
|
||||
size_t const prologSize = ARRAY_SIZE(MWM_PROLOG);
|
||||
char prolog[prologSize];
|
||||
src.Read(prolog, prologSize);
|
||||
|
||||
if (strcmp(prolog, MWM_PROLOG) != 0)
|
||||
return FHeaderT::v2;
|
||||
{
|
||||
version.format = v2;
|
||||
version.timestamp =
|
||||
my::GenerateTimestamp(2011 - 1900 /* number of years since 1900 */,
|
||||
10 /* number of month since January */, 1 /* month day */);
|
||||
return;
|
||||
}
|
||||
|
||||
return ReadVarUint<uint32_t>(src);
|
||||
uint32_t formatIndex = ReadVarUint<uint32_t>(src);
|
||||
if (formatIndex > lastFormat)
|
||||
{
|
||||
LOG(LERROR, ("Unknown file format index:", formatIndex));
|
||||
formatIndex = lastFormat;
|
||||
}
|
||||
version.format = static_cast<Format>(formatIndex);
|
||||
version.timestamp = ReadVarUint<uint32_t>(src);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
uint32_t ReadVersion(ModelReaderPtr const & r)
|
||||
MwmVersion::MwmVersion() : format(unknownFormat), timestamp(0) {}
|
||||
|
||||
void WriteVersion(Writer & w)
|
||||
{
|
||||
ReaderSource<ModelReaderPtr> src(r);
|
||||
return ReadVersionT(src);
|
||||
w.Write(MWM_PROLOG, ARRAY_SIZE(MWM_PROLOG));
|
||||
|
||||
// write inner data version
|
||||
WriteVarUint(w, static_cast<uint32_t>(lastFormat));
|
||||
|
||||
// static is used for equal time stamp for all "mwm" files in one generation process
|
||||
static uint32_t generatorStartTime = my::TodayAsYYMMDD();
|
||||
WriteVarUint(w, generatorStartTime);
|
||||
}
|
||||
|
||||
uint32_t ReadTimestamp(ReaderSrc & src)
|
||||
void ReadVersion(ReaderSrc & src, MwmVersion & version)
|
||||
{
|
||||
(void)ReadVersionT(src);
|
||||
|
||||
return ReadVarUint<uint32_t>(src);
|
||||
ReadVersionT(src, version);
|
||||
}
|
||||
|
||||
bool ReadVersion(FilesContainerR const & container, MwmVersion & version)
|
||||
{
|
||||
if (!container.IsExist(VERSION_FILE_TAG))
|
||||
return false;
|
||||
ModelReaderPtr versionReader = container.GetReader(VERSION_FILE_TAG);
|
||||
ReaderSource<ModelReaderPtr> src(versionReader);
|
||||
ReadVersionT(src, version);
|
||||
return true;
|
||||
}
|
||||
} // namespace version
|
||||
|
|
|
@ -2,18 +2,36 @@
|
|||
|
||||
#include "../std/stdint.hpp"
|
||||
|
||||
|
||||
class ModelReaderPtr;
|
||||
class Writer;
|
||||
class FilesContainerR;
|
||||
class ReaderSrc;
|
||||
class Writer;
|
||||
|
||||
namespace ver
|
||||
namespace version
|
||||
{
|
||||
void WriteVersion(Writer & w);
|
||||
enum Format
|
||||
{
|
||||
unknownFormat = -1,
|
||||
v1 = 0, // April 2011
|
||||
v2, // November 2011 (store type index, instead of raw type in mwm)
|
||||
v3, // March 2013 (store type index, instead of raw type in search data)
|
||||
lastFormat = v3
|
||||
};
|
||||
|
||||
/// @return See feature::DataHeader::Version for more details.
|
||||
uint32_t ReadVersion(ModelReaderPtr const & r);
|
||||
struct MwmVersion {
|
||||
MwmVersion();
|
||||
|
||||
/// @return Data timestamp in yymmdd format.
|
||||
uint32_t ReadTimestamp(ReaderSrc & src);
|
||||
}
|
||||
Format format;
|
||||
uint32_t timestamp;
|
||||
};
|
||||
|
||||
/// Writes latest format and current timestamp to the writer.
|
||||
void WriteVersion(Writer & w);
|
||||
|
||||
/// Reads mwm version from src.
|
||||
void ReadVersion(ReaderSrc & src, MwmVersion & version);
|
||||
|
||||
/// \return True when version was successfully parsed from container,
|
||||
/// otherwise returns false. In the latter case version is
|
||||
/// unchanged.
|
||||
bool ReadVersion(FilesContainerR const & container, MwmVersion & version);
|
||||
} // namespace version
|
||||
|
|
|
@ -383,7 +383,7 @@ void AddFeatureNameIndexPairs(FilesContainerR const & container,
|
|||
StringsFile<FeatureIndexValue> & stringsFile)
|
||||
{
|
||||
feature::DataHeader header;
|
||||
header.Load(container.GetReader(HEADER_FILE_TAG));
|
||||
header.Load(container.GetReader(HEADER_FILE_TAG), version::unknownFormat);
|
||||
FeaturesVector features(container, header);
|
||||
|
||||
ValueBuilder<FeatureIndexValue> valueBuilder;
|
||||
|
@ -404,7 +404,7 @@ void BuildSearchIndex(FilesContainerR const & cont, CategoriesHolder const & cat
|
|||
{
|
||||
{
|
||||
feature::DataHeader header;
|
||||
header.Load(cont.GetReader(HEADER_FILE_TAG));
|
||||
header.Load(cont.GetReader(HEADER_FILE_TAG), version::unknownFormat);
|
||||
FeaturesVector featuresV(cont, header);
|
||||
|
||||
serial::CodingParams cp(search::GetCPForTrie(header.GetDefCodingParams()));
|
||||
|
|
|
@ -133,9 +133,8 @@ void BenchmarkEngine::PrepareMaps()
|
|||
// add only maps needed for benchmarks
|
||||
MapsCollector collector;
|
||||
ForEachBenchmarkRecord(collector);
|
||||
feature::DataHeader::Version version;
|
||||
for_each(collector.m_maps.begin(), collector.m_maps.end(),
|
||||
bind(&Framework::RegisterMap, m_framework, _1, version));
|
||||
bind(&Framework::RegisterMap, m_framework, _1));
|
||||
}
|
||||
|
||||
BenchmarkEngine::BenchmarkEngine(Framework * fw)
|
||||
|
|
|
@ -110,8 +110,7 @@ void RunFeaturesLoadingBenchmark(string const & file, pair<int, int> scaleR, All
|
|||
return;
|
||||
|
||||
model::FeaturesFetcher src;
|
||||
feature::DataHeader::Version version;
|
||||
src.RegisterMap(file, version);
|
||||
src.RegisterMap(file);
|
||||
|
||||
RunBenchmark(src, header.GetBounds(), scaleR, res);
|
||||
}
|
||||
|
|
|
@ -32,24 +32,27 @@ void FeaturesFetcher::InitClassificator()
|
|||
}
|
||||
}
|
||||
|
||||
bool FeaturesFetcher::RegisterMap(string const & file, feature::DataHeader::Version & version)
|
||||
pair<MwmSet::MwmLock, bool> FeaturesFetcher::RegisterMap(string const & file)
|
||||
{
|
||||
try
|
||||
{
|
||||
m2::RectD r;
|
||||
if (!m_multiIndex.RegisterMap(file, r, version))
|
||||
pair<MwmSet::MwmLock, bool> p = m_multiIndex.RegisterMap(file);
|
||||
if (!p.second)
|
||||
{
|
||||
LOG(LWARNING,
|
||||
("Can't add map", file, "Probably it's already added or has newer data version."));
|
||||
return false;
|
||||
return p;
|
||||
}
|
||||
m_rect.Add(r);
|
||||
return true;
|
||||
MwmSet::MwmLock & lock = p.first;
|
||||
if (!lock.IsLocked())
|
||||
return p;
|
||||
m_rect.Add(lock.GetInfo().m_limitRect);
|
||||
return p;
|
||||
}
|
||||
catch (RootException const & e)
|
||||
{
|
||||
LOG(LERROR, ("IO error while adding ", file, " map. ", e.what()));
|
||||
return false;
|
||||
return make_pair(MwmSet::MwmLock(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,10 +65,9 @@ bool FeaturesFetcher::DeleteMap(string const & file)
|
|||
return m_multiIndex.DeleteMap(file);
|
||||
}
|
||||
|
||||
bool FeaturesFetcher::UpdateMap(string const & file, m2::RectD & rect)
|
||||
pair<MwmSet::MwmLock, Index::UpdateStatus> FeaturesFetcher::UpdateMap(string const & file)
|
||||
{
|
||||
feature::DataHeader::Version version;
|
||||
return m_multiIndex.UpdateMap(file, rect, version);
|
||||
return m_multiIndex.UpdateMap(file);
|
||||
}
|
||||
|
||||
//void FeaturesFetcher::Clean()
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "../coding/reader.hpp"
|
||||
#include "../coding/buffer_reader.hpp"
|
||||
|
||||
#include "../base/macros.hpp"
|
||||
|
||||
namespace model
|
||||
{
|
||||
//#define USE_BUFFER_READER
|
||||
|
@ -30,11 +32,16 @@ namespace model
|
|||
public:
|
||||
void InitClassificator();
|
||||
|
||||
/// @param[in] file Name of mwm file with extension.
|
||||
//{@
|
||||
/// @return True when map was successfully registered, also, sets
|
||||
/// version to the file format version.
|
||||
bool RegisterMap(string const & file, feature::DataHeader::Version & version);
|
||||
/// Registers new map.
|
||||
///
|
||||
/// \return A pair of MwmLock and a flag. MwmLock is locked iff map
|
||||
/// with fileName was created or already exists. Flag is
|
||||
/// set when a new map was registered. Thus, there are
|
||||
/// three main cases:
|
||||
/// * map already exists - returns active lock and unset flag
|
||||
/// * a new map was registered - returns active lock and set flag
|
||||
/// * can't register new map - returns inactive lock and unset flag
|
||||
WARN_UNUSED_RESULT pair<MwmSet::MwmLock, bool> RegisterMap(string const & file);
|
||||
|
||||
/// Deregisters map denoted by file from internal records.
|
||||
void DeregisterMap(string const & file);
|
||||
|
@ -47,12 +54,17 @@ namespace model
|
|||
/// \return True if map was successfully deleted.
|
||||
bool DeleteMap(string const & file);
|
||||
|
||||
/// Tries to update map denoted by file. If map is used right now,
|
||||
/// update will be delayed.
|
||||
/// Replaces map file corresponding to fileName with a new one, when
|
||||
/// it's possible - no clients of the map file. Otherwise, update
|
||||
/// will be delayed.
|
||||
///
|
||||
/// \return True when map was successfully updated, false when update
|
||||
/// was delayed or when update's version is not good.
|
||||
bool UpdateMap(string const & file, m2::RectD & rect);
|
||||
/// \return * map file have been updated - returns active lock and
|
||||
/// UPDATE_STATUS_OK
|
||||
/// * update is delayed because map is busy - returns active lock and
|
||||
/// UPDATE_STATUS_UPDATE_DELAYED
|
||||
/// * file isn't suitable for update - returns inactive lock and
|
||||
/// UPDATE_STATUS_BAD_FILE
|
||||
WARN_UNUSED_RESULT pair<MwmSet::MwmLock, Index::UpdateStatus> UpdateMap(string const & file);
|
||||
//@}
|
||||
|
||||
//void Clean();
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "../indexer/categories_holder.hpp"
|
||||
#include "../indexer/feature.hpp"
|
||||
#include "../indexer/mwm_version.hpp"
|
||||
#include "../indexer/scales.hpp"
|
||||
#include "../indexer/classificator_loader.hpp"
|
||||
|
||||
|
@ -84,26 +85,29 @@ namespace
|
|||
static const int BM_TOUCH_PIXEL_INCREASE = 20;
|
||||
}
|
||||
|
||||
bool Framework::RegisterMap(string const & file, feature::DataHeader::Version & version)
|
||||
pair<MwmSet::MwmLock, bool> Framework::RegisterMap(string const & file)
|
||||
{
|
||||
LOG(LINFO, ("Loading map:", file));
|
||||
|
||||
if (!m_model.RegisterMap(file, version))
|
||||
return false;
|
||||
pair<MwmSet::MwmLock, bool> p = m_model.RegisterMap(file);
|
||||
if (!p.second)
|
||||
return p;
|
||||
MwmSet::MwmLock & lock = p.first;
|
||||
ASSERT(lock.IsLocked(), ());
|
||||
|
||||
if (version == feature::DataHeader::v1)
|
||||
MwmInfo const & info = lock.GetInfo();
|
||||
|
||||
if (info.m_version.format == version::v1)
|
||||
{
|
||||
// Now we do force delete of old (April 2011) maps.
|
||||
LOG(LINFO, ("Deleting old map:", file));
|
||||
|
||||
DeregisterMap(file);
|
||||
VERIFY(my::DeleteFileX(GetPlatform().WritablePathForFile(file)), ());
|
||||
|
||||
version = feature::DataHeader::unknownVersion;
|
||||
return false;
|
||||
return make_pair(MwmSet::MwmLock(), false);
|
||||
}
|
||||
|
||||
return true;
|
||||
return p;
|
||||
}
|
||||
|
||||
void Framework::DeregisterMap(string const & file) { m_model.DeregisterMap(file); }
|
||||
|
@ -379,9 +383,12 @@ void Framework::UpdateAfterDownload(string const & fileName, TMapOptions opt)
|
|||
}
|
||||
|
||||
// Add downloaded map.
|
||||
m2::RectD rect;
|
||||
if (m_model.UpdateMap(fileName, rect))
|
||||
InvalidateRect(rect, true);
|
||||
pair<MwmSet::MwmLock, Index::UpdateStatus> p = m_model.UpdateMap(fileName);
|
||||
if (p.second == Index::UPDATE_STATUS_OK) {
|
||||
MwmSet::MwmLock & lock = p.first;
|
||||
ASSERT(lock.IsLocked(), ());
|
||||
InvalidateRect(lock.GetInfo().m_limitRect, true);
|
||||
}
|
||||
|
||||
GetSearchEngine()->ClearViewportsCache();
|
||||
}
|
||||
|
@ -411,14 +418,18 @@ void Framework::RegisterAllMaps()
|
|||
GetMaps(maps);
|
||||
for_each(maps.begin(), maps.end(), [&](string const & file)
|
||||
{
|
||||
feature::DataHeader::Version version;
|
||||
if (RegisterMap(file, version) && version < minVersion)
|
||||
minVersion = version;
|
||||
pair<MwmSet::MwmLock, bool> p = RegisterMap(file);
|
||||
if (p.second)
|
||||
{
|
||||
MwmSet::MwmLock & lock = p.first;
|
||||
ASSERT(lock.IsLocked(), ());
|
||||
minVersion = min(minVersion, static_cast<int>(lock.GetInfo().m_version.format));
|
||||
}
|
||||
});
|
||||
|
||||
m_countryTree.Init(maps);
|
||||
|
||||
GetSearchEngine()->SupportOldFormat(minVersion < feature::DataHeader::v3);
|
||||
GetSearchEngine()->SupportOldFormat(minVersion < version::v3);
|
||||
}
|
||||
|
||||
void Framework::DeregisterAllMaps()
|
||||
|
|
|
@ -174,7 +174,7 @@ public:
|
|||
///
|
||||
/// @return True and inner mwm data version from header in version
|
||||
/// or false in case of errors.
|
||||
bool RegisterMap(string const & file, feature::DataHeader::Version & version);
|
||||
pair<MwmSet::MwmLock, bool> RegisterMap(string const & file);
|
||||
//@}
|
||||
|
||||
/// Deletes all disk files corresponding to country.
|
||||
|
|
|
@ -400,9 +400,7 @@ UNIT_TEST(Bookmarks_AddressInfo)
|
|||
// Maps added in constructor (we need minsk-pass.mwm only)
|
||||
Framework fm;
|
||||
fm.DeregisterAllMaps();
|
||||
feature::DataHeader::Version version;
|
||||
fm.RegisterMap("minsk-pass.mwm", version);
|
||||
|
||||
fm.RegisterMap("minsk-pass.mwm");
|
||||
fm.OnSize(800, 600);
|
||||
|
||||
// assume that developers have English or Russian system language :)
|
||||
|
|
|
@ -63,8 +63,7 @@ namespace
|
|||
SourceT src;
|
||||
src.InitClassificator();
|
||||
|
||||
feature::DataHeader::Version version;
|
||||
src.RegisterMap(file + DATA_FILE_EXTENSION, version);
|
||||
src.RegisterMap(file + DATA_FILE_EXTENSION);
|
||||
|
||||
// Check that country rect is valid and not infinity.
|
||||
m2::RectD const r = src.GetWorldRect();
|
||||
|
|
|
@ -251,8 +251,7 @@ void RunTest(string const & file)
|
|||
model::FeaturesFetcher src1;
|
||||
src1.InitClassificator();
|
||||
|
||||
feature::DataHeader::Version version;
|
||||
src1.RegisterMap(file, version);
|
||||
src1.RegisterMap(file);
|
||||
|
||||
vector<m2::RectD> rects;
|
||||
rects.push_back(src1.GetWorldRect());
|
||||
|
|
|
@ -39,8 +39,14 @@ public:
|
|||
bool RunTest(string const & fileName, int lowS, int highS)
|
||||
{
|
||||
model::FeaturesFetcher src;
|
||||
feature::DataHeader::Version version;
|
||||
if (!src.RegisterMap(fileName, version) || version == feature::DataHeader::unknownVersion)
|
||||
pair<MwmSet::MwmLock, bool> p = src.RegisterMap(fileName);
|
||||
if (!p.second)
|
||||
return false;
|
||||
MwmSet::MwmLock & lock = p.first;
|
||||
ASSERT(lock.IsLocked(), ());
|
||||
|
||||
version::Format version = lock.GetInfo().m_version.format;
|
||||
if (version == version::unknownFormat)
|
||||
return false;
|
||||
|
||||
CheckNonEmptyGeometry doCheck;
|
||||
|
|
|
@ -40,7 +40,13 @@ RoutingMapping::RoutingMapping(string const & fName, Index const * pIndex)
|
|||
ModelReaderPtr r2 = FilesContainerR(pl.GetReader(mwmName)).GetReader(VERSION_FILE_TAG);
|
||||
ReaderSrc src2(r2.GetPtr());
|
||||
|
||||
if (ver::ReadTimestamp(src1) != ver::ReadTimestamp(src2))
|
||||
version::MwmVersion version1;
|
||||
version::ReadVersion(src1, version1);
|
||||
|
||||
version::MwmVersion version2;
|
||||
version::ReadVersion(src2, version2);
|
||||
|
||||
if (version1.timestamp != version2.timestamp)
|
||||
{
|
||||
m_container.Close();
|
||||
m_isValid = false;
|
||||
|
|
|
@ -218,7 +218,7 @@ FeatureLoader::~FeatureLoader()
|
|||
|
||||
void FeatureLoader::CreateLoader(size_t mwmID)
|
||||
{
|
||||
if (m_pGuard == 0 || mwmID != m_pGuard->GetID())
|
||||
if (m_pGuard == 0 || mwmID != m_pGuard->GetId())
|
||||
{
|
||||
delete m_pGuard;
|
||||
m_pGuard = new Index::FeaturesLoaderGuard(*m_pIndex, mwmID);
|
||||
|
|
|
@ -126,8 +126,8 @@ void LocalityFinder::RecreateCache(Cache & cache, m2::RectD rect) const
|
|||
for (MwmSet::MwmId mwmId = 0; mwmId < mwmInfo.size(); ++mwmId)
|
||||
{
|
||||
typedef feature::DataHeader HeaderT;
|
||||
Index::MwmLock mwmLock(*m_pIndex, mwmId);
|
||||
MwmValue * pMwm = mwmLock.GetValue();
|
||||
Index::MwmLock mwmLock(const_cast<Index &>(*m_pIndex), mwmId);
|
||||
MwmValue * pMwm = mwmLock.GetValue<MwmValue>();
|
||||
if (pMwm && pMwm->GetHeader().GetType() == HeaderT::world)
|
||||
{
|
||||
HeaderT const & header = pMwm->GetHeader();
|
||||
|
|
|
@ -263,8 +263,8 @@ void Query::UpdateViewportOffsets(MWMVectorT const & mwmInfo, m2::RectD const &
|
|||
// Search only mwms that intersect with viewport (world always does).
|
||||
if (rect.IsIntersect(mwmInfo[mwmId].m_limitRect))
|
||||
{
|
||||
Index::MwmLock mwmLock(*m_pIndex, mwmId);
|
||||
if (MwmValue * pMwm = mwmLock.GetValue())
|
||||
Index::MwmLock mwmLock(const_cast<Index &>(*m_pIndex), mwmId);
|
||||
if (MwmValue * pMwm = mwmLock.GetValue<MwmValue>())
|
||||
{
|
||||
FHeaderT const & header = pMwm->GetHeader();
|
||||
if (header.GetType() == FHeaderT::country)
|
||||
|
@ -575,7 +575,7 @@ namespace impl
|
|||
// For the best performance, incoming id's should be sorted by id.first (mwm file id).
|
||||
void LoadFeature(FeatureID const & id, FeatureType & f, string & name, string & country)
|
||||
{
|
||||
if (m_pFV.get() == 0 || m_pFV->GetID() != id.m_mwm)
|
||||
if (m_pFV.get() == 0 || m_pFV->GetId() != id.m_mwm)
|
||||
m_pFV.reset(new Index::FeaturesLoaderGuard(*m_query.m_pIndex, id.m_mwm));
|
||||
|
||||
m_pFV->GetFeature(id.m_offset, f);
|
||||
|
@ -1613,8 +1613,8 @@ void Query::SearchAddress(Results & res)
|
|||
|
||||
for (MwmSet::MwmId mwmId = 0; mwmId < mwmInfo.size(); ++mwmId)
|
||||
{
|
||||
Index::MwmLock mwmLock(*m_pIndex, mwmId);
|
||||
MwmValue * pMwm = mwmLock.GetValue();
|
||||
Index::MwmLock mwmLock(const_cast<Index &>(*m_pIndex), mwmId);
|
||||
MwmValue * pMwm = mwmLock.GetValue<MwmValue>();
|
||||
if (pMwm &&
|
||||
pMwm->m_cont.IsExist(SEARCH_INDEX_FILE_TAG) &&
|
||||
pMwm->GetHeader().GetType() == FHeaderT::world)
|
||||
|
@ -1666,8 +1666,11 @@ void Query::SearchAddress(Results & res)
|
|||
{
|
||||
for (MwmSet::MwmId id = 0; id < mwmInfo.size(); ++id)
|
||||
{
|
||||
Index::MwmLock mwmLock(*m_pIndex, id);
|
||||
if (m_pInfoGetter->IsBelongToRegion(mwmLock.GetFileName(), region.m_ids))
|
||||
Index::MwmLock mwmLock(const_cast<Index &>(*m_pIndex), id);
|
||||
string fileName;
|
||||
if (mwmLock.IsLocked())
|
||||
fileName = mwmLock.GetValue<MwmValue>()->GetFileName();
|
||||
if (m_pInfoGetter->IsBelongToRegion(fileName, region.m_ids))
|
||||
SearchInMWM(mwmLock, params);
|
||||
}
|
||||
}
|
||||
|
@ -2026,7 +2029,7 @@ void Query::SearchFeatures(Params const & params, MWMVectorT const & mwmInfo, Vi
|
|||
// Search only mwms that intersect with viewport (world always does).
|
||||
if (m_viewport[vID].IsIntersect(mwmInfo[mwmId].m_limitRect))
|
||||
{
|
||||
Index::MwmLock mwmLock(*m_pIndex, mwmId);
|
||||
Index::MwmLock mwmLock(const_cast<Index &>(*m_pIndex), mwmId);
|
||||
SearchInMWM(mwmLock, params, vID);
|
||||
}
|
||||
}
|
||||
|
@ -2067,7 +2070,7 @@ void FillCategories(Query::Params const & params, TrieIterator const * pTrieRoot
|
|||
void Query::SearchInMWM(Index::MwmLock const & mwmLock, Params const & params,
|
||||
ViewportID vID /*= DEFAULT_V*/)
|
||||
{
|
||||
if (MwmValue * pMwm = mwmLock.GetValue())
|
||||
if (MwmValue * pMwm = mwmLock.GetValue<MwmValue>())
|
||||
{
|
||||
if (pMwm->m_cont.IsExist(SEARCH_INDEX_FILE_TAG))
|
||||
{
|
||||
|
@ -2086,7 +2089,7 @@ void Query::SearchInMWM(Index::MwmLock const & mwmLock, Params const & params,
|
|||
trie::ValueReader(cp),
|
||||
trie::EdgeValueReader()));
|
||||
|
||||
MwmSet::MwmId const mwmId = mwmLock.GetID();
|
||||
MwmSet::MwmId const mwmId = mwmLock.GetId();
|
||||
FeaturesFilter filter((vID == DEFAULT_V || isWorld) ? 0 : &m_offsetsInViewport[vID][mwmId], m_cancel);
|
||||
|
||||
// Get categories for each token separately - find needed edge with categories.
|
||||
|
@ -2270,10 +2273,11 @@ void Query::SearchAdditional(Results & res, bool nearMe, bool inViewport, size_t
|
|||
|
||||
for (MwmSet::MwmId mwmId = 0; mwmId < mwmInfo.size(); ++mwmId)
|
||||
{
|
||||
Index::MwmLock mwmLock(*m_pIndex, mwmId);
|
||||
string const s = mwmLock.GetFileName();
|
||||
|
||||
if (s == name[0] || s == name[1])
|
||||
Index::MwmLock mwmLock(const_cast<Index &>(*m_pIndex), mwmId);
|
||||
string fileName;
|
||||
if (mwmLock.IsLocked())
|
||||
fileName = mwmLock.GetValue<MwmValue>()->GetFileName();
|
||||
if (fileName == name[0] || fileName == name[1])
|
||||
SearchInMWM(mwmLock, params);
|
||||
}
|
||||
|
||||
|
|
|
@ -183,9 +183,9 @@ UNIT_TEST(HS_StreetsMerge)
|
|||
classificator::Load();
|
||||
|
||||
Index index;
|
||||
m2::RectD rect;
|
||||
feature::DataHeader::Version version;
|
||||
TEST(index.Register("minsk-pass.mwm", rect, version), ());
|
||||
pair<MwmSet::MwmLock, bool> p = index.Register("minsk-pass.mwm");
|
||||
TEST(p.first.IsLocked(), ());
|
||||
TEST(p.second, ());
|
||||
|
||||
{
|
||||
search::HouseDetector houser(&index);
|
||||
|
@ -272,9 +272,9 @@ UNIT_TEST(HS_FindHouseSmoke)
|
|||
classificator::Load();
|
||||
|
||||
Index index;
|
||||
m2::RectD rect;
|
||||
feature::DataHeader::Version version;
|
||||
index.Register("minsk-pass.mwm", rect, version);
|
||||
pair<MwmSet::MwmLock, bool> p = index.Register("minsk-pass.mwm");
|
||||
TEST(p.first.IsLocked(), ());
|
||||
TEST(p.second, ());
|
||||
|
||||
{
|
||||
vector<string> streetName(1, "Московская улица");
|
||||
|
@ -375,13 +375,13 @@ UNIT_TEST(HS_MWMSearch)
|
|||
}
|
||||
|
||||
Index index;
|
||||
m2::RectD rect;
|
||||
feature::DataHeader::Version version;
|
||||
if (!index.Register(country + ".mwm", rect, version))
|
||||
pair<MwmSet::MwmLock, bool> p = index.Register(country + ".mwm");
|
||||
if (!p.second)
|
||||
{
|
||||
LOG(LWARNING, ("MWM file not found"));
|
||||
return;
|
||||
}
|
||||
TEST(p.first.IsLocked(), ());
|
||||
|
||||
CollectStreetIDs streetIDs;
|
||||
index.ForEachInScale(streetIDs, scales::GetUpperScale());
|
||||
|
|
|
@ -34,9 +34,12 @@ void doTests2(search::LocalityFinder & finder, vector<m2::PointD> const & input,
|
|||
UNIT_TEST(LocalityFinder)
|
||||
{
|
||||
Index index;
|
||||
m2::RectD rect;
|
||||
feature::DataHeader::Version version;
|
||||
TEST(index.Register("World.mwm", rect, version), ());
|
||||
pair<MwmSet::MwmLock, bool> p = index.Register("World.mwm");
|
||||
TEST(p.second, ());
|
||||
MwmSet::MwmLock & lock = p.first;
|
||||
TEST(lock.IsLocked(), ());
|
||||
MwmInfo const & info = index.GetMwmInfo(lock.GetId());
|
||||
m2::RectD const & rect = info.m_limitRect;
|
||||
|
||||
search::LocalityFinder finder(&index);
|
||||
finder.SetLanguage(StringUtf8Multilang::GetLangIndex("en"));
|
||||
|
@ -57,7 +60,7 @@ UNIT_TEST(LocalityFinder)
|
|||
// Tets one viewport based on whole map
|
||||
doTests(finder, input, results);
|
||||
|
||||
// Test two viewport based on quaters of worl map
|
||||
// Test two viewport based on quaters of world map
|
||||
m2::RectD rect1;
|
||||
rect1.setMinX(rect.minX());
|
||||
rect1.setMinY(rect.minY());
|
||||
|
|
Loading…
Add table
Reference in a new issue