Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(827)

Side by Side Diff: chrome/browser/budget_service/budget_database.cc

Issue 2199763002: Add in expiring budget (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@budget_database
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/budget_service/budget_database.h" 5 #include "chrome/browser/budget_service/budget_database.h"
6 6
7 #include "base/containers/adapters.h" 7 #include "base/containers/adapters.h"
8 #include "base/time/clock.h" 8 #include "base/time/clock.h"
9 #include "base/time/default_clock.h" 9 #include "base/time/default_clock.h"
10 #include "chrome/browser/budget_service/budget.pb.h" 10 #include "chrome/browser/budget_service/budget.pb.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 76
77 base::Time now = 77 base::Time now =
78 clock_->Now() + base::TimeDelta::FromHours(kBudgetDurationInHours); 78 clock_->Now() + base::TimeDelta::FromHours(kBudgetDurationInHours);
79 info_iter->second.second.push_back( 79 info_iter->second.second.push_back(
80 std::make_pair(amount, now.ToInternalValue())); 80 std::make_pair(amount, now.ToInternalValue()));
81 81
82 // Now that the cache is updated, write the data to the database. 82 // Now that the cache is updated, write the data to the database.
83 WriteCachedValuesToDatabase(origin, callback); 83 WriteCachedValuesToDatabase(origin, callback);
84 } 84 }
85 85
86 void BudgetDatabase::WriteCachedValuesToDatabase(
harkness 2016/08/01 09:49:06 This just moved to the bottom of the file to mirro
87 const GURL& origin,
88 const StoreBudgetCallback& callback) {
89 // Create the data structures that are passed to the ProtoDatabase.
90 std::unique_ptr<
91 leveldb_proto::ProtoDatabase<budget_service::Budget>::KeyEntryVector>
92 entries(new leveldb_proto::ProtoDatabase<
93 budget_service::Budget>::KeyEntryVector());
94 std::unique_ptr<std::vector<std::string>> keys_to_remove(
95 new std::vector<std::string>());
96
97 // Each operation can either update the existing budget or remove the origin's
98 // budget information.
99 if (budget_map_.find(origin.spec()) == budget_map_.end()) {
100 // If the origin doesn't exist in the cache, this is a remove operation.
101 keys_to_remove->push_back(origin.spec());
102 } else {
103 // Build the Budget proto object.
104 budget_service::Budget budget;
105 const BudgetInfo& info = budget_map_[origin.spec()];
106 budget.set_debt(info.first);
107 for (const auto& chunk : info.second) {
108 budget_service::BudgetChunk* budget_chunk = budget.add_budget();
109 budget_chunk->set_amount(chunk.first);
110 budget_chunk->set_expiration(chunk.second);
111 }
112 entries->push_back(std::make_pair(origin.spec(), budget));
113 }
114
115 // Send the updates to the database.
116 db_->UpdateEntries(std::move(entries), std::move(keys_to_remove), callback);
117 }
118
119 void BudgetDatabase::OnDatabaseInit(bool success) { 86 void BudgetDatabase::OnDatabaseInit(bool success) {
120 // TODO(harkness): Consider caching the budget database now? 87 // TODO(harkness): Consider caching the budget database now?
121 } 88 }
122 89
123 void BudgetDatabase::AddToCache( 90 void BudgetDatabase::AddToCache(
124 const GURL& origin, 91 const GURL& origin,
125 const AddToCacheCallback& callback, 92 const AddToCacheCallback& callback,
126 bool success, 93 bool success,
127 std::unique_ptr<budget_service::Budget> budget_proto) { 94 std::unique_ptr<budget_service::Budget> budget_proto) {
128 // If the database read failed, there's nothing to add to the cache. 95 // If the database read failed, there's nothing to add to the cache.
(...skipping 17 matching lines...) Expand all
146 void BudgetDatabase::DidGetBudget(const GURL& origin, 113 void BudgetDatabase::DidGetBudget(const GURL& origin,
147 const GetBudgetDetailsCallback& callback, 114 const GetBudgetDetailsCallback& callback,
148 bool success) { 115 bool success) {
149 // If the database wasn't able to read the information, return the 116 // If the database wasn't able to read the information, return the
150 // failure and an empty BudgetExpectation. 117 // failure and an empty BudgetExpectation.
151 if (!success) { 118 if (!success) {
152 callback.Run(success, 0, BudgetExpectation()); 119 callback.Run(success, 0, BudgetExpectation());
153 return; 120 return;
154 } 121 }
155 122
156 // Otherwise, build up the BudgetExpection. This is different from the format 123 // First, cleanup any expired budget chunks for the origin.
124 CleanupExpiredBudget(origin);
125
126 // Now, build up the BudgetExpection. This is different from the format
157 // in which the cache stores the data. The cache stores chunks of budget and 127 // in which the cache stores the data. The cache stores chunks of budget and
158 // when that budget expires. The BudgetExpectation describes a set of times 128 // when that budget expires. The BudgetExpectation describes a set of times
159 // and the budget at those times. 129 // and the budget at those times.
160 const BudgetInfo& info = budget_map_[origin.spec()]; 130 const BudgetInfo& info = budget_map_[origin.spec()];
161 BudgetExpectation expectation; 131 BudgetExpectation expectation;
162 double total = 0; 132 double total = 0;
163 133
164 // Starting with the chunks that expire the farthest in the future, build up 134 // Starting with the chunks that expire the farthest in the future, build up
165 // the budget expectations for those future times. 135 // the budget expectations for those future times.
166 for (const auto& chunk : base::Reversed(info.second)) { 136 for (const auto& chunk : base::Reversed(info.second)) {
167 expectation.push_front(std::make_pair(total, chunk.second)); 137 expectation.push_front(std::make_pair(total, chunk.second));
168 total += chunk.first; 138 total += chunk.first;
169 } 139 }
170 140
171 // Always add one entry at the front of the list for the total budget right 141 // Always add one entry at the front of the list for the total budget right
172 // now. 142 // now.
173 expectation.push_front(std::make_pair(total, 0)); 143 expectation.push_front(
144 std::make_pair(total, clock_->Now().ToInternalValue()));
Peter Beverloo 2016/08/01 17:35:28 Sorry that I missed this before- the GetBudgetDeta
harkness 2016/08/08 14:42:43 Done.
174 145
175 callback.Run(true /* success */, info.first, expectation); 146 callback.Run(true /* success */, info.first, expectation);
176 } 147 }
177 148
178 // Override the default clock with the specified clock. Only used for testing. 149 // Override the default clock with the specified clock. Only used for testing.
179 void BudgetDatabase::SetClockForTesting(std::unique_ptr<base::Clock> clock) { 150 void BudgetDatabase::SetClockForTesting(std::unique_ptr<base::Clock> clock) {
180 clock_ = std::move(clock); 151 clock_ = std::move(clock);
181 } 152 }
153
154 void BudgetDatabase::WriteCachedValuesToDatabase(
155 const GURL& origin,
156 const StoreBudgetCallback& callback) {
157 // First, cleanup any expired budget chunks for the origin.
158 CleanupExpiredBudget(origin);
159
160 // Create the data structures that are passed to the ProtoDatabase.
161 std::unique_ptr<
162 leveldb_proto::ProtoDatabase<budget_service::Budget>::KeyEntryVector>
163 entries(new leveldb_proto::ProtoDatabase<
164 budget_service::Budget>::KeyEntryVector());
165 std::unique_ptr<std::vector<std::string>> keys_to_remove(
166 new std::vector<std::string>());
167
168 // Each operation can either update the existing budget or remove the origin's
169 // budget information.
170 if (budget_map_.find(origin.spec()) == budget_map_.end()) {
171 // If the origin doesn't exist in the cache, this is a remove operation.
172 keys_to_remove->push_back(origin.spec());
173 } else {
174 // Build the Budget proto object.
175 budget_service::Budget budget;
176 const BudgetInfo& info = budget_map_[origin.spec()];
177 budget.set_debt(info.first);
178 for (const auto& chunk : info.second) {
179 budget_service::BudgetChunk* budget_chunk = budget.add_budget();
180 budget_chunk->set_amount(chunk.first);
181 budget_chunk->set_expiration(chunk.second);
182 }
183 entries->push_back(std::make_pair(origin.spec(), budget));
184 }
185
186 // Send the updates to the database.
187 db_->UpdateEntries(std::move(entries), std::move(keys_to_remove), callback);
188 }
189
190 void BudgetDatabase::CleanupExpiredBudget(const GURL& origin) {
191 if (budget_map_.find(origin.spec()) == budget_map_.end()) {
192 // Nothing to cleanup.
193 return;
Peter Beverloo 2016/08/01 17:35:28 style nit: no comment (redundant), no brackets for
harkness 2016/08/08 14:42:43 Done.
194 }
195
196 double now = clock_->Now().ToInternalValue();
197
198 BudgetChunks& chunks = budget_map_[origin.spec()].second;
199 auto cleanup_iter = chunks.begin();
200
201 // This relies on the list of chunks being in timestamp order.
202 while (cleanup_iter != chunks.end() && cleanup_iter->second <= now) {
203 cleanup_iter = chunks.erase(cleanup_iter);
204 }
Peter Beverloo 2016/08/01 17:35:28 What if |chunks.empty()| is true now?
harkness 2016/08/08 14:42:43 I don't expect budget_map_ to become so large that
205 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698