blob: deeacf3bab5314273099d0f2d84092d0aedcc5d3 [file] [log] [blame]
// 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_