root/chrome/browser/history/visit_filter.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// 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_

/* [<][>][^][v][top][bottom][index][help] */