forked from organicmaps/organicmaps
[search] [bookmarks] API changes.
This commit is contained in:
parent
6fb8cd93b2
commit
dbd594721a
9 changed files with 176 additions and 28 deletions
|
@ -403,6 +403,26 @@ size_t SearchAPI::GetMaximumPossibleNumberOfBookmarksToIndex()
|
|||
return kMaximumPossibleNumberOfBookmarksToIndex;
|
||||
}
|
||||
|
||||
void SearchAPI::EnableIndexingOfBookmarkGroup(kml::MarkGroupId const & groupId, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
m_indexableGroups.insert(groupId);
|
||||
else
|
||||
m_indexableGroups.erase(groupId);
|
||||
|
||||
m_engine.EnableIndexingOfBookmarkGroup(KmlGroupIdToSearchGroupId(groupId), enable);
|
||||
}
|
||||
|
||||
bool SearchAPI::IsIndexingOfBookmarkGroupEnabled(kml::MarkGroupId const & groupId)
|
||||
{
|
||||
return m_indexableGroups.count(groupId) > 0;
|
||||
}
|
||||
|
||||
unordered_set<kml::MarkGroupId> const & SearchAPI::GetIndexableGroups() const
|
||||
{
|
||||
return m_indexableGroups;
|
||||
}
|
||||
|
||||
void SearchAPI::OnBookmarksCreated(vector<BookmarkInfo> const & marks)
|
||||
{
|
||||
vector<BookmarkIdDoc> data;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
@ -152,6 +153,14 @@ public:
|
|||
// The limit is not enforced by the Search API.
|
||||
static size_t GetMaximumPossibleNumberOfBookmarksToIndex();
|
||||
|
||||
// By default all created bookmarks are saved in BookmarksProcessor
|
||||
// but we do not index them in an attempt to save time and memory.
|
||||
// This method must be used to enable or disable indexing all current and future
|
||||
// bookmarks belonging to |groupId|.
|
||||
void EnableIndexingOfBookmarkGroup(kml::MarkGroupId const & groupId, bool enable);
|
||||
bool IsIndexingOfBookmarkGroupEnabled(kml::MarkGroupId const & groupId);
|
||||
std::unordered_set<kml::MarkGroupId> const & GetIndexableGroups() const;
|
||||
|
||||
void OnBookmarksCreated(std::vector<BookmarkInfo> const & marks);
|
||||
void OnBookmarksUpdated(std::vector<BookmarkInfo> const & marks);
|
||||
void OnBookmarksDeleted(std::vector<kml::MarkId> const & marks);
|
||||
|
@ -192,4 +201,9 @@ private:
|
|||
// Viewport search callback should be changed every time when SearchAPI::PokeSearchInViewport
|
||||
// is called and we need viewport search params to construct it.
|
||||
search::ViewportSearchParams m_viewportParams;
|
||||
|
||||
// Same as the one in bookmarks::Processor. Duplicated here because
|
||||
// it is easier than obtaining the information about a group asynchronously
|
||||
// from |m_engine|.
|
||||
std::unordered_set<kml::MarkGroupId> m_indexableGroups;
|
||||
};
|
||||
|
|
|
@ -78,9 +78,27 @@ Processor::Processor(Emitter & emitter, base::Cancellable const & cancellable)
|
|||
{
|
||||
}
|
||||
|
||||
void Processor::EnableIndexingOfDescriptions(bool enable)
|
||||
void Processor::EnableIndexingOfDescriptions(bool enable) { m_indexDescriptions = enable; }
|
||||
|
||||
void Processor::EnableIndexingOfBookmarkGroup(GroupId const & groupId, bool enable)
|
||||
{
|
||||
m_indexDescriptions = enable;
|
||||
bool const wasIndexable = m_indexableGroups.count(groupId) > 0;
|
||||
if (enable)
|
||||
m_indexableGroups.insert(groupId);
|
||||
else
|
||||
m_indexableGroups.erase(groupId);
|
||||
bool const nowIndexable = m_indexableGroups.count(groupId) > 0;
|
||||
|
||||
if (wasIndexable == nowIndexable)
|
||||
return;
|
||||
|
||||
for (auto const & id : m_bookmarksInGroup[groupId])
|
||||
{
|
||||
if (nowIndexable)
|
||||
AddToIndex(id);
|
||||
else
|
||||
EraseFromIndex(id);
|
||||
}
|
||||
}
|
||||
|
||||
void Processor::Add(Id const & id, Doc const & doc)
|
||||
|
@ -99,17 +117,53 @@ void Processor::Add(Id const & id, Doc const & doc)
|
|||
|
||||
DocVec const docVec(builder);
|
||||
|
||||
m_index.Add(id, DocVecWrapper(docVec));
|
||||
m_docs[id] = docVec;
|
||||
}
|
||||
|
||||
void Processor::AddToIndex(Id const & id)
|
||||
{
|
||||
ASSERT_EQUAL(m_docs.count(id), 1, ());
|
||||
|
||||
m_index.Add(id, DocVecWrapper(m_docs[id]));
|
||||
}
|
||||
|
||||
void Processor::Update(Id const & id, Doc const & doc)
|
||||
{
|
||||
auto const groupIt = m_idToGroup.find(id);
|
||||
if (groupIt != m_idToGroup.end())
|
||||
{
|
||||
// A copy to avoid use-after-free.
|
||||
auto const group = groupIt->second;
|
||||
DetachFromGroup(id, group);
|
||||
}
|
||||
|
||||
Erase(id);
|
||||
Add(id, doc);
|
||||
|
||||
if (groupIt != m_idToGroup.end())
|
||||
{
|
||||
// A copy to avoid use-after-free.
|
||||
auto const group = groupIt->second;
|
||||
AttachToGroup(id, group);
|
||||
}
|
||||
}
|
||||
|
||||
void Processor::Erase(Id const & id)
|
||||
{
|
||||
ASSERT_EQUAL(m_docs.count(id), 1, ());
|
||||
|
||||
ASSERT(m_idToGroup.find(id) == m_idToGroup.end(),
|
||||
("A bookmark must be detached from all groups before being deleted."));
|
||||
|
||||
m_docs.erase(id);
|
||||
}
|
||||
|
||||
void Processor::EraseFromIndex(Id const & id)
|
||||
{
|
||||
ASSERT_EQUAL(m_docs.count(id), 1, ());
|
||||
|
||||
auto const & docVec = m_docs[id];
|
||||
m_index.Erase(id, DocVecWrapper(docVec));
|
||||
m_docs.erase(id);
|
||||
}
|
||||
|
||||
void Processor::AttachToGroup(Id const & id, GroupId const & group)
|
||||
|
@ -122,6 +176,9 @@ void Processor::AttachToGroup(Id const & id, GroupId const & group)
|
|||
}
|
||||
|
||||
m_idToGroup[id] = group;
|
||||
m_bookmarksInGroup[group].insert(id);
|
||||
if (m_indexableGroups.count(group) > 0)
|
||||
AddToIndex(id);
|
||||
}
|
||||
|
||||
void Processor::DetachFromGroup(Id const & id, GroupId const & group)
|
||||
|
@ -140,7 +197,17 @@ void Processor::DetachFromGroup(Id const & id, GroupId const & group)
|
|||
"but it only belongs to group", it->second));
|
||||
return;
|
||||
}
|
||||
|
||||
m_idToGroup.erase(it);
|
||||
m_bookmarksInGroup[group].erase(id);
|
||||
|
||||
if (m_indexableGroups.count(group) > 0)
|
||||
EraseFromIndex(id);
|
||||
|
||||
auto const groupIt = m_bookmarksInGroup.find(group);
|
||||
CHECK(groupIt != m_bookmarksInGroup.end(), (group, m_bookmarksInGroup));
|
||||
if (groupIt->second.size() == 0)
|
||||
m_bookmarksInGroup.erase(groupIt);
|
||||
}
|
||||
|
||||
void Processor::Search(Params const & params) const
|
||||
|
@ -175,7 +242,7 @@ void Processor::Search(Params const & params) const
|
|||
}
|
||||
|
||||
auto it = m_docs.find(id);
|
||||
ASSERT(it != m_docs.end(), ("Can't find retrieved doc:", id));
|
||||
CHECK(it != m_docs.end(), ("Can't find retrieved doc:", id));
|
||||
auto const & doc = it->second;
|
||||
|
||||
RankingInfo info;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
@ -47,8 +48,18 @@ public:
|
|||
// by their descriptions.
|
||||
void EnableIndexingOfDescriptions(bool enable);
|
||||
|
||||
void EnableIndexingOfBookmarkGroup(GroupId const & groupId, bool enable);
|
||||
|
||||
// Adds a bookmark to Processor but does not index it.
|
||||
void Add(Id const & id, Doc const & doc);
|
||||
// Indexes an already added bookmark.
|
||||
void AddToIndex(Id const & id);
|
||||
// Updates a bookmark with a new |doc|. Re-indexes if the bookmarks
|
||||
// is already attached to an indexable group.
|
||||
void Update(Id const & id, Doc const & doc);
|
||||
|
||||
void Erase(Id const & id);
|
||||
void EraseFromIndex(Id const & id);
|
||||
|
||||
void AttachToGroup(Id const & id, GroupId const & group);
|
||||
void DetachFromGroup(Id const & id, GroupId const & group);
|
||||
|
@ -82,11 +93,13 @@ private:
|
|||
std::unordered_map<Id, DocVec> m_docs;
|
||||
|
||||
bool m_indexDescriptions = false;
|
||||
std::unordered_set<GroupId> m_indexableGroups;
|
||||
|
||||
// Currently a bookmark can belong to at most one group
|
||||
// but in the future it is possible for a single bookmark to be
|
||||
// attached to multiple groups.
|
||||
std::unordered_map<Id, GroupId> m_idToGroup;
|
||||
std::unordered_map<GroupId, std::unordered_set<Id>> m_bookmarksInGroup;
|
||||
};
|
||||
} // namespace bookmarks
|
||||
} // namespace search
|
||||
|
|
|
@ -165,6 +165,13 @@ void Engine::EnableIndexingOfBookmarksDescriptions(bool enable)
|
|||
});
|
||||
}
|
||||
|
||||
void Engine::EnableIndexingOfBookmarkGroup(bookmarks::GroupId const & groupId, bool enable)
|
||||
{
|
||||
PostMessage(Message::TYPE_BROADCAST, [=](Processor & processor) {
|
||||
processor.EnableIndexingOfBookmarkGroup(groupId, enable);
|
||||
});
|
||||
}
|
||||
|
||||
void Engine::OnBookmarksCreated(vector<pair<bookmarks::Id, bookmarks::Doc>> const & marks)
|
||||
{
|
||||
PostMessage(Message::TYPE_BROADCAST,
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
void LoadCountriesTree();
|
||||
|
||||
void EnableIndexingOfBookmarksDescriptions(bool enable);
|
||||
void EnableIndexingOfBookmarkGroup(bookmarks::GroupId const & groupId, bool enable);
|
||||
|
||||
void OnBookmarksCreated(std::vector<std::pair<bookmarks::Id, bookmarks::Doc>> const & marks);
|
||||
void OnBookmarksUpdated(std::vector<std::pair<bookmarks::Id, bookmarks::Doc>> const & marks);
|
||||
|
|
|
@ -329,6 +329,11 @@ void Processor::EnableIndexingOfBookmarksDescriptions(bool enable)
|
|||
m_bookmarksProcessor.EnableIndexingOfDescriptions(enable);
|
||||
}
|
||||
|
||||
void Processor::EnableIndexingOfBookmarkGroup(bookmarks::GroupId const & groupId, bool enable)
|
||||
{
|
||||
m_bookmarksProcessor.EnableIndexingOfBookmarkGroup(groupId, enable);
|
||||
}
|
||||
|
||||
void Processor::OnBookmarksCreated(vector<pair<bookmarks::Id, bookmarks::Doc>> const & marks)
|
||||
{
|
||||
for (auto const & idDoc : marks)
|
||||
|
@ -338,10 +343,7 @@ void Processor::OnBookmarksCreated(vector<pair<bookmarks::Id, bookmarks::Doc>> c
|
|||
void Processor::OnBookmarksUpdated(vector<pair<bookmarks::Id, bookmarks::Doc>> const & marks)
|
||||
{
|
||||
for (auto const & idDoc : marks)
|
||||
{
|
||||
m_bookmarksProcessor.Erase(idDoc.first /* id */);
|
||||
m_bookmarksProcessor.Add(idDoc.first /* id */, idDoc.second /* doc */);
|
||||
}
|
||||
m_bookmarksProcessor.Update(idDoc.first /* id */, idDoc.second /* doc */);
|
||||
}
|
||||
|
||||
void Processor::OnBookmarksDeleted(vector<bookmarks::Id> const & marks)
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
void LoadCountriesTree();
|
||||
|
||||
void EnableIndexingOfBookmarksDescriptions(bool enable);
|
||||
void EnableIndexingOfBookmarkGroup(bookmarks::GroupId const & groupId, bool enable);
|
||||
|
||||
void OnBookmarksCreated(std::vector<std::pair<bookmarks::Id, bookmarks::Doc>> const & marks);
|
||||
void OnBookmarksUpdated(std::vector<std::pair<bookmarks::Id, bookmarks::Doc>> const & marks);
|
||||
|
|
|
@ -27,10 +27,19 @@ public:
|
|||
|
||||
Processor & GetProcessor() { return m_processor; }
|
||||
|
||||
void Add(Id const & id, Doc const & doc) { m_processor.Add(id, doc); }
|
||||
void Add(Id const & id, GroupId const & group, Doc const & doc)
|
||||
{
|
||||
m_processor.Add(id, doc);
|
||||
AttachToGroup(id, group);
|
||||
}
|
||||
|
||||
void Erase(Id const & id) { m_processor.Erase(id); }
|
||||
|
||||
void Update(Id const & id, Doc const & doc)
|
||||
{
|
||||
m_processor.Update(id, doc);
|
||||
}
|
||||
|
||||
void AttachToGroup(Id const & id, GroupId const & group) { m_processor.AttachToGroup(id, group); }
|
||||
void DetachFromGroup(Id const & id, GroupId const & group)
|
||||
{
|
||||
|
@ -85,18 +94,27 @@ UNIT_CLASS_TEST(BookmarksProcessorTest, Smoke)
|
|||
{
|
||||
GetProcessor().EnableIndexingOfDescriptions(true);
|
||||
|
||||
Add(10, MakeBookmarkData("Double R Diner" /* name */,
|
||||
"2R Diner" /* customName */,
|
||||
"They've got a cherry pie there that'll kill ya!" /* description */));
|
||||
Add(10, 0, MakeBookmarkData("Double R Diner" /* name */,
|
||||
"2R Diner" /* customName */,
|
||||
"They've got a cherry pie there that'll kill ya!" /* description */));
|
||||
|
||||
Add(18, MakeBookmarkData("Silver Mustang Casino" /* name */,
|
||||
"Ag Mustang" /* customName */,
|
||||
"Joyful place, owners Bradley and Rodney are very friendly!"));
|
||||
Add(20, MakeBookmarkData("Great Northern Hotel" /* name */,
|
||||
"N Hotel" /* customName */,
|
||||
"Clean place with a reasonable price" /* description */));
|
||||
Add(18, 0, MakeBookmarkData("Silver Mustang Casino" /* name */,
|
||||
"Ag Mustang" /* customName */,
|
||||
"Joyful place, owners Bradley and Rodney are very friendly!"));
|
||||
Add(20, 1, MakeBookmarkData("Great Northern Hotel" /* name */,
|
||||
"N Hotel" /* customName */,
|
||||
"Clean place with a reasonable price" /* description */));
|
||||
|
||||
TEST_EQUAL(Search("R&R food"), Ids{}, ());
|
||||
GetProcessor().EnableIndexingOfBookmarkGroup(GroupId{0}, true /* enable */);
|
||||
TEST_EQUAL(Search("R&R food"), Ids({10}), ());
|
||||
GetProcessor().EnableIndexingOfBookmarkGroup(GroupId{0}, false /* enable */);
|
||||
TEST_EQUAL(Search("R&R food"), Ids{}, ());
|
||||
GetProcessor().EnableIndexingOfBookmarkGroup(GroupId{0}, true /* enable */);
|
||||
TEST_EQUAL(Search("R&R food"), Ids({10}), ());
|
||||
|
||||
GetProcessor().EnableIndexingOfBookmarkGroup(GroupId{1}, true /* enable */);
|
||||
|
||||
TEST_EQUAL(Search("cherry pie"), Ids({10}), ());
|
||||
TEST_EQUAL(Search("great silver hotel"), Ids({20, 18}), ());
|
||||
TEST_EQUAL(Search("double r cafe"), Ids({10}), ());
|
||||
|
@ -104,44 +122,49 @@ UNIT_CLASS_TEST(BookmarksProcessorTest, Smoke)
|
|||
TEST_EQUAL(Search("2R"), Ids({10}), ());
|
||||
TEST_EQUAL(Search("Ag"), Ids({18}), ());
|
||||
|
||||
AttachToGroup(Id{10}, GroupId{0});
|
||||
AttachToGroup(Id{18}, GroupId{0});
|
||||
AttachToGroup(Id{20}, GroupId{1});
|
||||
TEST_EQUAL(Search("place"), Ids({20, 18}), ());
|
||||
TEST_EQUAL(Search("place", GroupId{0}), Ids({18}), ());
|
||||
DetachFromGroup(20, 1);
|
||||
AttachToGroup(20, 0);
|
||||
TEST_EQUAL(Search("place", GroupId{0}), Ids({20, 18}), ());
|
||||
|
||||
Update(20, MakeBookmarkData("Great Northern Hotel" /* name */,
|
||||
"N Hotel" /* customName */,
|
||||
"Clean establishment with a reasonable price" /* description */));
|
||||
TEST_EQUAL(Search("place", GroupId{0}), Ids({18}), ());
|
||||
}
|
||||
|
||||
UNIT_CLASS_TEST(BookmarksProcessorTest, IndexDescriptions)
|
||||
{
|
||||
GetProcessor().EnableIndexingOfDescriptions(true);
|
||||
GetProcessor().EnableIndexingOfBookmarkGroup(GroupId{0}, true /* enable */);
|
||||
|
||||
Add(10, MakeBookmarkData("Double R Diner" /* name */,
|
||||
Add(10, 0, MakeBookmarkData("Double R Diner" /* name */,
|
||||
"2R Diner" /* customName */,
|
||||
"They've got a cherry pie there that'll kill ya!" /* description */));
|
||||
TEST_EQUAL(Search("diner"), Ids({10}), ());
|
||||
TEST_EQUAL(Search("cherry pie"), Ids({10}), ());
|
||||
|
||||
DetachFromGroup(10, 0);
|
||||
Erase(10);
|
||||
TEST_EQUAL(Search("diner"), Ids(), ());
|
||||
TEST_EQUAL(Search("diner"), Ids{}, ());
|
||||
TEST_EQUAL(Search("cherry pie"), Ids{}, ());
|
||||
|
||||
GetProcessor().EnableIndexingOfDescriptions(false);
|
||||
Add(10, MakeBookmarkData("Double R Diner" /* name */,
|
||||
Add(10, 0, MakeBookmarkData("Double R Diner" /* name */,
|
||||
"2R Diner" /* customName */,
|
||||
"They've got a cherry pie there that'll kill ya!" /* description */));
|
||||
TEST_EQUAL(Search("diner"), Ids({10}), ());
|
||||
TEST_EQUAL(Search("cherry pie"), Ids(), ());
|
||||
TEST_EQUAL(Search("cherry pie"), Ids{}, ());
|
||||
|
||||
// Results for already indexed bookmarks don't change.
|
||||
GetProcessor().EnableIndexingOfDescriptions(true);
|
||||
TEST_EQUAL(Search("diner"), Ids({10}), ());
|
||||
TEST_EQUAL(Search("cherry pie"), Ids(), ());
|
||||
TEST_EQUAL(Search("cherry pie"), Ids{}, ());
|
||||
|
||||
DetachFromGroup(10, 0);
|
||||
Erase(10);
|
||||
TEST_EQUAL(Search("diner"), Ids(), ());
|
||||
TEST_EQUAL(Search("diner"), Ids{}, ());
|
||||
TEST_EQUAL(Search("cherry pie"), Ids{}, ());
|
||||
}
|
||||
} // namespace
|
||||
|
|
Loading…
Add table
Reference in a new issue