[search] [bookmarks] API changes.

This commit is contained in:
Maxim Pimenov 2019-09-02 16:53:44 +03:00 committed by Aleksey Belousov
parent 6fb8cd93b2
commit dbd594721a
9 changed files with 176 additions and 28 deletions

View file

@ -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;

View file

@ -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;
};

View file

@ -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;

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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