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

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

Issue 2188953004: Adding more functionality to BudgetDatabase. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
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"
9 #include "base/time/default_clock.h"
8 #include "chrome/browser/budget_service/budget.pb.h" 10 #include "chrome/browser/budget_service/budget.pb.h"
9 #include "components/leveldb_proto/proto_database_impl.h" 11 #include "components/leveldb_proto/proto_database_impl.h"
10 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
11 #include "url/gurl.h" 13 #include "url/gurl.h"
12 14
13 using content::BrowserThread; 15 using content::BrowserThread;
14 16
15 namespace { 17 namespace {
16 18
17 // UMA are logged for the database with this string as part of the name. 19 // UMA are logged for the database with this string as part of the name.
18 // They will be LevelDB.*.BackgroundBudgetService. Changes here should be 20 // They will be LevelDB.*.BackgroundBudgetService. Changes here should be
19 // synchronized with histograms.xml. 21 // synchronized with histograms.xml.
20 const char kDatabaseUMAName[] = "BackgroundBudgetService"; 22 const char kDatabaseUMAName[] = "BackgroundBudgetService";
21 23
24 // The default amount of time during which a budget will be valid.
25 // This is 3 days = 72 hours.
26 constexpr double kBudgetDurationInHours = 72.0;
Peter Beverloo 2016/08/01 17:33:08 nit: no ".0"
harkness 2016/08/03 11:17:47 Done.
27
22 } // namespace 28 } // namespace
23 29
24 BudgetDatabase::BudgetDatabase( 30 BudgetDatabase::BudgetDatabase(
25 const base::FilePath& database_dir, 31 const base::FilePath& database_dir,
26 const scoped_refptr<base::SequencedTaskRunner>& task_runner) 32 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
27 : db_(new leveldb_proto::ProtoDatabaseImpl<budget_service::Budget>( 33 : db_(new leveldb_proto::ProtoDatabaseImpl<budget_service::Budget>(
28 task_runner)), 34 task_runner)),
35 clock_(base::WrapUnique(new base::DefaultClock)),
29 weak_ptr_factory_(this) { 36 weak_ptr_factory_(this) {
30 db_->Init(kDatabaseUMAName, database_dir, 37 db_->Init(kDatabaseUMAName, database_dir,
31 base::Bind(&BudgetDatabase::OnDatabaseInit, 38 base::Bind(&BudgetDatabase::OnDatabaseInit,
32 weak_ptr_factory_.GetWeakPtr())); 39 weak_ptr_factory_.GetWeakPtr()));
33 } 40 }
34 41
35 BudgetDatabase::~BudgetDatabase() {} 42 BudgetDatabase::~BudgetDatabase() {}
36 43
37 // TODO(harkness): Remove this method once the replacement is available.
38 void BudgetDatabase::GetValue(const GURL& origin,
39 const GetValueCallback& callback) {
40 DCHECK_EQ(origin.GetOrigin(), origin);
41 db_->GetEntry(origin.spec(), callback);
42 }
43
44 void BudgetDatabase::SetValue(const GURL& origin,
45 const budget_service::Budget& budget,
46 const SetValueCallback& callback) {
47 DCHECK_EQ(origin.GetOrigin(), origin);
48
49 // TODO(harkness) Remove this method once the replacement is available.
50
51 // Build structures to hold the updated values.
52 std::unique_ptr<
53 leveldb_proto::ProtoDatabase<budget_service::Budget>::KeyEntryVector>
54 entries(new leveldb_proto::ProtoDatabase<
55 budget_service::Budget>::KeyEntryVector());
56 entries->push_back(std::make_pair(origin.spec(), budget));
57 std::unique_ptr<std::vector<std::string>> keys_to_remove(
58 new std::vector<std::string>());
59
60 // Send the updates to the database.
61 db_->UpdateEntries(std::move(entries), std::move(keys_to_remove), callback);
62 }
63
64 void BudgetDatabase::GetBudgetDetails( 44 void BudgetDatabase::GetBudgetDetails(
65 const GURL& origin, 45 const GURL& origin,
66 const GetBudgetDetailsCallback& callback) { 46 const GetBudgetDetailsCallback& callback) {
67 DCHECK_EQ(origin.GetOrigin(), origin); 47 DCHECK_EQ(origin.GetOrigin(), origin);
68 48
69 // If this origin is already in the cache, immediately return the data. 49 // If this origin is already in the cache, immediately return the data.
70 if (budget_map_.find(origin.spec()) != budget_map_.end()) { 50 if (budget_map_.find(origin.spec()) != budget_map_.end()) {
71 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 51 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
72 base::Bind(&BudgetDatabase::DidGetBudget, 52 base::Bind(&BudgetDatabase::DidGetBudget,
73 weak_ptr_factory_.GetWeakPtr(), origin, 53 weak_ptr_factory_.GetWeakPtr(), origin,
74 callback, true /* success */)); 54 callback, true /* success */));
75 return; 55 return;
76 } 56 }
77 57
78 // Otherwise, query for the data, add it to the cache, then return the result. 58 // Otherwise, query for the data, add it to the cache, then return the result.
79 AddToCacheCallback cache_callback = 59 AddToCacheCallback cache_callback =
80 base::Bind(&BudgetDatabase::DidGetBudget, weak_ptr_factory_.GetWeakPtr(), 60 base::Bind(&BudgetDatabase::DidGetBudget, weak_ptr_factory_.GetWeakPtr(),
81 origin, callback); 61 origin, callback);
82 db_->GetEntry(origin.spec(), base::Bind(&BudgetDatabase::AddToCache, 62 db_->GetEntry(origin.spec(), base::Bind(&BudgetDatabase::AddToCache,
83 weak_ptr_factory_.GetWeakPtr(), 63 weak_ptr_factory_.GetWeakPtr(),
84 origin, cache_callback)); 64 origin, cache_callback));
85 } 65 }
86 66
67 void BudgetDatabase::AddBudget(const GURL& origin,
68 double amount,
69 const StoreBudgetCallback& callback) {
70 DCHECK_EQ(origin.GetOrigin(), origin);
71
72 // Look up the origin in our cache. We don't support adding budget without
73 // having first queried for the existing budget.
Peter Beverloo 2016/08/01 17:33:08 nit: try to avoid "we"
harkness 2016/08/03 11:17:48 Done.
74 const auto& info_iter = budget_map_.find(origin.spec());
75 DCHECK(info_iter != budget_map_.end());
76
77 base::Time now =
Peter Beverloo 2016/08/01 17:33:09 now + 72 hours != |now| :-)
harkness 2016/08/03 11:17:47 tsk tsk.
78 clock_->Now() + base::TimeDelta::FromHours(kBudgetDurationInHours);
79 info_iter->second.second.push_back(
80 std::make_pair(amount, now.ToInternalValue()));
Peter Beverloo 2016/08/01 17:33:09 "info_iter->second.second" is rather unreadable.
harkness 2016/08/03 11:17:48 Good idea, updated.
81
82 // Now that the cache is updated, write the data to the database.
83 WriteCachedValuesToDatabase(origin, callback);
84 }
85
86 void BudgetDatabase::WriteCachedValuesToDatabase(
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());
Peter Beverloo 2016/08/01 17:33:08 Let's remove this case until there is a ClearBudge
harkness 2016/08/03 11:17:48 This case is possible once expiration is around, w
Peter Beverloo 2016/08/03 13:40:12 Ok. In general, try to minimize unused code :).
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
87 void BudgetDatabase::OnDatabaseInit(bool success) { 119 void BudgetDatabase::OnDatabaseInit(bool success) {
88 // TODO(harkness): Consider caching the budget database now? 120 // TODO(harkness): Consider caching the budget database now?
89 } 121 }
90 122
91 void BudgetDatabase::AddToCache( 123 void BudgetDatabase::AddToCache(
92 const GURL& origin, 124 const GURL& origin,
93 const AddToCacheCallback& callback, 125 const AddToCacheCallback& callback,
94 bool success, 126 bool success,
95 std::unique_ptr<budget_service::Budget> budget_proto) { 127 std::unique_ptr<budget_service::Budget> budget_proto) {
96 // If the database read failed, there's nothing to add to the cache. 128 // If the database read failed, there's nothing to add to the cache.
97 if (!success) { 129 if (!success || !budget_proto) {
98 callback.Run(success); 130 callback.Run(success);
99 return; 131 return;
100 } 132 }
101 133
102 // Add the data to the cache, converting from the proto format to an STL 134 // Add the data to the cache, converting from the proto format to an STL
103 // format which is better for removing things from the list. 135 // format which is better for removing things from the list.
104 BudgetChunks chunks; 136 BudgetChunks chunks;
105 for (const auto& chunk : budget_proto->budget()) 137 for (const auto& chunk : budget_proto->budget())
106 chunks.push_back(std::make_pair(chunk.amount(), chunk.expiration())); 138 chunks.push_back(std::make_pair(chunk.amount(), chunk.expiration()));
107 139
108 budget_map_[origin.spec()] = 140 double debt = budget_proto->has_debt() ? budget_proto->debt() : 0;
Peter Beverloo 2016/08/01 17:33:08 DCHECK(budget_proto->has_debt())? When wouldn't i
harkness 2016/08/03 11:17:47 That's true, maybe I was just being overly cautiou
Peter Beverloo 2016/08/03 13:40:11 So let's have a DCHECK() and continue on that assu
harkness 2016/08/08 12:59:35 Done.
109 std::make_pair(budget_proto->debt(), std::move(chunks)); 141 budget_map_[origin.spec()] = std::make_pair(debt, std::move(chunks));
110 142
111 callback.Run(success); 143 callback.Run(success);
112 } 144 }
113 145
114 void BudgetDatabase::DidGetBudget(const GURL& origin, 146 void BudgetDatabase::DidGetBudget(const GURL& origin,
115 const GetBudgetDetailsCallback& callback, 147 const GetBudgetDetailsCallback& callback,
116 bool success) { 148 bool success) {
117 // If the database wasn't able to read the information, return the 149 // If the database wasn't able to read the information, return the
118 // failure and an empty BudgetExpectation. 150 // failure and an empty BudgetExpectation.
119 if (!success) { 151 if (!success) {
(...skipping 15 matching lines...) Expand all
135 expectation.push_front(std::make_pair(total, chunk.second)); 167 expectation.push_front(std::make_pair(total, chunk.second));
136 total += chunk.first; 168 total += chunk.first;
137 } 169 }
138 170
139 // Always add one entry at the front of the list for the total budget right 171 // Always add one entry at the front of the list for the total budget right
140 // now. 172 // now.
141 expectation.push_front(std::make_pair(total, 0)); 173 expectation.push_front(std::make_pair(total, 0));
142 174
143 callback.Run(true /* success */, info.first, expectation); 175 callback.Run(true /* success */, info.first, expectation);
144 } 176 }
177
178 // Override the default clock with the specified clock. Only used for testing.
Peter Beverloo 2016/08/01 17:33:09 nit: redundant with header file
harkness 2016/08/03 11:17:47 Generally when a method has a gotcha like "SHould
Peter Beverloo 2016/08/03 13:40:11 It's doubly redundant with the comment in the head
harkness 2016/08/08 12:59:35 Done.
179 void BudgetDatabase::SetClockForTesting(std::unique_ptr<base::Clock> clock) {
180 clock_ = std::move(clock);
181 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698