• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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