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

Side by Side Diff: storage/browser/blob/blob_storage_context.cc

Issue 442383002: Move storage-related files from webkit/ to new top-level directory storage/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/browser/blob/blob_storage_context.h" 5 #include "storage/browser/blob/blob_storage_context.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/message_loop/message_loop_proxy.h"
11 #include "url/gurl.h" 11 #include "url/gurl.h"
12 #include "webkit/browser/blob/blob_data_handle.h" 12 #include "storage/browser/blob/blob_data_handle.h"
13 #include "webkit/common/blob/blob_data.h" 13 #include "storage/common/blob/blob_data.h"
14 14
15 namespace webkit_blob { 15 namespace storage {
16 16
17 namespace { 17 namespace {
18 18
19 // We can't use GURL directly for these hash fragment manipulations 19 // We can't use GURL directly for these hash fragment manipulations
20 // since it doesn't have specific knowlege of the BlobURL format. GURL 20 // since it doesn't have specific knowlege of the BlobURL format. GURL
21 // treats BlobURLs as if they were PathURLs which don't support hash 21 // treats BlobURLs as if they were PathURLs which don't support hash
22 // fragments. 22 // fragments.
23 23
24 bool BlobUrlHasRef(const GURL& url) { 24 bool BlobUrlHasRef(const GURL& url) {
25 return url.spec().find('#') != std::string::npos; 25 return url.spec().find('#') != std::string::npos;
26 } 26 }
27 27
28 GURL ClearBlobUrlRef(const GURL& url) { 28 GURL ClearBlobUrlRef(const GURL& url) {
29 size_t hash_pos = url.spec().find('#'); 29 size_t hash_pos = url.spec().find('#');
30 if (hash_pos == std::string::npos) 30 if (hash_pos == std::string::npos)
31 return url; 31 return url;
32 return GURL(url.spec().substr(0, hash_pos)); 32 return GURL(url.spec().substr(0, hash_pos));
33 } 33 }
34 34
35 // TODO(michaeln): use base::SysInfo::AmountOfPhysicalMemoryMB() in some 35 // TODO(michaeln): use base::SysInfo::AmountOfPhysicalMemoryMB() in some
36 // way to come up with a better limit. 36 // way to come up with a better limit.
37 static const int64 kMaxMemoryUsage = 500 * 1024 * 1024; // Half a gig. 37 static const int64 kMaxMemoryUsage = 500 * 1024 * 1024; // Half a gig.
38 38
39 } // namespace 39 } // namespace
40 40
41 BlobStorageContext::BlobMapEntry::BlobMapEntry() 41 BlobStorageContext::BlobMapEntry::BlobMapEntry() : refcount(0), flags(0) {
42 : refcount(0), flags(0) {
43 } 42 }
44 43
45 BlobStorageContext::BlobMapEntry::BlobMapEntry( 44 BlobStorageContext::BlobMapEntry::BlobMapEntry(int refcount,
46 int refcount, int flags, BlobData* data) 45 int flags,
46 BlobData* data)
47 : refcount(refcount), flags(flags), data(data) { 47 : refcount(refcount), flags(flags), data(data) {
48 } 48 }
49 49
50 BlobStorageContext::BlobMapEntry::~BlobMapEntry() { 50 BlobStorageContext::BlobMapEntry::~BlobMapEntry() {
51 } 51 }
52 52
53 BlobStorageContext::BlobStorageContext() 53 BlobStorageContext::BlobStorageContext() : memory_usage_(0) {
54 : memory_usage_(0) {
55 } 54 }
56 55
57 BlobStorageContext::~BlobStorageContext() { 56 BlobStorageContext::~BlobStorageContext() {
58 } 57 }
59 58
60 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID( 59 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID(
61 const std::string& uuid) { 60 const std::string& uuid) {
62 scoped_ptr<BlobDataHandle> result; 61 scoped_ptr<BlobDataHandle> result;
63 BlobMap::iterator found = blob_map_.find(uuid); 62 BlobMap::iterator found = blob_map_.find(uuid);
64 if (found == blob_map_.end()) 63 if (found == blob_map_.end())
65 return result.Pass(); 64 return result.Pass();
66 if (found->second.flags & EXCEEDED_MEMORY) 65 if (found->second.flags & EXCEEDED_MEMORY)
67 return result.Pass(); 66 return result.Pass();
68 DCHECK(!(found->second.flags & BEING_BUILT)); 67 DCHECK(!(found->second.flags & BEING_BUILT));
69 result.reset(new BlobDataHandle( 68 result.reset(new BlobDataHandle(
70 found->second.data.get(), this, base::MessageLoopProxy::current().get())); 69 found->second.data.get(), this, base::MessageLoopProxy::current().get()));
71 return result.Pass(); 70 return result.Pass();
72 } 71 }
73 72
74 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL( 73 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL(
75 const GURL& url) { 74 const GURL& url) {
76 BlobURLMap::iterator found = public_blob_urls_.find( 75 BlobURLMap::iterator found =
77 BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); 76 public_blob_urls_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url);
78 if (found == public_blob_urls_.end()) 77 if (found == public_blob_urls_.end())
79 return scoped_ptr<BlobDataHandle>(); 78 return scoped_ptr<BlobDataHandle>();
80 return GetBlobDataFromUUID(found->second); 79 return GetBlobDataFromUUID(found->second);
81 } 80 }
82 81
83 scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob( 82 scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob(
84 const BlobData* data) { 83 const BlobData* data) {
85 StartBuildingBlob(data->uuid()); 84 StartBuildingBlob(data->uuid());
86 for (std::vector<BlobData::Item>::const_iterator iter = 85 for (std::vector<BlobData::Item>::const_iterator iter = data->items().begin();
87 data->items().begin(); 86 iter != data->items().end();
88 iter != data->items().end(); ++iter) { 87 ++iter) {
89 AppendBlobDataItem(data->uuid(), *iter); 88 AppendBlobDataItem(data->uuid(), *iter);
90 } 89 }
91 FinishBuildingBlob(data->uuid(), data->content_type()); 90 FinishBuildingBlob(data->uuid(), data->content_type());
92 scoped_ptr<BlobDataHandle> handle = GetBlobDataFromUUID(data->uuid()); 91 scoped_ptr<BlobDataHandle> handle = GetBlobDataFromUUID(data->uuid());
93 DecrementBlobRefCount(data->uuid()); 92 DecrementBlobRefCount(data->uuid());
94 return handle.Pass(); 93 return handle.Pass();
95 } 94 }
96 95
97 bool BlobStorageContext::RegisterPublicBlobURL( 96 bool BlobStorageContext::RegisterPublicBlobURL(const GURL& blob_url,
98 const GURL& blob_url, const std::string& uuid) { 97 const std::string& uuid) {
99 DCHECK(!BlobUrlHasRef(blob_url)); 98 DCHECK(!BlobUrlHasRef(blob_url));
100 DCHECK(IsInUse(uuid)); 99 DCHECK(IsInUse(uuid));
101 DCHECK(!IsUrlRegistered(blob_url)); 100 DCHECK(!IsUrlRegistered(blob_url));
102 if (!IsInUse(uuid) || IsUrlRegistered(blob_url)) 101 if (!IsInUse(uuid) || IsUrlRegistered(blob_url))
103 return false; 102 return false;
104 IncrementBlobRefCount(uuid); 103 IncrementBlobRefCount(uuid);
105 public_blob_urls_[blob_url] = uuid; 104 public_blob_urls_[blob_url] = uuid;
106 return true; 105 return true;
107 } 106 }
108 107
109 void BlobStorageContext::RevokePublicBlobURL(const GURL& blob_url) { 108 void BlobStorageContext::RevokePublicBlobURL(const GURL& blob_url) {
110 DCHECK(!BlobUrlHasRef(blob_url)); 109 DCHECK(!BlobUrlHasRef(blob_url));
111 if (!IsUrlRegistered(blob_url)) 110 if (!IsUrlRegistered(blob_url))
112 return; 111 return;
113 DecrementBlobRefCount(public_blob_urls_[blob_url]); 112 DecrementBlobRefCount(public_blob_urls_[blob_url]);
114 public_blob_urls_.erase(blob_url); 113 public_blob_urls_.erase(blob_url);
115 } 114 }
116 115
117 void BlobStorageContext::StartBuildingBlob(const std::string& uuid) { 116 void BlobStorageContext::StartBuildingBlob(const std::string& uuid) {
118 DCHECK(!IsInUse(uuid) && !uuid.empty()); 117 DCHECK(!IsInUse(uuid) && !uuid.empty());
119 blob_map_[uuid] = BlobMapEntry(1, BEING_BUILT, new BlobData(uuid)); 118 blob_map_[uuid] = BlobMapEntry(1, BEING_BUILT, new BlobData(uuid));
120 } 119 }
121 120
122 void BlobStorageContext::AppendBlobDataItem( 121 void BlobStorageContext::AppendBlobDataItem(const std::string& uuid,
123 const std::string& uuid, const BlobData::Item& item) { 122 const BlobData::Item& item) {
124 DCHECK(IsBeingBuilt(uuid)); 123 DCHECK(IsBeingBuilt(uuid));
125 BlobMap::iterator found = blob_map_.find(uuid); 124 BlobMap::iterator found = blob_map_.find(uuid);
126 if (found == blob_map_.end()) 125 if (found == blob_map_.end())
127 return; 126 return;
128 if (found->second.flags & EXCEEDED_MEMORY) 127 if (found->second.flags & EXCEEDED_MEMORY)
129 return; 128 return;
130 BlobData* target_blob_data = found->second.data.get(); 129 BlobData* target_blob_data = found->second.data.get();
131 DCHECK(target_blob_data); 130 DCHECK(target_blob_data);
132 131
133 bool exceeded_memory = false; 132 bool exceeded_memory = false;
(...skipping 27 matching lines...) Expand all
161 case BlobData::Item::TYPE_FILE_FILESYSTEM: 160 case BlobData::Item::TYPE_FILE_FILESYSTEM:
162 AppendFileSystemFileItem(target_blob_data, 161 AppendFileSystemFileItem(target_blob_data,
163 item.filesystem_url(), 162 item.filesystem_url(),
164 item.offset(), 163 item.offset(),
165 item.length(), 164 item.length(),
166 item.expected_modification_time()); 165 item.expected_modification_time());
167 break; 166 break;
168 case BlobData::Item::TYPE_BLOB: { 167 case BlobData::Item::TYPE_BLOB: {
169 scoped_ptr<BlobDataHandle> src = GetBlobDataFromUUID(item.blob_uuid()); 168 scoped_ptr<BlobDataHandle> src = GetBlobDataFromUUID(item.blob_uuid());
170 if (src) 169 if (src)
171 exceeded_memory = !ExpandStorageItems(target_blob_data, 170 exceeded_memory =
172 src->data(), 171 !ExpandStorageItems(
173 item.offset(), 172 target_blob_data, src->data(), item.offset(), item.length());
174 item.length());
175 break; 173 break;
176 } 174 }
177 default: 175 default:
178 NOTREACHED(); 176 NOTREACHED();
179 break; 177 break;
180 } 178 }
181 179
182 // If we're using too much memory, drop this blob's data. 180 // If we're using too much memory, drop this blob's data.
183 // TODO(michaeln): Blob memory storage does not yet spill over to disk, 181 // TODO(michaeln): Blob memory storage does not yet spill over to disk,
184 // as a stop gap, we'll prevent memory usage over a max amount. 182 // as a stop gap, we'll prevent memory usage over a max amount.
185 if (exceeded_memory) { 183 if (exceeded_memory) {
186 memory_usage_ -= target_blob_data->GetMemoryUsage(); 184 memory_usage_ -= target_blob_data->GetMemoryUsage();
187 found->second.flags |= EXCEEDED_MEMORY; 185 found->second.flags |= EXCEEDED_MEMORY;
188 found->second.data = new BlobData(uuid); 186 found->second.data = new BlobData(uuid);
189 return; 187 return;
190 } 188 }
191 } 189 }
192 190
193 void BlobStorageContext::FinishBuildingBlob( 191 void BlobStorageContext::FinishBuildingBlob(const std::string& uuid,
194 const std::string& uuid, const std::string& content_type) { 192 const std::string& content_type) {
195 DCHECK(IsBeingBuilt(uuid)); 193 DCHECK(IsBeingBuilt(uuid));
196 BlobMap::iterator found = blob_map_.find(uuid); 194 BlobMap::iterator found = blob_map_.find(uuid);
197 if (found == blob_map_.end()) 195 if (found == blob_map_.end())
198 return; 196 return;
199 found->second.data->set_content_type(content_type); 197 found->second.data->set_content_type(content_type);
200 found->second.flags &= ~BEING_BUILT; 198 found->second.flags &= ~BEING_BUILT;
201 } 199 }
202 200
203 void BlobStorageContext::CancelBuildingBlob(const std::string& uuid) { 201 void BlobStorageContext::CancelBuildingBlob(const std::string& uuid) {
204 DCHECK(IsBeingBuilt(uuid)); 202 DCHECK(IsBeingBuilt(uuid));
(...skipping 13 matching lines...) Expand all
218 BlobMap::iterator found = blob_map_.find(uuid); 216 BlobMap::iterator found = blob_map_.find(uuid);
219 if (found == blob_map_.end()) 217 if (found == blob_map_.end())
220 return; 218 return;
221 DCHECK_EQ(found->second.data->uuid(), uuid); 219 DCHECK_EQ(found->second.data->uuid(), uuid);
222 if (--(found->second.refcount) == 0) { 220 if (--(found->second.refcount) == 0) {
223 memory_usage_ -= found->second.data->GetMemoryUsage(); 221 memory_usage_ -= found->second.data->GetMemoryUsage();
224 blob_map_.erase(found); 222 blob_map_.erase(found);
225 } 223 }
226 } 224 }
227 225
228 bool BlobStorageContext::ExpandStorageItems( 226 bool BlobStorageContext::ExpandStorageItems(BlobData* target_blob_data,
229 BlobData* target_blob_data, BlobData* src_blob_data, 227 BlobData* src_blob_data,
230 uint64 offset, uint64 length) { 228 uint64 offset,
229 uint64 length) {
231 DCHECK(target_blob_data && src_blob_data && 230 DCHECK(target_blob_data && src_blob_data &&
232 length != static_cast<uint64>(-1)); 231 length != static_cast<uint64>(-1));
233 232
234 std::vector<BlobData::Item>::const_iterator iter = 233 std::vector<BlobData::Item>::const_iterator iter =
235 src_blob_data->items().begin(); 234 src_blob_data->items().begin();
236 if (offset) { 235 if (offset) {
237 for (; iter != src_blob_data->items().end(); ++iter) { 236 for (; iter != src_blob_data->items().end(); ++iter) {
238 if (offset >= iter->length()) 237 if (offset >= iter->length())
239 offset -= iter->length(); 238 offset -= iter->length();
240 else 239 else
(...skipping 24 matching lines...) Expand all
265 iter->offset() + offset, 264 iter->offset() + offset,
266 new_length, 265 new_length,
267 iter->expected_modification_time()); 266 iter->expected_modification_time());
268 } 267 }
269 length -= new_length; 268 length -= new_length;
270 offset = 0; 269 offset = 0;
271 } 270 }
272 return true; 271 return true;
273 } 272 }
274 273
275 bool BlobStorageContext::AppendBytesItem( 274 bool BlobStorageContext::AppendBytesItem(BlobData* target_blob_data,
276 BlobData* target_blob_data, const char* bytes, int64 length) { 275 const char* bytes,
276 int64 length) {
277 if (length < 0) { 277 if (length < 0) {
278 DCHECK(false); 278 DCHECK(false);
279 return false; 279 return false;
280 } 280 }
281 if (memory_usage_ + length > kMaxMemoryUsage) 281 if (memory_usage_ + length > kMaxMemoryUsage)
282 return false; 282 return false;
283 target_blob_data->AppendData(bytes, static_cast<size_t>(length)); 283 target_blob_data->AppendData(bytes, static_cast<size_t>(length));
284 memory_usage_ += length; 284 memory_usage_ += length;
285 return true; 285 return true;
286 } 286 }
287 287
288 void BlobStorageContext::AppendFileItem( 288 void BlobStorageContext::AppendFileItem(
289 BlobData* target_blob_data, 289 BlobData* target_blob_data,
290 const base::FilePath& file_path, uint64 offset, uint64 length, 290 const base::FilePath& file_path,
291 uint64 offset,
292 uint64 length,
291 const base::Time& expected_modification_time) { 293 const base::Time& expected_modification_time) {
292 target_blob_data->AppendFile(file_path, offset, length, 294 target_blob_data->AppendFile(
293 expected_modification_time); 295 file_path, offset, length, expected_modification_time);
294 296
295 // It may be a temporary file that should be deleted when no longer needed. 297 // It may be a temporary file that should be deleted when no longer needed.
296 scoped_refptr<ShareableFileReference> shareable_file = 298 scoped_refptr<ShareableFileReference> shareable_file =
297 ShareableFileReference::Get(file_path); 299 ShareableFileReference::Get(file_path);
298 if (shareable_file.get()) 300 if (shareable_file.get())
299 target_blob_data->AttachShareableFileReference(shareable_file.get()); 301 target_blob_data->AttachShareableFileReference(shareable_file.get());
300 } 302 }
301 303
302 void BlobStorageContext::AppendFileSystemFileItem( 304 void BlobStorageContext::AppendFileSystemFileItem(
303 BlobData* target_blob_data, 305 BlobData* target_blob_data,
304 const GURL& filesystem_url, uint64 offset, uint64 length, 306 const GURL& filesystem_url,
307 uint64 offset,
308 uint64 length,
305 const base::Time& expected_modification_time) { 309 const base::Time& expected_modification_time) {
306 target_blob_data->AppendFileSystemFile(filesystem_url, offset, length, 310 target_blob_data->AppendFileSystemFile(
307 expected_modification_time); 311 filesystem_url, offset, length, expected_modification_time);
308 } 312 }
309 313
310 bool BlobStorageContext::IsInUse(const std::string& uuid) { 314 bool BlobStorageContext::IsInUse(const std::string& uuid) {
311 return blob_map_.find(uuid) != blob_map_.end(); 315 return blob_map_.find(uuid) != blob_map_.end();
312 } 316 }
313 317
314 bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) { 318 bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) {
315 BlobMap::iterator found = blob_map_.find(uuid); 319 BlobMap::iterator found = blob_map_.find(uuid);
316 if (found == blob_map_.end()) 320 if (found == blob_map_.end())
317 return false; 321 return false;
318 return found->second.flags & BEING_BUILT; 322 return found->second.flags & BEING_BUILT;
319 } 323 }
320 324
321 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) { 325 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) {
322 return public_blob_urls_.find(blob_url) != public_blob_urls_.end(); 326 return public_blob_urls_.find(blob_url) != public_blob_urls_.end();
323 } 327 }
324 328
325 } // namespace webkit_blob 329 } // namespace storage
OLDNEW
« no previous file with comments | « storage/browser/blob/blob_storage_context.h ('k') | storage/browser/blob/blob_url_request_job.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698