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

Side by Side Diff: webkit/dom_storage/dom_storage_area.cc

Issue 10389061: DomStorageArea: Allow multiple simultaneous in flight commit batches. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review. Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « webkit/dom_storage/dom_storage_area.h ('k') | webkit/dom_storage/dom_storage_area_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "webkit/dom_storage/dom_storage_area.h" 5 #include "webkit/dom_storage/dom_storage_area.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 } 53 }
54 54
55 DomStorageArea::DomStorageArea( 55 DomStorageArea::DomStorageArea(
56 int64 namespace_id, const GURL& origin, 56 int64 namespace_id, const GURL& origin,
57 const FilePath& directory, DomStorageTaskRunner* task_runner) 57 const FilePath& directory, DomStorageTaskRunner* task_runner)
58 : namespace_id_(namespace_id), origin_(origin), 58 : namespace_id_(namespace_id), origin_(origin),
59 directory_(directory), 59 directory_(directory),
60 task_runner_(task_runner), 60 task_runner_(task_runner),
61 map_(new DomStorageMap(kPerAreaQuota)), 61 map_(new DomStorageMap(kPerAreaQuota)),
62 is_initial_import_done_(true), 62 is_initial_import_done_(true),
63 is_shutdown_(false) { 63 is_shutdown_(false),
64 commit_batches_in_flight_(0) {
64 if (namespace_id == kLocalStorageNamespaceId && !directory.empty()) { 65 if (namespace_id == kLocalStorageNamespaceId && !directory.empty()) {
65 FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_)); 66 FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_));
66 backing_.reset(new DomStorageDatabase(path)); 67 backing_.reset(new DomStorageDatabase(path));
67 is_initial_import_done_ = false; 68 is_initial_import_done_ = false;
68 } 69 }
69 } 70 }
70 71
71 DomStorageArea::~DomStorageArea() { 72 DomStorageArea::~DomStorageArea() {
72 } 73 }
73 74
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 155
155 DomStorageArea* copy = new DomStorageArea(destination_namespace_id, origin_, 156 DomStorageArea* copy = new DomStorageArea(destination_namespace_id, origin_,
156 FilePath(), task_runner_); 157 FilePath(), task_runner_);
157 copy->map_ = map_; 158 copy->map_ = map_;
158 copy->is_shutdown_ = is_shutdown_; 159 copy->is_shutdown_ = is_shutdown_;
159 return copy; 160 return copy;
160 } 161 }
161 162
162 bool DomStorageArea::HasUncommittedChanges() const { 163 bool DomStorageArea::HasUncommittedChanges() const {
163 DCHECK(!is_shutdown_); 164 DCHECK(!is_shutdown_);
164 return commit_batch_.get() || in_flight_commit_batch_.get(); 165 return commit_batch_.get() || commit_batches_in_flight_;
165 } 166 }
166 167
167 void DomStorageArea::DeleteOrigin() { 168 void DomStorageArea::DeleteOrigin() {
168 DCHECK(!is_shutdown_); 169 DCHECK(!is_shutdown_);
169 if (HasUncommittedChanges()) { 170 if (HasUncommittedChanges()) {
170 // TODO(michaeln): This logically deletes the data immediately, 171 // TODO(michaeln): This logically deletes the data immediately,
171 // and in a matter of a second, deletes the rows from the backing 172 // and in a matter of a second, deletes the rows from the backing
172 // database file, but the file itself will linger until shutdown 173 // database file, but the file itself will linger until shutdown
173 // or purge time. Ideally, this should delete the file more 174 // or purge time. Ideally, this should delete the file more
174 // quickly. 175 // quickly.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 backing_->ReadAllValues(&initial_values); 227 backing_->ReadAllValues(&initial_values);
227 map_->SwapValues(&initial_values); 228 map_->SwapValues(&initial_values);
228 is_initial_import_done_ = true; 229 is_initial_import_done_ = true;
229 } 230 }
230 231
231 DomStorageArea::CommitBatch* DomStorageArea::CreateCommitBatchIfNeeded() { 232 DomStorageArea::CommitBatch* DomStorageArea::CreateCommitBatchIfNeeded() {
232 DCHECK(!is_shutdown_); 233 DCHECK(!is_shutdown_);
233 if (!commit_batch_.get()) { 234 if (!commit_batch_.get()) {
234 commit_batch_.reset(new CommitBatch()); 235 commit_batch_.reset(new CommitBatch());
235 236
236 // Start a timer to commit any changes that accrue in the batch, 237 // Start a timer to commit any changes that accrue in the batch, but only if
237 // but only if a commit is not currently in flight. In that case 238 // no commits are currently in flight. In that case the timer will be
238 // the timer will be started after the current commit has happened. 239 // started after the commits have happened.
239 if (!in_flight_commit_batch_.get()) { 240 if (!commit_batches_in_flight_) {
240 task_runner_->PostDelayedTask( 241 task_runner_->PostDelayedTask(
241 FROM_HERE, 242 FROM_HERE,
242 base::Bind(&DomStorageArea::OnCommitTimer, this), 243 base::Bind(&DomStorageArea::OnCommitTimer, this),
243 base::TimeDelta::FromSeconds(kCommitTimerSeconds)); 244 base::TimeDelta::FromSeconds(kCommitTimerSeconds));
244 } 245 }
245 } 246 }
246 return commit_batch_.get(); 247 return commit_batch_.get();
247 } 248 }
248 249
249 void DomStorageArea::OnCommitTimer() { 250 void DomStorageArea::OnCommitTimer() {
250 DCHECK_EQ(kLocalStorageNamespaceId, namespace_id_); 251 DCHECK_EQ(kLocalStorageNamespaceId, namespace_id_);
251 if (is_shutdown_) 252 if (is_shutdown_)
252 return; 253 return;
253 254
254 DCHECK(backing_.get()); 255 DCHECK(backing_.get());
255 DCHECK(commit_batch_.get()); 256 DCHECK(commit_batch_.get());
256 DCHECK(!in_flight_commit_batch_.get()); 257 DCHECK(!commit_batches_in_flight_);
257 258
258 // This method executes on the primary sequence, we schedule 259 // This method executes on the primary sequence, we schedule
259 // a task for immediate execution on the commit sequence. 260 // a task for immediate execution on the commit sequence.
260 DCHECK(task_runner_->IsRunningOnPrimarySequence()); 261 DCHECK(task_runner_->IsRunningOnPrimarySequence());
261 in_flight_commit_batch_ = commit_batch_.Pass();
262 bool success = task_runner_->PostShutdownBlockingTask( 262 bool success = task_runner_->PostShutdownBlockingTask(
263 FROM_HERE, 263 FROM_HERE,
264 DomStorageTaskRunner::COMMIT_SEQUENCE, 264 DomStorageTaskRunner::COMMIT_SEQUENCE,
265 base::Bind(&DomStorageArea::CommitChanges, this)); 265 base::Bind(&DomStorageArea::CommitChanges, this,
266 base::Owned(commit_batch_.release())));
267 ++commit_batches_in_flight_;
266 DCHECK(success); 268 DCHECK(success);
267 } 269 }
268 270
269 void DomStorageArea::CommitChanges() { 271 void DomStorageArea::CommitChanges(const CommitBatch* commit_batch) {
270 // This method executes on the commit sequence. 272 // This method executes on the commit sequence.
271 DCHECK(task_runner_->IsRunningOnCommitSequence()); 273 DCHECK(task_runner_->IsRunningOnCommitSequence());
272 DCHECK(in_flight_commit_batch_.get()); 274 bool success = backing_->CommitChanges(commit_batch->clear_all_first,
273 bool success = backing_->CommitChanges( 275 commit_batch->changed_values);
274 in_flight_commit_batch_->clear_all_first,
275 in_flight_commit_batch_->changed_values);
276 DCHECK(success); // TODO(michaeln): what if it fails? 276 DCHECK(success); // TODO(michaeln): what if it fails?
277 task_runner_->PostTask( 277 task_runner_->PostTask(
278 FROM_HERE, 278 FROM_HERE,
279 base::Bind(&DomStorageArea::OnCommitComplete, this)); 279 base::Bind(&DomStorageArea::OnCommitComplete, this));
280 } 280 }
281 281
282 void DomStorageArea::OnCommitComplete() { 282 void DomStorageArea::OnCommitComplete() {
283 // We're back on the primary sequence in this method. 283 // We're back on the primary sequence in this method.
284 DCHECK(task_runner_->IsRunningOnPrimarySequence()); 284 DCHECK(task_runner_->IsRunningOnPrimarySequence());
285 if (is_shutdown_) 285 if (is_shutdown_)
286 return; 286 return;
287 in_flight_commit_batch_.reset(); 287 --commit_batches_in_flight_;
288 if (commit_batch_.get()) { 288 if (commit_batch_.get() && !commit_batches_in_flight_) {
289 // More changes have accrued, restart the timer. 289 // More changes have accrued, restart the timer.
290 task_runner_->PostDelayedTask( 290 task_runner_->PostDelayedTask(
291 FROM_HERE, 291 FROM_HERE,
292 base::Bind(&DomStorageArea::OnCommitTimer, this), 292 base::Bind(&DomStorageArea::OnCommitTimer, this),
293 base::TimeDelta::FromSeconds(kCommitTimerSeconds)); 293 base::TimeDelta::FromSeconds(kCommitTimerSeconds));
294 } 294 }
295 } 295 }
296 296
297 void DomStorageArea::ShutdownInCommitSequence() { 297 void DomStorageArea::ShutdownInCommitSequence() {
298 // This method executes on the commit sequence. 298 // This method executes on the commit sequence.
299 DCHECK(task_runner_->IsRunningOnCommitSequence()); 299 DCHECK(task_runner_->IsRunningOnCommitSequence());
300 DCHECK(backing_.get()); 300 DCHECK(backing_.get());
301 if (commit_batch_.get()) { 301 if (commit_batch_.get()) {
302 // Commit any changes that accrued prior to the timer firing. 302 // Commit any changes that accrued prior to the timer firing.
303 bool success = backing_->CommitChanges( 303 bool success = backing_->CommitChanges(
304 commit_batch_->clear_all_first, 304 commit_batch_->clear_all_first,
305 commit_batch_->changed_values); 305 commit_batch_->changed_values);
306 DCHECK(success); 306 DCHECK(success);
307 } 307 }
308 commit_batch_.reset(); 308 commit_batch_.reset();
309 in_flight_commit_batch_.reset();
310 backing_.reset(); 309 backing_.reset();
311 } 310 }
312 311
313 } // namespace dom_storage 312 } // namespace dom_storage
OLDNEW
« no previous file with comments | « webkit/dom_storage/dom_storage_area.h ('k') | webkit/dom_storage/dom_storage_area_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698