File: share_ranking.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (152 lines) | stat: -rw-r--r-- 5,618 bytes parent folder | download | duplicates (6)
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright 2021 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_SHARE_SHARE_RANKING_H_
#define CHROME_BROWSER_SHARE_SHARE_RANKING_H_

#include <optional>

#include "base/callback_list.h"
#include "base/containers/flat_map.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "build/build_config.h"
#include "chrome/browser/share/proto/share_ranking_message.pb.h"
#include "chrome/browser/share/share_history.h"
#include "components/leveldb_proto/public/proto_database.h"

class Profile;

namespace sharing {

class ShareHistory;

class ShareRanking : public base::SupportsUserData::Data {
 public:
  using Ranking = std::vector<std::string>;

  using BackingDb = leveldb_proto::ProtoDatabase<proto::ShareRanking>;
  using GetRankingCallback =
      base::OnceCallback<void(std::optional<Ranking> result)>;

  static ShareRanking* Get(Profile* profile);

  explicit ShareRanking(Profile* profile,
                        std::unique_ptr<BackingDb> backing_db = nullptr);
  ~ShareRanking() override;

  void UpdateRanking(const std::string& type, Ranking ranking);
  void GetRanking(const std::string& type, GetRankingCallback callback);

  // This method:
  // 1. Fetches the existing rankings and histories for |type| from the provided
  //    databases
  // 2. Runs the ranking algorithm (see below).
  // 3. If |persist_update|, writes the new ranking back to |ranking|
  // 4. Returns the display ranking to use for this specific share
  void Rank(ShareHistory* history,
            const std::string& type,
            const std::vector<std::string>& available_on_system,
            size_t fold,
            size_t length,
            bool persist_update,
            GetRankingCallback callback);

  void Clear(const base::Time& start = base::Time(),
             const base::Time& end = base::Time());

  // The core of the ranking algorithm, exposed as a pure function for ease of
  // testing and reasoning about the code. This function takes the existing
  // share history and ranking for this type, a set of all targets available on
  // the current system, and a length, and computes the new display ranking and
  // the new persistent ranking.
  //
  // TODO(ellyjones): Document (publicly) how this works and why.
  static void ComputeRanking(
      const std::map<std::string, int>& all_share_history,
      const std::map<std::string, int>& recent_share_history,
      const Ranking& old_ranking,
      const std::vector<std::string>& available_on_system,
      size_t fold,
      size_t length,
      Ranking* display_ranking,
      Ranking* persisted_ranking);

  static const char* const kMoreTarget;

  void set_initial_ranking_for_test(Ranking ranking) {
    initial_ranking_for_test_ = ranking;
  }

 private:
  // A PendingRankCall represents a call to Rank() that is in progress; an
  // object of this type is threaded through the async calls used by Rank() to
  // pass state from one step to the next.
  struct PendingRankCall {
    PendingRankCall();
    ~PendingRankCall();

    // These members mirror the parameters passed in to Rank().
    std::string type;
    std::vector<std::string> available_on_system;
    size_t fold;
    size_t length;
    bool persist_update;
    GetRankingCallback callback;

    // This is the ShareHistory passed into Rank(), held as a WeakPtr in case
    // the Rank() call is pending across profile teardown.
    base::WeakPtr<ShareHistory> history_db;

    // These are intermediate results generated by async steps of Rank(),
    // accumulated into the PendingRankCall for later use.
    std::vector<ShareHistory::Target> all_history;
    std::vector<ShareHistory::Target> recent_history;
  };

  void Init();
  void OnInitDone(leveldb_proto::Enums::InitStatus status);
  void OnBackingGetDone(std::string key,
                        GetRankingCallback callback,
                        bool ok,
                        std::unique_ptr<proto::ShareRanking> ranking);

  void FlushToBackingDb(const std::string& key);

  // Steps of the state machine for Rank() - in order, that method:
  // 1. Fetches all history for the given type
  // 2. Fetches recent history for the given type
  // 3. Fetches the existing ranking for the given type
  // Each of these steps is asynchronous and the On*Done methods are used for
  // their completion callbacks.
  void OnRankGetAllDone(std::unique_ptr<PendingRankCall> pending,
                        std::vector<ShareHistory::Target> history);
  void OnRankGetRecentDone(std::unique_ptr<PendingRankCall> pending,
                           std::vector<ShareHistory::Target> history);
  void OnRankGetOldRankingDone(std::unique_ptr<PendingRankCall> pending,
                               std::optional<Ranking> ranking);

  // Return the default initial ranking, which depends on the current locale.
  Ranking GetDefaultInitialRankingForType(const std::string& type);

  bool init_finished_ = false;
  leveldb_proto::Enums::InitStatus db_init_status_;

  base::OnceClosureList post_init_callbacks_;

  std::unique_ptr<BackingDb> db_;

  // Cached ranking values, which are used when populated; otherwise they are
  // fetched from the backing database. Updates to this are written back to the
  // backing database by FlushToBackingDb().
  base::flat_map<std::string, Ranking> ranking_;

  std::optional<Ranking> initial_ranking_for_test_;

  base::WeakPtrFactory<ShareRanking> weak_factory_{this};
};

}  // namespace sharing

#endif  // CHROME_BROWSER_SHARE_SHARE_RANKING_H_