Store reference to type index instead of raw type in mwm search index.

This commit is contained in:
vng 2013-02-21 22:52:39 +03:00 committed by Alex Zolotarev
parent f4a9517f29
commit 9db034bade
8 changed files with 230 additions and 86 deletions

View file

@ -34,11 +34,12 @@ public:
private:
typedef strings::UniString StringT;
typedef multimap<uint32_t, shared_ptr<Category> > ContainerT;
typedef ContainerT::const_iterator IteratorT;
typedef multimap<uint32_t, shared_ptr<Category> > Type2CategoryContT;
typedef multimap<StringT, uint32_t> Name2CatContT;
typedef Type2CategoryContT::const_iterator IteratorT;
multimap<uint32_t, shared_ptr<Category> > m_type2cat;
multimap<StringT, uint32_t> m_name2type;
Type2CategoryContT m_type2cat;
Name2CatContT m_name2type;
public:
CategoriesHolder() {}
@ -65,7 +66,7 @@ public:
template <class ToDo>
void ForEachTypeByName(StringT const & name, ToDo toDo) const
{
typedef typename multimap<StringT, uint32_t>::const_iterator IterT;
typedef typename Name2CatContT::const_iterator IterT;
pair<IterT, IterT> range = m_name2type.equal_range(name);
while (range.first != range.second)

View file

@ -336,6 +336,8 @@ public:
if (types.Empty()) return;
Classificator const & c = classif();
// add names of categories of the feature
for (size_t i = 0; i < types.Size(); ++i)
{
@ -354,7 +356,8 @@ public:
if (my::between_s(m_scales.first, m_scales.second, r.first) ||
my::between_s(m_scales.first, m_scales.second, r.second))
{
inserter.AddToken(search::CATEGORIES_LANG, search::FeatureTypeToString(type));
inserter.AddToken(search::CATEGORIES_LANG,
search::FeatureTypeToString(c.GetIndexForType(type)));
}
}
}

View file

@ -66,11 +66,11 @@ void Framework::AddMap(string const & file)
//threads::MutexGuard lock(m_modelSyn);
int const version = m_model.AddMap(file);
if (m_lowestMapVersion > version)
m_lowestMapVersion = version;
// Now we do force delete of old (April 2011) maps.
//if (m_lowestMapVersion == -1 || (version != -1 && m_lowestMapVersion > version))
// m_lowestMapVersion = version;
if (version == 0)
if (version == feature::DataHeader::v1)
{
LOG(LINFO, ("Deleting old map:", file));
RemoveMap(file);
@ -78,10 +78,10 @@ void Framework::AddMap(string const & file)
}
}
void Framework::RemoveMap(string const & datFile)
void Framework::RemoveMap(string const & file)
{
//threads::MutexGuard lock(m_modelSyn);
m_model.RemoveMap(datFile);
m_model.RemoveMap(file);
}
void Framework::StartLocation()
@ -183,7 +183,7 @@ Framework::Framework()
m_width(0),
m_height(0),
m_informationDisplay(this),
//m_lowestMapVersion(-1),
m_lowestMapVersion(numeric_limits<int>::max()),
m_benchmarkEngine(0)
{
// Checking whether we should enable benchmark.
@ -226,27 +226,27 @@ Framework::Framework()
m_model.InitClassificator();
// To avoid possible races - init search engine once in constructor.
(void)GetSearchEngine();
// Get all available maps.
vector<string> maps;
GetResourcesMaps(maps);
#ifndef OMIM_OS_ANDROID
// On Android, local maps are added and removed when
// external storage is connected/disconnected.
// On Android, local maps are added and removed when external storage is connected/disconnected.
GetLocalMaps(maps);
#endif
// Remove duplicate maps if they're both present in resources and in WritableDir
// Remove duplicate maps if they're both present in resources and in WritableDir.
sort(maps.begin(), maps.end());
maps.erase(unique(maps.begin(), maps.end()), maps.end());
// Add founded maps to index.
for_each(maps.begin(), maps.end(), bind(&Framework::AddMap, this, _1));
// Init storage with needed callback.
m_storage.Init(bind(&Framework::UpdateAfterDownload, this, _1));
// To avoid possible races - init search engine once in constructor.
(void)GetSearchEngine();
LOG(LDEBUG, ("Storage initialized"));
}
@ -358,6 +358,8 @@ void Framework::AddLocalMaps()
GetLocalMaps(maps);
for_each(maps.begin(), maps.end(), bind(&Framework::AddMap, this, _1));
m_pSearchEngine->SupportOldFormat(m_lowestMapVersion < feature::DataHeader::v3);
}
void Framework::RemoveLocalMaps()
@ -1283,11 +1285,14 @@ search::Engine * Framework::GetSearchEngine() const
try
{
m_pSearchEngine.reset(new search::Engine(&m_model.GetIndex(),
pl.GetReader(SEARCH_CATEGORIES_FILE_NAME),
pl.GetReader(PACKED_POLYGONS_FILE),
pl.GetReader(COUNTRIES_FILE),
languages::CurrentLanguage()));
m_pSearchEngine.reset(new search::Engine(
&m_model.GetIndex(),
pl.GetReader(SEARCH_CATEGORIES_FILE_NAME),
pl.GetReader(PACKED_POLYGONS_FILE),
pl.GetReader(COUNTRIES_FILE),
languages::CurrentLanguage()));
m_pSearchEngine->SupportOldFormat(m_lowestMapVersion < feature::DataHeader::v3);
}
catch (RootException const & e)
{
@ -1449,36 +1454,6 @@ void Framework::SetupMeasurementSystem()
Invalidate();
}
/*
// 0 - old April version which we should delete
#define MAXIMUM_VERSION_TO_DELETE 0
bool Framework::NeedToDeleteOldMaps() const
{
return m_lowestMapVersion == MAXIMUM_VERSION_TO_DELETE;
}
void Framework::DeleteOldMaps()
{
Platform & p = GetPlatform();
vector<string> maps;
p.GetFilesByExt(p.WritableDir(), DATA_FILE_EXTENSION, maps);
for (vector<string>::iterator it = maps.begin(); it != maps.end(); ++it)
{
feature::DataHeader header;
LoadMapHeader(p.GetReader(*it), header);
if (header.GetVersion() <= MAXIMUM_VERSION_TO_DELETE)
{
LOG(LINFO, ("Deleting old map", *it));
RemoveMap(*it);
FileWriter::DeleteFileX(p.WritablePathForFile(*it));
InvalidateRect(header.GetBounds());
}
}
m_lowestMapVersion = MAXIMUM_VERSION_TO_DELETE + 1;
}
*/
string Framework::GetCountryCode(m2::PointD const & pt) const
{
return GetSearchEngine()->GetCountryCode(pt);

View file

@ -125,10 +125,9 @@ protected:
return 0.0;
}
/// Stores lowest loaded map version
/// Holds -1 if no maps were added
/// Stores lowest loaded map version or MAX_INT if no maps added.
/// @see feature::DataHeader::Version
//int m_lowestMapVersion;
int m_lowestMapVersion;
void DrawAdditionalInfo(shared_ptr<PaintEvent> const & e);
@ -136,21 +135,13 @@ protected:
void ClearAllCaches();
void AddMap(string const & file);
void RemoveMap(string const & file);
public:
Framework();
virtual ~Framework();
/*
/// @name Used on iPhone for upgrade from April 1.0.1 version
//@{
/// @return true if client should display delete old maps dialog before using downloader
bool NeedToDeleteOldMaps() const;
void DeleteOldMaps();
//@}
*/
void AddMap(string const & file);
void RemoveMap(string const & datFile);
bool IsCategoryExist(string const & name);
/// @name Process storage connecting/disconnecting.
//@{

View file

@ -94,6 +94,11 @@ Engine::~Engine()
{
}
void Engine::SupportOldFormat(bool b)
{
m_pQuery->SupportOldFormat(b);
}
namespace
{
m2::PointD GetViewportXY(double lat, double lon)

View file

@ -36,6 +36,8 @@ public:
string const & lang);
~Engine();
void SupportOldFormat(bool b);
void PrepareSearch(m2::RectD const & viewport,
bool hasPt, double lat, double lon);
bool Search(SearchParams const & params, m2::RectD const & viewport);

View file

@ -213,8 +213,8 @@ void Query::UpdateViewportOffsets(MWMVectorT const & mwmInfo, m2::RectD const &
Index::MwmLock mwmLock(*m_pIndex, mwmId);
if (MwmValue * pMwm = mwmLock.GetValue())
{
feature::DataHeader const & header = pMwm->GetHeader();
if (header.GetType() == feature::DataHeader::country)
FHeaderT const & header = pMwm->GetHeader();
if (header.GetType() == FHeaderT::country)
{
pair<int, int> const scaleR = header.GetScaleRange();
int const scale = min(max(viewScale + SCALE_SEARCH_DEPTH, scaleR.first), scaleR.second);
@ -653,21 +653,184 @@ public:
namespace
{
typedef vector<strings::UniString> TokensVectorT;
typedef vector<strings::UniString> TokensVectorT;
class DoInsertTypeNames
{
TokensVectorT & m_tokens;
public:
DoInsertTypeNames(TokensVectorT & tokens) : m_tokens(tokens) {}
void operator() (uint32_t t)
class DoInsertTypeNames
{
m_tokens.push_back(FeatureTypeToString(t));
}
};
Classificator const & m_c;
TokensVectorT & m_tokens;
bool m_supportOldFormat;
static int GetOldTypeFromIndex(size_t index)
{
// "building" has old type value = 70
ASSERT_NOT_EQUAL(index, 70, ());
switch (index)
{
case 156: return 4099;
case 98: return 4163;
case 374: return 4419;
case 188: return 4227;
case 100: return 6147;
case 107: return 4547;
case 96: return 5059;
case 60: return 6275;
case 66: return 5251;
case 161: return 4120;
case 160: return 4376;
case 159: return 4568;
case 16: return 4233;
case 178: return 5654;
case 227: return 4483;
case 111: return 5398;
case 256: return 5526;
case 702: return 263446;
case 146: return 4186;
case 155: return 4890;
case 141: return 4570;
case 158: return 4762;
case 38: return 5891;
case 63: return 4291;
case 270: return 4355;
case 327: return 4675;
case 704: return 4611;
case 242: return 4739;
case 223: return 4803;
case 174: return 4931;
case 137: return 5123;
case 186: return 5187;
case 250: return 5315;
case 104: return 4299;
case 113: return 5379;
case 206: return 4867;
case 184: return 5443;
case 125: return 5507;
case 170: return 5571;
case 25: return 5763;
case 118: return 5827;
case 76: return 6019;
case 116: return 6083;
case 108: return 6211;
case 35: return 6339;
case 180: return 6403;
case 121: return 6595;
case 243: return 6659;
case 150: return 6723;
case 175: return 6851;
case 600: return 4180;
case 348: return 4244;
case 179: return 4116;
case 77: return 4884;
case 387: return 262164;
case 214: return 4308;
case 289: return 4756;
case 264: return 4692;
case 93: return 4500;
case 240: return 4564;
case 127: return 4820;
case 29: return 4436;
case 20: return 4948;
case 18: return 4628;
case 293: return 4372;
case 22: return 4571;
case 3: return 4699;
case 51: return 4635;
case 89: return 4123;
case 307: return 5705;
case 15: return 5321;
case 6: return 4809;
case 58: return 6089;
case 26: return 5513;
case 187: return 5577;
case 1: return 5769;
case 12: return 5897;
case 244: return 5961;
case 8: return 6153;
case 318: return 6217;
case 2: return 6025;
case 30: return 5833;
case 7: return 6281;
case 65: return 6409;
case 221: return 6473;
case 54: return 4937;
case 69: return 5385;
case 4: return 6537;
case 200: return 5257;
case 195: return 5129;
case 120: return 5193;
case 56: return 5904;
case 5: return 6864;
case 169: return 4171;
case 61: return 5707;
case 575: return 5968;
case 563: return 5456;
case 13: return 6992;
case 10: return 4811;
case 109: return 4236;
case 67: return 4556;
case 276: return 4442;
case 103: return 4506;
case 183: return 4440;
case 632: return 4162;
case 135: return 4098;
case 205: return 5004;
case 87: return 4684;
case 164: return 4940;
case 201: return 4300;
case 68: return 4620;
case 101: return 5068;
case 0: return 70;
case 737: return 4102;
case 703: return 5955;
case 705: return 6531;
case 706: return 5635;
case 707: return 5699;
case 708: return 4995;
case 715: return 4298;
case 717: return 4362;
case 716: return 4490;
case 718: return 4234;
case 719: return 4106;
case 722: return 4240;
case 723: return 6480;
case 725: return 4312;
case 726: return 4248;
case 727: return 4184;
case 728: return 4504;
case 732: return 4698;
case 733: return 4378;
case 734: return 4634;
case 166: return 4250;
case 288: return 4314;
case 274: return 4122;
}
return -1;
}
public:
DoInsertTypeNames(TokensVectorT & tokens, bool supportOldFormat)
: m_c(classif()), m_tokens(tokens), m_supportOldFormat(supportOldFormat)
{
}
void operator() (uint32_t t)
{
uint32_t const index = m_c.GetIndexForType(t);
m_tokens.push_back(FeatureTypeToString(index));
// v2-version MWM has raw classificator types in search index prefix, so
// do the hack: add synonyms for old convention if needed.
if (m_supportOldFormat)
{
int const type = GetOldTypeFromIndex(index);
if (type >= 0)
{
ASSERT ( type == 70 || type > 4000, (type));
m_tokens.push_back(FeatureTypeToString(static_cast<uint32_t>(type)));
}
}
}
};
} // namespace search::impl
Query::Params::Params(Query const & q, bool isLocalities/* = false*/)
@ -686,10 +849,10 @@ Query::Params::Params(Query const & q, bool isLocalities/* = false*/)
if (q.m_pCategories && !isLocalities)
{
for (size_t i = 0; i < tokensCount; ++i)
q.m_pCategories->ForEachTypeByName(q.m_tokens[i], DoInsertTypeNames(m_tokens[i]));
q.m_pCategories->ForEachTypeByName(q.m_tokens[i], DoInsertTypeNames(m_tokens[i], q.m_supportOldFormat));
if (!q.m_prefix.empty())
q.m_pCategories->ForEachTypeByName(q.m_prefix, DoInsertTypeNames(m_prefixTokens));
q.m_pCategories->ForEachTypeByName(q.m_prefix, DoInsertTypeNames(m_prefixTokens, q.m_supportOldFormat));
}
FillLanguages(q);
@ -1021,7 +1184,7 @@ void Query::SearchAddress()
MwmValue * pMwm = mwmLock.GetValue();
if (pMwm &&
pMwm->m_cont.IsReaderExist(SEARCH_INDEX_FILE_TAG) &&
pMwm->GetHeader().GetType() == feature::DataHeader::world)
pMwm->GetHeader().GetType() == FHeaderT::world)
{
impl::Locality city;
impl::Region region;
@ -1532,10 +1695,10 @@ void Query::SearchInMWM(Index::MwmLock const & mwmLock, Params const & params, i
{
if (pMwm->m_cont.IsReaderExist(SEARCH_INDEX_FILE_TAG))
{
feature::DataHeader const & header = pMwm->GetHeader();
FHeaderT const & header = pMwm->GetHeader();
/// @todo do not process World.mwm here - do it in SearchLocality
bool const isWorld = (header.GetType() == feature::DataHeader::world);
bool const isWorld = (header.GetType() == FHeaderT::world);
if (isWorld && !m_worldSearch)
return;

View file

@ -64,6 +64,8 @@ public:
size_t resultsNeeded = 10);
~Query();
inline void SupportOldFormat(bool b) { m_supportOldFormat = b; }
void Init();
void SetViewport(m2::RectD viewport[], size_t count);
@ -139,6 +141,7 @@ private:
typedef vector<MwmInfo> MWMVectorT;
typedef vector<vector<uint32_t> > OffsetsVectorT;
typedef feature::DataHeader FHeaderT;
void SetViewportByIndex(MWMVectorT const & mwmInfo, m2::RectD const & viewport, size_t idx);
void UpdateViewportOffsets(MWMVectorT const & mwmInfo, m2::RectD const & rect,
@ -212,6 +215,7 @@ private:
KeywordLangMatcher m_keywordsScorer;
OffsetsVectorT m_offsetsInViewport[RECTSCOUNT];
bool m_supportOldFormat;
template <class ParamT, class RefT> class CompareT
{