| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_HISTORY_VISIT_FILTER_H_ |
| #define CHROME_BROWSER_HISTORY_VISIT_FILTER_H_ |
| |
| #include <vector> |
| |
| #include "base/gtest_prod_util.h" |
| #include "base/time/time.h" |
| |
| namespace history { |
| |
| class VisitRow; |
| |
| // Helper class for creation of filters for VisitDatabase that is used to filter |
| // out visits by time of the day, day of the week, workdays, holidays, duration |
| // of the visit, location and the combinations of that. |
| // It also stores sorting order of the returned resilts. |
| class VisitFilter { |
| public: |
| VisitFilter(); |
| virtual ~VisitFilter(); |
| |
| // Vector of time intervals [begin time, end time]. All of the following |
| // functions produce vectors that are sorted in order from most recent to |
| // least recent and have intervals that do not intersect. |
| // |first| always points to the beginning of the time period, |second| - to |
| // the end. |
| typedef std::vector<std::pair<base::Time, base::Time> > TimeVector; |
| |
| // Returns time vector associated with the object. |
| const TimeVector& times() const { |
| return times_; |
| } |
| |
| // Sets |max_results| of the results to be returned. 0 means "return results |
| // for the two months prior to passed time". |
| void set_max_results(size_t max_results) { |
| max_results_ = max_results; |
| if (times_.size() > max_results_) |
| times_.resize(max_results_); |
| } |
| |
| // Sets the time that should be used as a basis for the filter. Normally this |
| // is the time that a query is made. |
| void SetFilterTime(const base::Time& filter_time); |
| |
| // Sets the amount of time around the filter time to take into account. This |
| // only applies to the filter time's time-of-day, restrictions on how long |
| // back in time to look should be controlled by changing |max_results|. |
| // |
| // How the filter width is used depends on the sorting order. For |
| // |ORDER_BY_TIME_LINEAR| it is the distance to the cutoff point, while for |
| // |ORDER_BY_TIME_GAUSSIAN| it is the standard deviation. |
| void SetFilterWidth(const base::TimeDelta& filter_width); |
| |
| // The following two filters are exclusive - setting one, clears the other |
| // one. |
| |
| // Sets the filter to use only visits that happened on the specified day of |
| // the week. |
| // |day| - day of the week: 0 - sunday, 1 - monday, etc. |
| void SetDayOfTheWeekFilter(int day); |
| |
| // Sets the filter to use only visits that happened on a holiday/workday. |
| // |workday| - if true means Monday-Friday, if false means Saturday-Sunday. |
| // TODO(georgey) - internationalize it. |
| void SetDayTypeFilter(bool workday); |
| |
| // Sorting order that results after applying this filter are sorted by. |
| enum SortingOrder { |
| ORDER_BY_RECENCY, // Most recent visits are most relevant ones. (default) |
| ORDER_BY_VISIT_COUNT, // Most visited are listed first. |
| ORDER_BY_DURATION_SPENT, // The sites that user spents more time in are |
| // sorted first. |
| ORDER_BY_TIME_GAUSSIAN, // Visits that happened closer to the filter time's |
| // time-of-day are scored higher. The dropoff in |
| // score follows a normal distribution curve with |
| // the filter width as the standard deviation. |
| ORDER_BY_TIME_LINEAR, // Visits that happened closer to the filter time's |
| // time-of-day are score higher. The dropoff in score |
| // is a linear function, with filter width being the |
| // point where a visit does not count at all anymore. |
| }; |
| |
| double GetVisitScore(const VisitRow& visit) const; |
| |
| void set_sorting_order(SortingOrder order) { |
| sorting_order_ = order; |
| UpdateTimeVector(); |
| } |
| |
| SortingOrder sorting_order() const { |
| return sorting_order_; |
| } |
| |
| // Clears all of the filters. |
| void ClearFilters(); |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, CheckFilters); |
| FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesInRange); |
| FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesOnTheDayOfTheWeek); |
| FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, GetTimesOnTheSameDayType); |
| FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, UniteTimeVectors); |
| FRIEND_TEST_ALL_PREFIXES(VisitFilterTest, IntersectTimeVectors); |
| |
| // Internal helper for the update. |
| bool UpdateTimeVector(); |
| |
| // Internal helper for getting the times in range. See SetTimeInRangeFilter(). |
| static void GetTimesInRange(base::Time begin_time_of_the_day, |
| base::Time end_time_of_the_day, |
| size_t max_results, |
| TimeVector* times); |
| |
| // Internal helper for getting the days in range. See SetDayOfTheWeekFilter(). |
| // |day| could be outside of the range: -4 (3 - 7) means Wednesday last week, |
| // 17 (3 + 2 * 7) means Wednesday in two weeks. |
| static void GetTimesOnTheDayOfTheWeek(int day, |
| base::Time week, |
| size_t max_results, |
| TimeVector* times); |
| |
| // Internal helper for getting the days in range. See SetDayTypeFilter(). |
| static void GetTimesOnTheSameDayType(bool workday, |
| base::Time week, |
| size_t max_results, |
| TimeVector* times); |
| |
| // Unites two vectors, so the new vector has non-intersecting union of the |
| // original ranges. Returns true if the result is non-empty, false otherwise. |
| static bool UniteTimeVectors(const TimeVector& vector1, |
| const TimeVector& vector2, |
| TimeVector* result); |
| |
| // Intersects two vectors, so the new vector has ranges that are covered by |
| // both of the original ranges. Returns true if the result is non-empty, false |
| // otherwise. |
| static bool IntersectTimeVectors(const TimeVector& vector1, |
| const TimeVector& vector2, |
| TimeVector* result); |
| |
| // Returns the time-of-day difference between the two times. The result will |
| // always represent a value between 0 and 12 hours inclusive. |
| static base::TimeDelta GetTimeOfDayDifference(base::Time t1, base::Time t2); |
| |
| base::Time filter_time_; |
| base::TimeDelta filter_width_; |
| enum { |
| DAY_UNDEFINED = -1, |
| WORKDAY = 7, |
| HOLIDAY = 8, |
| }; |
| int day_; |
| TimeVector times_; |
| size_t max_results_; |
| SortingOrder sorting_order_; |
| }; |
| |
| } // history |
| |
| #endif // CHROME_BROWSER_HISTORY_VISIT_FILTER_H_ |