Home | History | Annotate | Download | only in history
      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.
     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".
     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 
     90   void set_sorting_order(SortingOrder order) {
     91     sorting_order_ = order;
     92     UpdateTimeVector();
     93   }
     94 
     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