history_clusters_db_tasks.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright 2021 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. #ifndef COMPONENTS_HISTORY_CLUSTERS_CORE_HISTORY_CLUSTERS_DB_TASKS_H_
  5. #define COMPONENTS_HISTORY_CLUSTERS_CORE_HISTORY_CLUSTERS_DB_TASKS_H_
  6. #include <vector>
  7. #include "base/callback.h"
  8. #include "base/time/time.h"
  9. #include "components/history/core/browser/history_db_task.h"
  10. #include "components/history/core/browser/history_types.h"
  11. #include "components/history_clusters/core/history_clusters_service.h"
  12. #include "components/history_clusters/core/history_clusters_types.h"
  13. namespace history_clusters {
  14. // Gets persisted `AnnotatedVisit`s to cluster including both persisted visits
  15. // from the history DB and incomplete visits.
  16. // - We don't want incomplete visits to be mysteriously missing from the
  17. // Clusters UI. They haven't recorded the page end metrics yet, but that's
  18. // fine.
  19. // - The history backend will return persisted visits with already computed
  20. // `referring_visit_of_redirect_chain_start`, while incomplete visits will have
  21. // to invoke `GetRedirectChainStart()`.
  22. class GetAnnotatedVisitsToCluster : public history::HistoryDBTask {
  23. public:
  24. using Callback = base::OnceCallback<void(
  25. std::vector<int64_t> cluster_ids,
  26. std::vector<history::AnnotatedVisit> annotated_visits,
  27. QueryClustersContinuationParams continuation_params)>;
  28. // For a given `end_time`, this returns an appropriate beginning time
  29. // designed to avoid breaking up internet browsing sessions. Before 4PM, it
  30. // returns 4AM the previous day. After 4PM, it returns 4AM today.
  31. static base::Time GetBeginTimeOnDayBoundary(base::Time time);
  32. GetAnnotatedVisitsToCluster(
  33. IncompleteVisitMap incomplete_visit_map,
  34. base::Time begin_time_limit,
  35. QueryClustersContinuationParams continuation_params,
  36. bool recent_first,
  37. int days_of_clustered_visits,
  38. bool recluster,
  39. Callback callback);
  40. ~GetAnnotatedVisitsToCluster() override;
  41. // history::HistoryDBTask:
  42. bool RunOnDBThread(history::HistoryBackend* backend,
  43. history::HistoryDatabase* db) override;
  44. void DoneRunOnMainThread() override;
  45. private:
  46. // Helper for `RunOnDBThread()` that generates the `QueryOptions` for each
  47. // history request. Because `base::Time::Now()` may change during the async
  48. // history request, and because determining whether history was exhausted
  49. // depends on whether the query reached `Now()`, `now` is set when this
  50. // function is called and shared with `IncrementContinuationParams()`.
  51. history::QueryOptions GetHistoryQueryOptions(history::HistoryBackend* backend,
  52. base::Time now);
  53. // Helper for `RunOnDBThread()` that adds complete but unclustered visits
  54. // from `backend` to `annotated_visits_`. Returns whether the visits were
  55. // limited by `options.max_count`.
  56. bool AddUnclusteredVisits(history::HistoryBackend* backend,
  57. history::HistoryDatabase* db,
  58. history::QueryOptions options);
  59. // Helper for `RunOnDBThread()` that adds incomplete visits from
  60. // `incomplete_visit_map_` to `annotated_visits_`.
  61. void AddIncompleteVisits(history::HistoryBackend* backend,
  62. base::Time begin_time,
  63. base::Time end_time);
  64. // Helper for `RunOnDBThread()` that updates `continuation_params_` after each
  65. // history request preparing it for the next call. See
  66. // `GetHistoryQueryOptions()`'s comment regarding `now`.
  67. void IncrementContinuationParams(history::QueryOptions options,
  68. bool limited_by_max_count,
  69. base::Time now);
  70. // Helper for `RunOnDbThread()` that adds clustered visits from `backend` and
  71. // `db` to `annotated_visits_`.
  72. void AddClusteredVisits(history::HistoryBackend* backend,
  73. history::HistoryDatabase* db,
  74. base::Time unclustered_begin_time);
  75. // Incomplete visits that have history rows and are withing the time frame of
  76. // the completed visits fetched will be appended to the annotated visits
  77. // returned for clustering. It's used in the DB thread as each filtered visit
  78. // will need to fetch its `referring_visit_of_redirect_chain_start`.
  79. IncompleteVisitMap incomplete_visit_map_;
  80. // The lower bound of the begin times used in the history requests for
  81. // completed visits. This is a lower bound time of all the visits fetched,
  82. // though the visit count cap may be reached before we've queried all the way
  83. // to `begin_time_limit_`.
  84. base::Time begin_time_limit_;
  85. // The current continuation state representing what's already been queried and
  86. // where the next query should pick up. Initially set in the constructor and
  87. // updated after each history request. The final state will be returned to
  88. // `callback_` to be used in the next query task.
  89. QueryClustersContinuationParams continuation_params_;
  90. // Whether to begin with the most recent visits and iterate towards older
  91. // visits, or vice versa. Since persistent clustering begins with older
  92. // visits, clustered visits will be older than unclustered visits (except
  93. // unclustered sync visits). Therefore, when `recent_first_` is true,
  94. // unclustered visits are iterated 1st and
  95. // `continuation_params_.exhausted_unclustered_visits` will be set true before
  96. // (or simultaneously) with `.exhausted_all_visits`. When `recent_first_` is
  97. // false, both will be set true only when all visits until now have been
  98. // iterated; i.e. `.exhausted_unclustered_visits == .exhausted_all_visits`.
  99. bool recent_first_ = true;
  100. // How many days of clustered visits to include. When 0, will return only 1
  101. // day of unclustered annotated visits. Otherwise, will additionally return
  102. // clustered visits up to `days_of_clustered_visits_` days older than the
  103. // unclustered visits; i.e. clustered visits newer than
  104. // `days_of_clustered_visits_` before the last `QueryOptions::begin_time`.
  105. // Works the same regardless of `recent_first_`. This is useful to re-cluster
  106. // already clustered visits with unclustered visits to allow existing clusters
  107. // to grow rather than be split up arbitrarily at day boundaries.
  108. int days_of_clustered_visits_;
  109. // If true, forces reclustering as if `persist_clusters_in_history_db` were
  110. // false.
  111. bool recluster_;
  112. // The clusters whose visits were returned. Any cluster included will have all
  113. // its visits included; i.e. won't return partial clusters. Retrieved from the
  114. // history DB thread and returned through the callback on the main thread.
  115. std::vector<int64_t> cluster_ids_;
  116. // Persisted visits retrieved from the history DB thread and returned through
  117. // the callback on the main thread.
  118. std::vector<history::AnnotatedVisit> annotated_visits_;
  119. // The callback called on the main thread on completion.
  120. Callback callback_;
  121. };
  122. } // namespace history_clusters
  123. #endif // COMPONENTS_HISTORY_CLUSTERS_CORE_HISTORY_CLUSTERS_DB_TASKS_H_