Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / components / sync_driver / revisit / offset_tab_matcher.cc
blob7d99e0ce682461a4781d0f844b82dc4afb9ff4ae
1 // Copyright 2015 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.
5 #include "components/sync_driver/revisit/offset_tab_matcher.h"
7 #include "base/metrics/histogram_macros.h"
8 #include "base/metrics/sparse_histogram.h"
9 #include "components/sessions/serialized_navigation_entry.h"
11 namespace sync_driver {
13 namespace {
15 // This is an upper bound of the max size of positive offset we will emit
16 // correct metrics for. Anything larger than this will be clamped to this value.
17 // This value doesn't exactly correspond to what we actually expect, this value
18 // is currently larger than expected. This value is more for the safety of our
19 // sparse histogram usage. It is assumed that the max negative offset is
20 // symmetrical and can be found by taking the negative of this value.
21 const int kMaxOffset = 10;
23 } // namespace
25 OffsetTabMatcher::OffsetTabMatcher(const PageEquality& page_equality)
26 : page_equality_(page_equality) {}
28 void OffsetTabMatcher::Check(const sessions::SessionTab* tab) {
29 const int current_index = tab->normalized_navigation_index();
30 for (std::size_t i = 0; i < tab->navigations.size(); ++i) {
31 // Ignore the entry if it is the current entry. There's actually some
32 // ambiguity here, the index of a tab is located in two places. Hopefully
33 // they are equal, but it is possible for the index() accessor of an entry
34 // to be different from the index in the tab's vector. Theoretically this
35 // should not happen outside of tab construction logic, but to be safe all
36 // matcher logic treats the index in the vector as the authoritative index.
37 // We chose this because the other matcher wants efficient random access.
38 if (current_index >= 0 && (std::size_t)current_index == i) {
39 continue;
41 const int offset = i - current_index;
42 if (page_equality_.IsSamePage(tab->navigations[i].virtual_url()) &&
43 (best_tab_ == nullptr || best_tab_->timestamp < tab->timestamp ||
44 (best_tab_->timestamp == tab->timestamp && best_offset_ < offset))) {
45 best_tab_ = tab;
46 best_offset_ = offset;
51 void OffsetTabMatcher::Emit(
52 const PageVisitObserver::TransitionType transition) {
53 if (best_tab_ == nullptr) {
54 UMA_HISTOGRAM_ENUMERATION("Sync.PageRevisitNavigationMissTransition",
55 transition,
56 PageVisitObserver::kTransitionTypeLast);
57 } else {
58 // The sparse macro allows us to handle negative offsets. However, we need
59 // to be careful when doing this because of the unrestricted nature of
60 // sparse we could end up with a very large output space across many
61 // clients. So we clamp on a resonable bound that's larger than we expect to
62 // be sure no unexpected data causes problems.
63 UMA_HISTOGRAM_SPARSE_SLOWLY("Sync.PageRevisitNavigationMatchOffset",
64 Clamp(best_offset_, -kMaxOffset, kMaxOffset));
65 UMA_HISTOGRAM_CUSTOM_TIMES("Sync.PageRevisitNavigationMatchAge",
66 (base::Time::Now() - best_tab_->timestamp),
67 base::TimeDelta::FromSeconds(1),
68 base::TimeDelta::FromDays(14), 100);
69 UMA_HISTOGRAM_ENUMERATION("Sync.PageRevisitNavigationMatchTransition",
70 transition,
71 PageVisitObserver::kTransitionTypeLast);
75 int OffsetTabMatcher::Clamp(const int input, const int lower, const int upper) {
76 return std::max(lower, std::min(upper, input));
79 } // namespace sync_driver