summaryrefslogtreecommitdiff
path: root/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h
blob: 212285ebe1425641158a51f48b6ece80c71affc1 (plain)
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// 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 NET_EXTRAS_SQLITE_SQLITE_PERSISTENT_SHARED_DICTIONARY_STORE_H_
#define NET_EXTRAS_SQLITE_SQLITE_PERSISTENT_SHARED_DICTIONARY_STORE_H_

#include <map>
#include <set>
#include <vector>

#include "base/component_export.h"
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/unguessable_token.h"
#include "net/extras/shared_dictionary/shared_dictionary_info.h"
#include "net/extras/shared_dictionary/shared_dictionary_usage_info.h"
#include "url/origin.h"

namespace base {
class FilePath;
class SequencedTaskRunner;
}  // namespace base

namespace net {

class SharedDictionaryIsolationKey;

// This class is used for storing SharedDictionary information to the persistent
// storage.
class COMPONENT_EXPORT(NET_EXTRAS) SQLitePersistentSharedDictionaryStore {
 public:
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  enum class Error {
    kOk = 0,
    kFailedToInitializeDatabase = 1,
    kInvalidSql = 2,
    kFailedToExecuteSql = 3,
    kFailedToBeginTransaction = 4,
    kFailedToCommitTransaction = 5,
    kInvalidTotalDictSize = 6,
    kFailedToGetTotalDictSize = 7,
    kFailedToSetTotalDictSize = 8,
    kTooBigDictionary = 9,
    kMaxValue = kTooBigDictionary
  };
  class COMPONENT_EXPORT(NET_EXTRAS) RegisterDictionaryResult {
   public:
    RegisterDictionaryResult(
        int64_t primary_key_in_database,
        absl::optional<base::UnguessableToken> replaced_disk_cache_key_token,
        std::set<base::UnguessableToken> evicted_disk_cache_key_tokens,
        uint64_t total_dictionary_size,
        uint64_t total_dictionary_count);
    ~RegisterDictionaryResult();

    RegisterDictionaryResult(const RegisterDictionaryResult& other);
    RegisterDictionaryResult(RegisterDictionaryResult&& other);
    RegisterDictionaryResult& operator=(const RegisterDictionaryResult& other);
    RegisterDictionaryResult& operator=(RegisterDictionaryResult&& other);

    int64_t primary_key_in_database() const { return primary_key_in_database_; }
    const absl::optional<base::UnguessableToken>&
    replaced_disk_cache_key_token() const {
      return replaced_disk_cache_key_token_;
    }
    const std::set<base::UnguessableToken>& evicted_disk_cache_key_tokens()
        const {
      return evicted_disk_cache_key_tokens_;
    }
    uint64_t total_dictionary_size() const { return total_dictionary_size_; }
    uint64_t total_dictionary_count() const { return total_dictionary_count_; }

   private:
    int64_t primary_key_in_database_;
    absl::optional<base::UnguessableToken> replaced_disk_cache_key_token_;
    std::set<base::UnguessableToken> evicted_disk_cache_key_tokens_;
    uint64_t total_dictionary_size_;
    uint64_t total_dictionary_count_;
  };

  using SizeOrError = base::expected<uint64_t, Error>;
  using RegisterDictionaryResultOrError =
      base::expected<RegisterDictionaryResult, Error>;
  using DictionaryListOrError =
      base::expected<std::vector<SharedDictionaryInfo>, Error>;
  using DictionaryMapOrError = base::expected<
      std::map<SharedDictionaryIsolationKey, std::vector<SharedDictionaryInfo>>,
      Error>;
  using UnguessableTokenSetOrError =
      base::expected<std::set<base::UnguessableToken>, Error>;
  using UsageInfoOrError =
      base::expected<std::vector<SharedDictionaryUsageInfo>, Error>;
  using OriginListOrError = base::expected<std::vector<url::Origin>, Error>;

  SQLitePersistentSharedDictionaryStore(
      const base::FilePath& path,
      const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
      const scoped_refptr<base::SequencedTaskRunner>& background_task_runner);

  SQLitePersistentSharedDictionaryStore(
      const SQLitePersistentSharedDictionaryStore&) = delete;
  SQLitePersistentSharedDictionaryStore& operator=(
      const SQLitePersistentSharedDictionaryStore&) = delete;

  ~SQLitePersistentSharedDictionaryStore();

  void GetTotalDictionarySize(base::OnceCallback<void(SizeOrError)> callback);
  void RegisterDictionary(
      const SharedDictionaryIsolationKey& isolation_key,
      SharedDictionaryInfo dictionary_info,
      const uint64_t max_size_per_site,
      const uint64_t max_count_per_site,
      base::OnceCallback<void(RegisterDictionaryResultOrError)> callback);
  void GetDictionaries(
      const SharedDictionaryIsolationKey& isolation_key,
      base::OnceCallback<void(DictionaryListOrError)> callback);
  void GetAllDictionaries(
      base::OnceCallback<void(DictionaryMapOrError)> callback);
  void GetUsageInfo(base::OnceCallback<void(UsageInfoOrError)> callback);
  void GetOriginsBetween(const base::Time start_time,
                         const base::Time end_time,
                         base::OnceCallback<void(OriginListOrError)> callback);
  void ClearAllDictionaries(base::OnceCallback<void(Error)> callback);
  void ClearDictionaries(
      const base::Time start_time,
      const base::Time end_time,
      base::RepeatingCallback<bool(const GURL&)> url_matcher,
      base::OnceCallback<void(UnguessableTokenSetOrError)> callback);
  void ClearDictionariesForIsolationKey(
      const SharedDictionaryIsolationKey& isolation_key,
      base::OnceCallback<void(UnguessableTokenSetOrError)> callback);
  void DeleteExpiredDictionaries(
      const base::Time now,
      base::OnceCallback<void(UnguessableTokenSetOrError)> callback);
  // Deletes dictionaries in order of `last_used_time` if the total size of all
  // dictionaries exceeds `cache_max_size` or the total dictionary count exceeds
  // `cache_max_count` until the total size reaches `size_low_watermark` and the
  // total count reaches `count_low_watermark`. If `cache_max_size` is zero, the
  // size limitation is ignored.
  void ProcessEviction(
      const uint64_t cache_max_size,
      const uint64_t size_low_watermark,
      const uint64_t cache_max_count,
      const uint64_t count_low_watermark,
      base::OnceCallback<void(UnguessableTokenSetOrError)> callback);
  void GetAllDiskCacheKeyTokens(
      base::OnceCallback<void(UnguessableTokenSetOrError)> callback);
  void DeleteDictionariesByDiskCacheKeyTokens(
      std::set<base::UnguessableToken> disk_cache_key_tokens,
      base::OnceCallback<void(Error)> callback);
  void UpdateDictionaryLastUsedTime(int64_t primary_key_in_database,
                                    base::Time last_used_time);

  base::WeakPtr<SQLitePersistentSharedDictionaryStore> GetWeakPtr();

 private:
  class Backend;

  const scoped_refptr<Backend> backend_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<SQLitePersistentSharedDictionaryStore> weak_factory_
      GUARDED_BY_CONTEXT(sequence_checker_){this};
};

}  // namespace net

#endif  // NET_EXTRAS_SQLITE_SQLITE_PERSISTENT_REPORTING_AND_NEL_STORE_H_