| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "components/sync_driver/revisit/offset_tab_matcher.h" | |
| 6 | |
| 7 #include "base/metrics/histogram_macros.h" | |
| 8 #include "base/metrics/sparse_histogram.h" | |
| 9 #include "components/sessions/core/serialized_navigation_entry.h" | |
| 10 | |
| 11 namespace sync_driver { | |
| 12 | |
| 13 namespace { | |
| 14 | |
| 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; | |
| 22 | |
| 23 } // namespace | |
| 24 | |
| 25 OffsetTabMatcher::OffsetTabMatcher(const PageEquality& page_equality) | |
| 26 : page_equality_(page_equality) {} | |
| 27 | |
| 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; | |
| 40 } | |
| 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; | |
| 47 } | |
| 48 } | |
| 49 } | |
| 50 | |
| 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); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 int OffsetTabMatcher::Clamp(const int input, const int lower, const int upper) { | |
| 76 return std::max(lower, std::min(upper, input)); | |
| 77 } | |
| 78 | |
| 79 } // namespace sync_driver | |
| OLD | NEW |