File: site_data_cache_impl.cc

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 (179 lines) | stat: -rw-r--r-- 6,744 bytes parent folder | download | duplicates (9)
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
176
177
178
179
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/performance_manager/persistence/site_data/site_data_cache_impl.h"

#include <set>

#include "base/check.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/functional/callback.h"
#include "base/memory/ptr_util.h"
#include "components/performance_manager/persistence/site_data/leveldb_site_data_store.h"
#include "components/performance_manager/persistence/site_data/site_data_cache_factory.h"
#include "components/performance_manager/persistence/site_data/site_data_writer.h"
#include "components/performance_manager/public/persistence/site_data/site_data_reader.h"

namespace performance_manager {

namespace {

constexpr char kDataStoreDBName[] = "Site Characteristics Database";

}  // namespace

SiteDataCacheImpl::SiteDataCacheImpl(const std::string& browser_context_id,
                                     const base::FilePath& browser_context_path)
    : browser_context_id_(browser_context_id) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  data_store_ = std::make_unique<LevelDBSiteDataStore>(
      browser_context_path.AppendASCII(kDataStoreDBName));

  // Register the debug interface against the browser context. The factory
  // should always exist by the time this is called, since it is created once
  // there's a browser context with keyed services enabled.
  auto* factory = SiteDataCacheFactory::GetInstance();
  CHECK(factory);
  factory->SetDataCacheInspectorForBrowserContext(this, browser_context_id_);
}

SiteDataCacheImpl::SiteDataCacheImpl(const std::string& browser_context_id)
    : browser_context_id_(browser_context_id) {}

SiteDataCacheImpl::~SiteDataCacheImpl() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  SiteDataCacheFactory::GetInstance()->SetDataCacheInspectorForBrowserContext(
      nullptr, browser_context_id_);
}

std::unique_ptr<SiteDataReader> SiteDataCacheImpl::GetReaderForOrigin(
    const url::Origin& origin) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  internal::SiteDataImpl* impl = GetOrCreateFeatureImpl(origin);
  DCHECK(impl);
  SiteDataReader* data_reader = new SiteDataReaderImpl(impl);
  return base::WrapUnique(data_reader);
}

std::unique_ptr<SiteDataWriter> SiteDataCacheImpl::GetWriterForOrigin(
    const url::Origin& origin) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  internal::SiteDataImpl* impl = GetOrCreateFeatureImpl(origin);
  DCHECK(impl);
  SiteDataWriter* data_writer = new SiteDataWriter(impl);
  return base::WrapUnique(data_writer);
}

bool SiteDataCacheImpl::IsRecording() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return true;
}

int SiteDataCacheImpl::Size() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return origin_data_map_.size();
}

const char* SiteDataCacheImpl::GetDataCacheName() {
  return "SiteDataCache";
}

std::vector<url::Origin> SiteDataCacheImpl::GetAllInMemoryOrigins() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  std::vector<url::Origin> ret;

  ret.reserve(origin_data_map_.size());
  for (const auto& entry : origin_data_map_)
    ret.push_back(entry.first);

  return ret;
}

void SiteDataCacheImpl::GetDataStoreSize(DataStoreSizeCallback on_have_data) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  data_store_->GetStoreSize(std::move(on_have_data));
}

bool SiteDataCacheImpl::GetDataForOrigin(const url::Origin& origin,
                                         bool* is_dirty,
                                         std::unique_ptr<SiteDataProto>* data) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK_NE(nullptr, data);
  const auto it = origin_data_map_.find(origin);
  if (it == origin_data_map_.end())
    return false;

  std::unique_ptr<SiteDataProto> ret = std::make_unique<SiteDataProto>();
  ret->CopyFrom(it->second->FlushStateToProto());
  *is_dirty = it->second->is_dirty();
  *data = std::move(ret);
  return true;
}

SiteDataCacheImpl* SiteDataCacheImpl::GetDataCache() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return this;
}

internal::SiteDataImpl* SiteDataCacheImpl::GetOrCreateFeatureImpl(
    const url::Origin& origin) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // Start by checking if there's already an entry for this origin.
  auto iter = origin_data_map_.find(origin);
  if (iter != origin_data_map_.end())
    return iter->second;

  // If not create a new one and add it to the map.
  internal::SiteDataImpl* site_data = new internal::SiteDataImpl(
      origin, weak_factory_.GetWeakPtr(), data_store_.get());

  // internal::SiteDataImpl is a ref-counted object, it's safe to store a raw
  // pointer to it here as this class will get notified when it's about to be
  // destroyed and it'll be removed from the map.
  origin_data_map_.insert(std::make_pair(origin, site_data));
  return site_data;
}

void SiteDataCacheImpl::OnSiteDataImplDestroyed(internal::SiteDataImpl* impl) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(impl);
  DCHECK(base::Contains(origin_data_map_, impl->origin()));
  // Remove the entry for this origin as this is about to get destroyed.
  auto num_erased = origin_data_map_.erase(impl->origin());
  DCHECK_EQ(1U, num_erased);
}

void SiteDataCacheImpl::ClearSiteDataForOrigins(
    const std::vector<url::Origin>& origins_to_remove) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // It's not necessary to invalidate the pending DB write operations as they
  // run on a sequenced task and so it's guaranteed that the remove operations
  // posted here will run after any other pending operation.
  for (const auto& it : origins_to_remove) {
    auto map_iter = origin_data_map_.find(it);
    if (map_iter != origin_data_map_.end())
      map_iter->second->ClearObservationsAndInvalidateReadOperation();
  }

  data_store_->RemoveSiteDataFromStore(origins_to_remove);
}

void SiteDataCacheImpl::ClearAllSiteData() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  // It's not necessary to invalidate the pending DB write operations as they
  // run on a sequenced task and so it's guaranteed that the remove operations
  // posted here will run after any other pending operation.
  for (auto& data : origin_data_map_)
    data.second->ClearObservationsAndInvalidateReadOperation();
  data_store_->ClearStore();
}

void SiteDataCacheImpl::SetInitializationCallbackForTesting(
    base::OnceClosure callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  data_store_->SetInitializationCallbackForTesting(std::move(callback));
}

}  // namespace performance_manager