label_cluster_finalizer.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/history_clusters/core/label_cluster_finalizer.h"
  5. #include <string>
  6. #include "base/containers/flat_set.h"
  7. #include "base/strings/utf_string_conversions.h"
  8. #include "components/history/core/browser/history_types.h"
  9. #include "components/history_clusters/core/config.h"
  10. #include "components/history_clusters/core/history_clusters_util.h"
  11. #include "components/history_clusters/core/on_device_clustering_features.h"
  12. #include "components/history_clusters/core/on_device_clustering_util.h"
  13. #include "components/strings/grit/components_strings.h"
  14. #include "components/url_formatter/url_formatter.h"
  15. #include "ui/base/l10n/l10n_util.h"
  16. namespace history_clusters {
  17. LabelClusterFinalizer::LabelClusterFinalizer() = default;
  18. LabelClusterFinalizer::~LabelClusterFinalizer() = default;
  19. void LabelClusterFinalizer::FinalizeCluster(history::Cluster& cluster) {
  20. float max_label_score = -1;
  21. absl::optional<std::u16string> current_highest_scoring_label;
  22. absl::optional<std::u16string> current_highest_scoring_label_unquoted;
  23. // First try finding search terms to use as the cluster label.
  24. for (const auto& visit : cluster.visits) {
  25. if (!visit.annotated_visit.content_annotations.search_terms.empty() &&
  26. visit.score > max_label_score) {
  27. current_highest_scoring_label_unquoted =
  28. visit.annotated_visit.content_annotations.search_terms;
  29. current_highest_scoring_label = l10n_util::GetStringFUTF16(
  30. IDS_HISTORY_CLUSTERS_CLUSTER_LABEL_SEARCH_TERMS,
  31. *current_highest_scoring_label_unquoted);
  32. max_label_score = visit.score;
  33. }
  34. }
  35. // If we haven't found a label yet, use Entities, if that flag is enabled.
  36. // TODO(crbug.com/1294348): Implement a configurable quality threshold, so
  37. // low quality Entity labels can be ignored in favor of hostnames below.
  38. if (GetConfig().labels_from_entities && !current_highest_scoring_label) {
  39. base::flat_map<std::string, float> entity_to_score;
  40. for (const auto& visit : cluster.visits) {
  41. for (const auto& entity : visit.annotated_visit.content_annotations
  42. .model_annotations.entities) {
  43. auto it = entity_to_score.find(entity.id);
  44. float new_score = it != entity_to_score.end()
  45. ? it->second + (entity.weight * visit.score)
  46. : entity.weight * visit.score;
  47. if (new_score > max_label_score) {
  48. max_label_score = new_score;
  49. current_highest_scoring_label = base::UTF8ToUTF16(entity.id);
  50. current_highest_scoring_label_unquoted =
  51. current_highest_scoring_label;
  52. }
  53. entity_to_score[entity.id] = new_score;
  54. }
  55. }
  56. }
  57. // If we haven't found a label yet, use hostnames if the flag is enabled.
  58. if (GetConfig().labels_from_hostnames && !current_highest_scoring_label) {
  59. base::flat_map<std::u16string, float> hostname_to_score;
  60. for (const auto& visit : cluster.visits) {
  61. std::u16string host =
  62. ComputeURLForDisplay(visit.normalized_url, /*trim_after_host=*/true);
  63. float& hostname_score = hostname_to_score[host];
  64. hostname_score += visit.score;
  65. if (hostname_score > max_label_score) {
  66. current_highest_scoring_label = host;
  67. current_highest_scoring_label_unquoted = current_highest_scoring_label;
  68. max_label_score = hostname_score;
  69. }
  70. }
  71. // At the end of this process, if we assigned a hostname label, yet there
  72. // is more than one hostname available, append " and more" to the label.
  73. if (current_highest_scoring_label && hostname_to_score.size() > 1) {
  74. current_highest_scoring_label = l10n_util::GetStringFUTF16(
  75. IDS_HISTORY_CLUSTERS_CLUSTER_LABEL_MULTIPLE_HOSTNAMES,
  76. *current_highest_scoring_label);
  77. }
  78. }
  79. if (current_highest_scoring_label) {
  80. cluster.label = *current_highest_scoring_label;
  81. cluster.raw_label = *current_highest_scoring_label_unquoted;
  82. }
  83. }
  84. } // namespace history_clusters