OLD | NEW |
---|---|
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 "content/browser/indexed_db/indexed_db_context_impl.h" | 5 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 info->SetDouble("last_modified", | 180 info->SetDouble("last_modified", |
181 GetOriginLastModified(origin_url).ToJsTime()); | 181 GetOriginLastModified(origin_url).ToJsTime()); |
182 info->SetString("path", GetFilePath(origin_url).value()); | 182 info->SetString("path", GetFilePath(origin_url).value()); |
183 info->SetDouble("connection_count", GetConnectionCount(origin_url)); | 183 info->SetDouble("connection_count", GetConnectionCount(origin_url)); |
184 | 184 |
185 // This ends up being O(n^2) since we iterate over all open databases | 185 // This ends up being O(n^2) since we iterate over all open databases |
186 // to extract just those in the origin, and we're iterating over all | 186 // to extract just those in the origin, and we're iterating over all |
187 // origins in the outer loop. | 187 // origins in the outer loop. |
188 | 188 |
189 if (factory_) { | 189 if (factory_) { |
190 std::vector<IndexedDBDatabase*> databases = | 190 std::pair<IndexedDBFactory::OriginDbMapIterator, |
191 IndexedDBFactory::OriginDbMapIterator> range = | |
191 factory_->GetOpenDatabasesForOrigin(origin_url); | 192 factory_->GetOpenDatabasesForOrigin(origin_url); |
192 // TODO(jsbell): Sort by name? | 193 // TODO(jsbell): Sort by name? |
193 scoped_ptr<base::ListValue> database_list(new base::ListValue()); | 194 scoped_ptr<base::ListValue> database_list(new base::ListValue()); |
194 | 195 |
195 for (std::vector<IndexedDBDatabase*>::iterator it = databases.begin(); | 196 for (IndexedDBFactory::OriginDbMapIterator it = range.first; |
196 it != databases.end(); | 197 it != range.second; |
197 ++it) { | 198 ++it) { |
198 | 199 |
199 const IndexedDBDatabase* db = *it; | 200 const IndexedDBDatabase* db = it->second; |
200 scoped_ptr<base::DictionaryValue> db_info(new base::DictionaryValue()); | 201 scoped_ptr<base::DictionaryValue> db_info(new base::DictionaryValue()); |
201 | 202 |
202 db_info->SetString("name", db->name()); | 203 db_info->SetString("name", db->name()); |
203 db_info->SetDouble("pending_opens", db->PendingOpenCount()); | 204 db_info->SetDouble("pending_opens", db->PendingOpenCount()); |
204 db_info->SetDouble("pending_upgrades", db->PendingUpgradeCount()); | 205 db_info->SetDouble("pending_upgrades", db->PendingUpgradeCount()); |
205 db_info->SetDouble("running_upgrades", db->RunningUpgradeCount()); | 206 db_info->SetDouble("running_upgrades", db->RunningUpgradeCount()); |
206 db_info->SetDouble("pending_deletes", db->PendingDeleteCount()); | 207 db_info->SetDouble("pending_deletes", db->PendingDeleteCount()); |
207 db_info->SetDouble("connection_count", | 208 db_info->SetDouble("connection_count", |
208 db->ConnectionCount() - db->PendingUpgradeCount() - | 209 db->ConnectionCount() - db->PendingUpgradeCount() - |
209 db->RunningUpgradeCount()); | 210 db->RunningUpgradeCount()); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 origin_size_map_.erase(origin_url); | 330 origin_size_map_.erase(origin_url); |
330 space_available_map_.erase(origin_url); | 331 space_available_map_.erase(origin_url); |
331 } | 332 } |
332 } | 333 } |
333 | 334 |
334 void IndexedDBContextImpl::ForceClose(const GURL origin_url) { | 335 void IndexedDBContextImpl::ForceClose(const GURL origin_url) { |
335 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 336 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
336 if (data_path_.empty() || !IsInOriginSet(origin_url)) | 337 if (data_path_.empty() || !IsInOriginSet(origin_url)) |
337 return; | 338 return; |
338 | 339 |
339 if (connections_.find(origin_url) != connections_.end()) { | 340 if (factory_) { |
340 ConnectionSet& connections = connections_[origin_url]; | 341 factory_->ForceClose(origin_url); |
341 ConnectionSet::iterator it = connections.begin(); | 342 DCHECK_EQ(0UL, GetConnectionCount(origin_url)); |
342 while (it != connections.end()) { | |
343 // Remove before closing so callbacks don't double-erase | |
344 IndexedDBConnection* connection = *it; | |
345 DCHECK(connection->IsConnected()); | |
346 connections.erase(it++); | |
347 connection->ForceClose(); | |
348 } | |
349 DCHECK_EQ(connections_[origin_url].size(), 0UL); | |
350 connections_.erase(origin_url); | |
351 } | 343 } |
352 if (factory_) | |
353 factory_->ForceClose(origin_url); | |
354 } | 344 } |
355 | 345 |
356 size_t IndexedDBContextImpl::GetConnectionCount(const GURL& origin_url) { | 346 size_t IndexedDBContextImpl::GetConnectionCount(const GURL& origin_url) { |
357 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 347 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
358 if (data_path_.empty() || !IsInOriginSet(origin_url)) | 348 if (data_path_.empty() || !IsInOriginSet(origin_url)) |
359 return 0; | 349 return 0; |
360 | 350 |
361 if (connections_.find(origin_url) == connections_.end()) | 351 if (!factory_) |
362 return 0; | 352 return 0; |
363 | 353 |
364 return connections_[origin_url].size(); | 354 return factory_->GetConnectionCount(origin_url); |
365 } | 355 } |
366 | 356 |
367 base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) const { | 357 base::FilePath IndexedDBContextImpl::GetFilePath(const GURL& origin_url) const { |
368 std::string origin_id = webkit_database::GetIdentifierFromOrigin(origin_url); | 358 std::string origin_id = webkit_database::GetIdentifierFromOrigin(origin_url); |
369 return GetIndexedDBFilePath(origin_id); | 359 return GetIndexedDBFilePath(origin_id); |
370 } | 360 } |
371 | 361 |
372 base::FilePath IndexedDBContextImpl::GetFilePathForTesting( | 362 base::FilePath IndexedDBContextImpl::GetFilePathForTesting( |
373 const std::string& origin_id) const { | 363 const std::string& origin_id) const { |
374 return GetIndexedDBFilePath(origin_id); | 364 return GetIndexedDBFilePath(origin_id); |
375 } | 365 } |
376 | 366 |
377 void IndexedDBContextImpl::SetTaskRunnerForTesting( | 367 void IndexedDBContextImpl::SetTaskRunnerForTesting( |
378 base::SequencedTaskRunner* task_runner) { | 368 base::SequencedTaskRunner* task_runner) { |
379 DCHECK(!task_runner_); | 369 DCHECK(!task_runner_); |
380 task_runner_ = task_runner; | 370 task_runner_ = task_runner; |
381 } | 371 } |
382 | 372 |
383 void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url, | 373 void IndexedDBContextImpl::ConnectionOpened(const GURL& origin_url, |
384 IndexedDBConnection* connection) { | 374 IndexedDBConnection* connection) { |
385 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 375 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
386 DCHECK_EQ(connections_[origin_url].count(connection), 0UL); | |
387 if (quota_manager_proxy()) { | 376 if (quota_manager_proxy()) { |
388 quota_manager_proxy()->NotifyStorageAccessed( | 377 quota_manager_proxy()->NotifyStorageAccessed( |
389 quota::QuotaClient::kIndexedDatabase, | 378 quota::QuotaClient::kIndexedDatabase, |
390 origin_url, | 379 origin_url, |
391 quota::kStorageTypeTemporary); | 380 quota::kStorageTypeTemporary); |
392 } | 381 } |
393 connections_[origin_url].insert(connection); | |
394 if (AddToOriginSet(origin_url)) { | 382 if (AddToOriginSet(origin_url)) { |
395 // A newly created db, notify the quota system. | 383 // A newly created db, notify the quota system. |
396 QueryDiskAndUpdateQuotaUsage(origin_url); | 384 QueryDiskAndUpdateQuotaUsage(origin_url); |
397 } else { | 385 } else { |
398 EnsureDiskUsageCacheInitialized(origin_url); | 386 EnsureDiskUsageCacheInitialized(origin_url); |
399 } | 387 } |
400 QueryAvailableQuota(origin_url); | 388 QueryAvailableQuota(origin_url); |
401 } | 389 } |
402 | 390 |
403 void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url, | 391 void IndexedDBContextImpl::ConnectionClosed(const GURL& origin_url, |
404 IndexedDBConnection* connection) { | 392 IndexedDBConnection* connection) { |
405 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); | 393 DCHECK(TaskRunner()->RunsTasksOnCurrentThread()); |
406 // May not be in the map if connection was forced to close | |
407 if (connections_.find(origin_url) == connections_.end() || | |
408 connections_[origin_url].count(connection) != 1) | |
409 return; | |
410 if (quota_manager_proxy()) { | 394 if (quota_manager_proxy()) { |
411 quota_manager_proxy()->NotifyStorageAccessed( | 395 quota_manager_proxy()->NotifyStorageAccessed( |
412 quota::QuotaClient::kIndexedDatabase, | 396 quota::QuotaClient::kIndexedDatabase, |
413 origin_url, | 397 origin_url, |
414 quota::kStorageTypeTemporary); | 398 quota::kStorageTypeTemporary); |
415 } | 399 } |
416 connections_[origin_url].erase(connection); | 400 if (factory_ && factory_->GetConnectionCount(origin_url) == 0) |
417 if (connections_[origin_url].size() == 0) { | |
418 QueryDiskAndUpdateQuotaUsage(origin_url); | 401 QueryDiskAndUpdateQuotaUsage(origin_url); |
419 connections_.erase(origin_url); | |
420 } | |
421 } | 402 } |
422 | 403 |
423 void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) { | 404 void IndexedDBContextImpl::TransactionComplete(const GURL& origin_url) { |
424 DCHECK(connections_.find(origin_url) != connections_.end() && | 405 if (factory_) { |
425 connections_[origin_url].size() > 0); | 406 DCHECK(factory_->GetConnectionCount(origin_url) > 0); |
jsbell
2014/01/03 00:34:25
Suggest rewriting as:
DCHECK(!factory_ || factory
cmumford
2014/01/03 21:34:01
Done.
| |
407 } | |
426 QueryDiskAndUpdateQuotaUsage(origin_url); | 408 QueryDiskAndUpdateQuotaUsage(origin_url); |
427 QueryAvailableQuota(origin_url); | 409 QueryAvailableQuota(origin_url); |
428 } | 410 } |
429 | 411 |
430 void IndexedDBContextImpl::DatabaseDeleted(const GURL& origin_url) { | 412 void IndexedDBContextImpl::DatabaseDeleted(const GURL& origin_url) { |
431 AddToOriginSet(origin_url); | 413 AddToOriginSet(origin_url); |
432 QueryDiskAndUpdateQuotaUsage(origin_url); | 414 QueryDiskAndUpdateQuotaUsage(origin_url); |
433 QueryAvailableQuota(origin_url); | 415 QueryAvailableQuota(origin_url); |
434 } | 416 } |
435 | 417 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
582 origin_set_.reset(); | 564 origin_set_.reset(); |
583 origin_size_map_.clear(); | 565 origin_size_map_.clear(); |
584 space_available_map_.clear(); | 566 space_available_map_.clear(); |
585 } | 567 } |
586 | 568 |
587 base::TaskRunner* IndexedDBContextImpl::TaskRunner() const { | 569 base::TaskRunner* IndexedDBContextImpl::TaskRunner() const { |
588 return task_runner_; | 570 return task_runner_; |
589 } | 571 } |
590 | 572 |
591 } // namespace content | 573 } // namespace content |
OLD | NEW |