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() {
21 DCHECK(use_tracker_
.empty());
24 void IndexedDBActiveBlobRegistry::AddBlobRef(int64 database_id
,
26 DCHECK(backing_store_
);
27 DCHECK(backing_store_
->task_runner()->RunsTasksOnCurrentThread());
28 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
29 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key
));
30 DCHECK(!ContainsKey(deleted_dbs_
, database_id
));
31 bool need_ref
= use_tracker_
.empty();
32 SingleDBMap
& single_db_map
= use_tracker_
[database_id
];
33 SingleDBMap::iterator iter
= single_db_map
.find(blob_key
);
34 if (iter
== single_db_map
.end()) {
35 single_db_map
[blob_key
] = false;
37 backing_store_
->factory()->ReportOutstandingBlobs(
38 backing_store_
->origin_url(), true);
42 DCHECK(!iter
->second
); // You can't add a reference once it's been deleted.
46 void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64 database_id
,
48 DCHECK(backing_store_
);
49 DCHECK(backing_store_
->task_runner()->RunsTasksOnCurrentThread());
50 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
51 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key
));
52 AllDBsMap::iterator db_pair
= use_tracker_
.find(database_id
);
53 if (db_pair
== use_tracker_
.end()) {
57 SingleDBMap
& single_db
= db_pair
->second
;
58 SingleDBMap::iterator blob_pair
= single_db
.find(blob_key
);
59 if (blob_pair
== single_db
.end()) {
63 bool delete_in_backend
= false;
64 DeletedDBSet::iterator db_to_delete
= deleted_dbs_
.find(database_id
);
65 bool db_marked_for_deletion
= db_to_delete
!= deleted_dbs_
.end();
66 // Don't bother deleting the file if we're going to delete its whole
67 // database directory soon.
68 delete_in_backend
= blob_pair
->second
&& !db_marked_for_deletion
;
69 single_db
.erase(blob_pair
);
70 if (single_db
.empty()) {
71 use_tracker_
.erase(db_pair
);
72 if (db_marked_for_deletion
) {
73 delete_in_backend
= true;
74 blob_key
= DatabaseMetaDataKey::kAllBlobsKey
;
75 deleted_dbs_
.erase(db_to_delete
);
78 if (delete_in_backend
)
79 backing_store_
->ReportBlobUnused(database_id
, blob_key
);
80 if (use_tracker_
.empty()) {
81 backing_store_
->factory()->ReportOutstandingBlobs(
82 backing_store_
->origin_url(), false);
86 bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64 database_id
,
88 DCHECK(backing_store_
);
89 DCHECK(backing_store_
->task_runner()->RunsTasksOnCurrentThread());
90 DCHECK(KeyPrefix::IsValidDatabaseId(database_id
));
91 AllDBsMap::iterator db_pair
= use_tracker_
.find(database_id
);
92 if (db_pair
== use_tracker_
.end())
95 if (blob_key
== DatabaseMetaDataKey::kAllBlobsKey
) {
96 deleted_dbs_
.insert(database_id
);
100 SingleDBMap
& single_db
= db_pair
->second
;
101 SingleDBMap::iterator iter
= single_db
.find(blob_key
);
102 if (iter
== single_db
.end())
109 void IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe(
110 scoped_refptr
<base::TaskRunner
> task_runner
,
111 base::WeakPtr
<IndexedDBActiveBlobRegistry
> weak_ptr
,
114 const base::FilePath
& unused
) {
115 task_runner
->PostTask(FROM_HERE
,
116 base::Bind(&IndexedDBActiveBlobRegistry::ReleaseBlobRef
,
122 webkit_blob::ShareableFileReference::FinalReleaseCallback
123 IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(int64 database_id
,
126 &IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe
,
127 scoped_refptr
<base::TaskRunner
>(backing_store_
->task_runner()),
128 weak_factory_
.GetWeakPtr(),
133 base::Closure
IndexedDBActiveBlobRegistry::GetAddBlobRefCallback(
136 return base::Bind(&IndexedDBActiveBlobRegistry::AddBlobRef
,
137 weak_factory_
.GetWeakPtr(),
142 void IndexedDBActiveBlobRegistry::ForceShutdown() {
143 weak_factory_
.InvalidateWeakPtrs();
144 use_tracker_
.clear();
145 backing_store_
= NULL
;
148 } // namespace content