1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_HISTORY_VISIT_FILTER_H_ 6 #define CHROME_BROWSER_HISTORY_VISIT_FILTER_H_ 7 8 #include <vector> 9 10 #include "base/gtest_prod_util.h" 11 #include "base/time/time.h" 12 13 namespace history { 14 15 class VisitRow; 16 17 // Helper class for creation of filters for VisitDatabase that is used to filter 18 // out visits by time of the day, day of the week, workdays, holidays, duration 19 // of the visit, location and the combinations of that. 20 // It also stores sorting order of the returned resilts. 21 class VisitFilter { 22 public: 23 VisitFilter(); 24 virtual ~VisitFilter(); 25 26 // Vector of time intervals [begin time, end time]. All of the following 27 // functions produce vectors that are sorted in order from most recent to 28 // least recent and have intervals that do not intersect. 29 // |first| always points to the beginning of the time period, |second| - to 30 // the end. 31 typedef std::vector<std::pair<base::Time, base::Time> > TimeVector; 32 33 // Returns time vector associated with the object. times()34 const TimeVector& times() const { 35 return times_; 36 } 37 38 // Sets |max_results| of the results to be returned. 0 means "return results 39 // for the two months prior to passed time". set_max_results(size_t max_results)40 void set_max_results(size_t max_results) { 41 max_results_ = max_results; 42 if (times_.size() > max_results_) 43 times_.resize(max_results_); 44 } 45 46 // Sets the time that should be used as a basis for the filter. Normally this 47 // is the time that a query is made. 48 void SetFilterTime(const base::Time& filter_time); 49 50 // Sets the amount of time around the filter time to take into account. This 51 // only applies to the filter time's time-of-day, restrictions on how long 52 // back in time to look should be controlled by changing |max_results|. 53 // 54 // How the filter width is used depends on the sorting order. For 55 // |ORDER_BY_TIME_LINEAR| it is the distance to the cutoff point, while for 56 // |ORDER_BY_TIME_GAUSSIAN| it is the standard deviation. 57 void SetFilterWidth(const base::TimeDelta& filter_width); 58 59 // The following two filters are exclusive - setting one, clears the other 60 // one. 61 62 // Sets the filter to use only visits that happened on the specified day of 63 // the week. 64 // |day| - day of the week: 0 - sunday, 1 - monday, etc. 65 void SetDayOfTheWeekFilter(int day); 66 67 // Sets the filter to use only visits that happened on a holiday/workday. 68 // |workday| - if true means Monday-Friday, if false means Saturday-Sunday. 69 // TODO(georgey) - internationalize it. 70 void SetDayTypeFilter(bool workday); 71 72 // Sorting order that results after applying this filter are sorted by. 73 enum SortingOrder { 74 ORDER_BY_RECENCY, // Most recent visits are most relevant ones. (default) 75 ORDER_BY_VISIT_COUNT, // Most visited are listed first. 76 ORDER_BY_DURATION_SPENT, // The sites that user spents more time in are 77 // sorted first. 78 ORDER_BY_TIME_GAUSSIAN, // Visits that happened closer to the filter time's 79 // time-of-day are scored higher. The dropoff in 80 // score follows a normal distribution curve with 81 // the filter width as the standard deviation. 82 ORDER_BY_TIME_LINEAR, // Visits that happened closer to the filter time's 83 // time-of-day are score higher. The dropoff in score 84 // is a linear function, with filter width being the 85 // point where a visit does not count at all anymore. 86 }; 87 88 double GetVisitScore(const VisitRow& visit) const; 89 set_sorting_order(SortingOrder order)90 void set_sorting_order(SortingOrder order) { 91 sorting_order_ = order; 92 UpdateTimeVector(); 93 } 94 sorting_order()95 SortingOrder sorting_order() const { 96 return sorting_order_; 97 } 98 99 // Clears all of the filters. 100 void ClearFilters(); 101 102 private: 103 FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, CheckFilters); 104 FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesInRange); 105 FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesOnTheDayOfTheWeek); 106 FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesOnTheSameDayType); 107 FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, UniteTimeVectors); 108 FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, IntersectTimeVectors); 109 110 // Internal helper for the update. 111 bool UpdateTimeVector(); 112 113 // Internal helper for getting the times in range. See SetTimeInRangeFilter(). 114 static void GetTimesInRange(base::Time begin_time_of_the_day, 115 base::Time end_time_of_the_day, 116 size_t max_results, 117 TimeVector* times); 118 119 // Internal helper for getting the days in range. See SetDayOfTheWeekFilter(). 120 // |day| could be outside of the range: -4 (3 - 7) means Wednesday last week, 121 // 17 (3 + 2 * 7) means Wednesday in two weeks. 122 static void GetTimesOnTheDayOfTheWeek(int day, 123 base::Time week, 124 size_t max_results, 125 TimeVector* times); 126 127 // Internal helper for getting the days in range. See SetDayTypeFilter(). 128 static void GetTimesOnTheSameDayType(bool workday, 129 base::Time week, 130 size_t max_results, 131 TimeVector* times); 132 133 // Unites two vectors, so the new vector has non-intersecting union of the 134 // original ranges. Returns true if the result is non-empty, false otherwise. 135 static bool UniteTimeVectors(const TimeVector& vector1, 136 const TimeVector& vector2, 137 TimeVector* result); 138 139 // Intersects two vectors, so the new vector has ranges that are covered by 140 // both of the original ranges. Returns true if the result is non-empty, false 141 // otherwise. 142 static bool IntersectTimeVectors(const TimeVector& vector1, 143 const TimeVector& vector2, 144 TimeVector* result); 145 146 // Returns the time-of-day difference between the two times. The result will 147 // always represent a value between 0 and 12 hours inclusive. 148 static base::TimeDelta GetTimeOfDayDifference(base::Time t1, base::Time t2); 149 150 base::Time filter_time_; 151 base::TimeDelta filter_width_; 152 enum { 153 DAY_UNDEFINED = -1, 154 WORKDAY = 7, 155 HOLIDAY = 8, 156 }; 157 int day_; 158 TimeVector times_; 159 size_t max_results_; 160 SortingOrder sorting_order_; 161 }; 162 163 } // history 164 165 #endif // CHROME_BROWSER_HISTORY_VISIT_FILTER_H_ 166