1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SSL_DAILY_NAVIGATION_COUNTER_H_
#define CHROME_BROWSER_SSL_DAILY_NAVIGATION_COUNTER_H_
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/values.h"
namespace base {
class Clock;
}
// This class records the number of navigations inside a rolling window. Each
// navigation is counted in its day's bucket. Counts are regularly saved to
// a dictionary which can be backed by a pref, so that the counts are persisted.
// Counts belonging to the days outside the rolling window are discarded.
// This class is only intended to count an approximate the number of
// navigations for HTTPS-First Mode related heuristics. Browser restarts or
// crashes may lose some counts which shouldn't affect the heuristics
// significantly.
class DailyNavigationCounter {
public:
// `dict` is the backing dictionary where counts are read from and saved to.
// `clock` is the clock used to get time.
// `rolling_window_duration_in_days` is the size of the rolling window during
// which navigations are recorded. Counts outside this window will be
// discarded. E.g. rolling_window_duration_in_days=1 means counts added two
// days ago will be discarded today.
// `save_interval` is the number of navigations after which the counts are
// saved to `dict`.
DailyNavigationCounter(base::Value::Dict* dict,
base::Clock* clock,
size_t rolling_window_duration_in_days,
size_t save_interval);
virtual ~DailyNavigationCounter();
// Returns the total number of navigations.
size_t GetTotal() const;
// Increments the number of navigations for this day. Returns true if the
// counts are written to `dict`.
bool Increment();
// Returns the number of navigations that are in memory but not yet saved
// to the dict.
size_t unsaved_count_for_testing() const { return unsaved_count_; }
private:
raw_ptr<base::Value::Dict> dict_;
raw_ptr<base::Clock> clock_;
// Number of navigations that haven't been saved in the pref yet.
int unsaved_count_ = 0;
// Age of the oldest navigation to be counted. Anything older than this will
// be discarded.
size_t rolling_window_duration_in_days_;
// If the number of unsaved navigations is larger than this, counts will be
// saved to the dict.
int save_interval_ = 10;
// The map that counts the navigations. Keys are dates formatted as
// yyyy-MM-DD, values are the number of navigations on that day. At any point,
// there will be at most (save_interval_ + rolling_window_duration_in_days)
// different keys in this map. After that, entries will be written into
// dict_, discarding old entries.
//
// This could be a simple integer, but that would would prevent us from
// discarding very old counts when the profile wasn't used for a long time.
// E.g. 99 navigations made 20 days ago, then zero for 20 days, then one
// navigation next day would return 100 navigations in total instead of one,
// if save_interval_=100.
base::flat_map<std::string, int> counts_map_;
};
#endif // CHROME_BROWSER_SSL_DAILY_NAVIGATION_COUNTER_H_
|