Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Unified Diff: components/drive/search_metadata.cc

Issue 1321553003: Files.app: split query into AND conditioned keywords in metadata search. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move import of scoped_vector. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/drive/search_metadata.cc
diff --git a/components/drive/search_metadata.cc b/components/drive/search_metadata.cc
index 381e81fb0db9260cbd4f4a3778abfcae8c63ddfd..36676cbe36974df2133555ceabc8794727681f15 100644
--- a/components/drive/search_metadata.cc
+++ b/components/drive/search_metadata.cc
@@ -10,6 +10,9 @@
#include "base/bind.h"
#include "base/i18n/string_search.h"
#include "base/metrics/histogram.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "components/drive/drive_api_util.h"
@@ -141,12 +144,13 @@ class HiddenEntryClassifier {
// Used to implement SearchMetadata.
// Adds entry to the result when appropriate.
-// In particular, if |query| is non-null, only adds files with the name matching
-// the query.
+// In particular, if size of |queries| is larger than 0, only adds files with
+// the name matching the query.
FileError MaybeAddEntryToResult(
ResourceMetadata* resource_metadata,
ResourceMetadata::Iterator* it,
- base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents* query,
+ const ScopedVector<
+ base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>& queries,
const SearchMetadataPredicate& predicate,
size_t at_most_num_matches,
HiddenEntryClassifier* hidden_entry_classifier,
@@ -168,7 +172,8 @@ FileError MaybeAddEntryToResult(
// contain |query| to match the query.
std::string highlighted;
if (!predicate.Run(entry) ||
- (query && !FindAndHighlight(entry.base_name(), query, &highlighted)))
+ (queries.size() > 0 &&
+ !FindAndHighlight(entry.base_name(), queries, &highlighted)))
return FILE_ERROR_OK;
// Hidden entry should not be returned.
@@ -194,8 +199,18 @@ FileError SearchMetadataOnBlockingPool(ResourceMetadata* resource_metadata,
ResultCandidateComparator> result_candidates;
// Prepare data structure for searching.
- base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents query(
- base::UTF8ToUTF16(query_text));
+ std::vector<base::string16> keywords =
+ base::SplitString(base::UTF8ToUTF16(query_text),
+ base::StringPiece16(base::kWhitespaceUTF16),
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+ ScopedVector<base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>
+ queries;
+ for (const auto& keyword : keywords) {
+ queries.push_back(
+ new base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents(
+ keyword));
+ }
// Prepare an object to filter out hidden entries.
ResourceEntry mydrive;
@@ -210,9 +225,8 @@ FileError SearchMetadataOnBlockingPool(ResourceMetadata* resource_metadata,
scoped_ptr<ResourceMetadata::Iterator> it = resource_metadata->GetIterator();
for (; !it->IsAtEnd(); it->Advance()) {
FileError error = MaybeAddEntryToResult(
- resource_metadata, it.get(), query_text.empty() ? NULL : &query,
- predicate, at_most_num_matches, &hidden_entry_classifier,
- &result_candidates);
+ resource_metadata, it.get(), queries, predicate, at_most_num_matches,
+ &hidden_entry_classifier, &result_candidates);
if (error != FILE_ERROR_OK)
return error;
}
@@ -308,26 +322,59 @@ bool MatchesType(int options, const ResourceEntry& entry) {
bool FindAndHighlight(
const std::string& text,
- base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents* query,
+ const ScopedVector<
+ base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>& queries,
std::string* highlighted_text) {
- DCHECK(query);
DCHECK(highlighted_text);
highlighted_text->clear();
- base::string16 text16 = base::UTF8ToUTF16(text);
+ // Empty query does not match with anything.
+ if (text.empty())
hashimoto 2015/09/07 06:17:09 The comment says "empty query", but here the empti
yawano 2015/09/08 10:27:21 We should have checked empty query. Fixed and adde
+ return false;
+
+ // Check text matches with all queries.
size_t match_start = 0;
size_t match_length = 0;
- if (!query->Search(text16, &match_start, &match_length))
- return false;
- base::string16 pre = text16.substr(0, match_start);
- base::string16 match = text16.substr(match_start, match_length);
- base::string16 post = text16.substr(match_start + match_length);
- highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(pre)));
- highlighted_text->append("<b>");
- highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(match)));
- highlighted_text->append("</b>");
- highlighted_text->append(net::EscapeForHTML(base::UTF16ToUTF8(post)));
+ base::string16 text16 = base::UTF8ToUTF16(text);
+ std::vector<bool> highlights(text16.size(), false);
+ for (auto* query : queries) {
+ if (!query->Search(text16, &match_start, &match_length))
+ return false;
+
+ size_t match_end = match_start + match_length;
+ for (size_t i = match_start; i < match_end; ++i) {
+ highlights[i] = true;
+ }
hashimoto 2015/09/07 06:17:09 nit: You can do std::fill(highlights.begin() + mat
yawano 2015/09/08 10:27:21 Done.
+ }
+
+ // Generate highlighted text.
+ bool highlighting = false;
+ size_t start = 0;
hashimoto 2015/09/07 06:17:09 nit: |start| sounds a bit ambiguous. How about a m
yawano 2015/09/08 10:27:21 Done.
+
+ for (size_t i = 0; i < text16.size(); ++i) {
+ if (highlighting == highlights[i])
+ continue;
+
+ // Append [start, i).
+ if (i > start) {
hashimoto 2015/09/07 06:17:09 Do we need this check? IIUC this is only needed if
yawano 2015/09/08 10:27:21 Done.
+ highlighted_text->append(net::EscapeForHTML(
+ base::UTF16ToUTF8(text16.substr(start, i - start))));
+ }
+
+ highlighted_text->append(highlighting ? "</b>" : "<b>");
hashimoto 2015/09/07 06:17:09 I found this line a bit difficult to understand. H
yawano 2015/09/08 10:27:21 Done.
+
+ start = i;
+ highlighting = highlights[i];
+ }
+
+ DCHECK_GE(text16.size(), start);
+ highlighted_text->append(net::EscapeForHTML(
+ base::UTF16ToUTF8(text16.substr(start, text16.size() - start))));
+
+ if (highlighting)
+ highlighted_text->append("</b>");
+
return true;
}

Powered by Google App Engine
This is Rietveld 408576698