1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/location.h"
7 #include "base/stl_util.h"
8 #include "base/task_runner.h"
9 #include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
10 #include "content/browser/indexed_db/indexed_db_backing_store.h"
11 #include "content/browser/indexed_db/indexed_db_factory.h"
12 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
16 IndexedDBActiveBlobRegistry::IndexedDBActiveBlobRegistry(
17 IndexedDBBackingStore
* backing_store
)
18 : backing_store_(backing_store
), weak_factory_(this) {}
20 IndexedDBActiveBlobRegistry::~IndexedDBActiveBlobRegistry() {
23 void IndexedDBActiveBlobRegistry::AddBlobRef(int64 database_id
,
25 DCHECK(backing_store_
);
26 DCHECK(backing_store_
->task_runner()->RunsTasksOnCurrentThread());
27 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
28 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key
));
29 DCHECK(!ContainsKey(deleted_dbs_
, database_id
));
30 bool need_ref
= use_tracker_
.empty();
31 SingleDBMap
& single_db_map
= use_tracker_
[database_id
];
32 SingleDBMap::iterator iter
= single_db_map
.find(blob_key
);
33 if (iter
== single_db_map
.end()) {
34 single_db_map
[blob_key
] = false;
36 backing_store_
->factory()->ReportOutstandingBlobs(
37 backing_store_
->origin_url(), true);
41 DCHECK(!iter
->second
); // You can't add a reference once it's been deleted.
45 void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64 database_id
,
47 DCHECK(backing_store_
);
48 DCHECK(backing_store_
->task_runner()->RunsTasksOnCurrentThread());
49 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
50 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key
));
51 AllDBsMap::iterator db_pair
= use_tracker_
.find(database_id
);
52 if (db_pair
== use_tracker_
.end()) {
56 SingleDBMap
& single_db
= db_pair
->second
;
57 SingleDBMap::iterator blob_pair
= single_db
.find(blob_key
);
58 if (blob_pair
== single_db
.end()) {
62 bool delete_in_backend
= false;
63 DeletedDBSet::iterator db_to_delete
= deleted_dbs_
.find(database_id
);
64 bool db_marked_for_deletion
= db_to_delete
!= deleted_dbs_
.end();
65 // Don't bother deleting the file if we're going to delete its whole
66 // database directory soon.
67 delete_in_backend
= blob_pair
->second
&& !db_marked_for_deletion
;
68 single_db
.erase(blob_pair
);
69 if (single_db
.empty()) {
70 use_tracker_
.erase(db_pair
);
71 if (db_marked_for_deletion
) {
72 delete_in_backend
= true;
73 blob_key
= DatabaseMetaDataKey::kAllBlobsKey
;
74 deleted_dbs_
.erase(db_to_delete
);
77 if (delete_in_backend
)
78 backing_store_
->ReportBlobUnused(database_id
, blob_key
);
79 if (use_tracker_
.empty()) {
80 backing_store_
->factory()->ReportOutstandingBlobs(
81 backing_store_
->origin_url(), false);
85 bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64 database_id
,
87 DCHECK(backing_store_
);
88 DCHECK(backing_store_
->task_runner()->RunsTasksOnCurrentThread());
89 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
90 AllDBsMap::iterator db_pair
= use_tracker_
.find(database_id
);
91 if (db_pair
== use_tracker_
.end())
94 if (blob_key
== DatabaseMetaDataKey::kAllBlobsKey
) {
95 deleted_dbs_
.insert(database_id
);
99 SingleDBMap
& single_db
= db_pair
->second
;
100 SingleDBMap::iterator iter
= single_db
.find(blob_key
);
101 if (iter
== single_db
.end())
108 void IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe(
109 scoped_refptr
<base::TaskRunner
> task_runner
,
110 base::WeakPtr
<IndexedDBActiveBlobRegistry
> weak_ptr
,
113 const base::FilePath
& unused
) {
114 task_runner
->PostTask(FROM_HERE
,
115 base::Bind(&IndexedDBActiveBlobRegistry::ReleaseBlobRef
,
121 storage::ShareableFileReference::FinalReleaseCallback
122 IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(int64 database_id
,
125 &IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe
,
126 scoped_refptr
<base::TaskRunner
>(backing_store_
->task_runner()),
127 weak_factory_
.GetWeakPtr(),
132 base::Closure
IndexedDBActiveBlobRegistry::GetAddBlobRefCallback(
135 return base::Bind(&IndexedDBActiveBlobRegistry::AddBlobRef
,
136 weak_factory_
.GetWeakPtr(),
141 void IndexedDBActiveBlobRegistry::ForceShutdown() {
142 weak_factory_
.InvalidateWeakPtrs();
143 use_tracker_
.clear();
144 backing_store_
= NULL
;
147 } // namespace content