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

Side by Side Diff: webkit/blob/blob_storage_context.cc

Issue 14139026: New blobstoragecontext for use in the main browser process, not plugged in yet. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 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/blob/blob_storage_context.h ('k') | webkit/blob/blob_storage_context_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) 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/blob/blob_storage_controller.h" 5 #include "webkit/blob/blob_storage_context.h"
6 6
7 #include "base/bind.h"
8 #include "base/location.h"
7 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop_proxy.h"
11 #include "base/sys_info.h"
8 #include "googleurl/src/gurl.h" 12 #include "googleurl/src/gurl.h"
9 #include "webkit/blob/blob_data.h" 13 #include "webkit/blob/blob_data.h"
10 14
11 namespace webkit_blob { 15 namespace webkit_blob {
12 16
13 namespace { 17 namespace {
14 18
15 // We can't use GURL directly for these hash fragment manipulations 19 // We can't use GURL directly for these hash fragment manipulations
16 // 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
17 // 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
18 // fragments. 22 // fragments.
19 23
20 bool BlobUrlHasRef(const GURL& url) { 24 bool BlobUrlHasRef(const GURL& url) {
21 return url.spec().find('#') != std::string::npos; 25 return url.spec().find('#') != std::string::npos;
22 } 26 }
23 27
24 GURL ClearBlobUrlRef(const GURL& url) { 28 GURL ClearBlobUrlRef(const GURL& url) {
25 size_t hash_pos = url.spec().find('#'); 29 size_t hash_pos = url.spec().find('#');
26 if (hash_pos == std::string::npos) 30 if (hash_pos == std::string::npos)
27 return url; 31 return url;
28 return GURL(url.spec().substr(0, hash_pos)); 32 return GURL(url.spec().substr(0, hash_pos));
29 } 33 }
30 34
31 static const int64 kMaxMemoryUsage = 1024 * 1024 * 1024; // 1G 35 // TODO(michaeln): use base::SysInfo::AmountOfPhysicalMemoryMB() in some
36 // way to come up with a better limit.
37 static const int64 kMaxMemoryUsage = 500 * 1024 * 1024; // Half a gig.
32 38
33 } // namespace 39 } // namespace
34 40
35 BlobStorageController::BlobStorageController() 41 //-----------------------------------------------------------------------
42 // BlobDataHandle
43 //-----------------------------------------------------------------------
44
45 BlobDataHandle::BlobDataHandle(BlobData* blob_data, BlobStorageContext* context,
46 base::SequencedTaskRunner* task_runner)
47 : blob_data_(blob_data),
48 context_(context->AsWeakPtr()),
49 io_task_runner_(task_runner) {
50 // Ensures the uuid remains registered and the underlying data is not deleted.
51 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
52 context_->IncrementBlobRefCount(blob_data->uuid());
53 blob_data_->AddRef();
54 }
55
56 BlobDataHandle::~BlobDataHandle() {
57 if (io_task_runner_->RunsTasksOnCurrentThread()) {
58 // Note: Do not test context_ on the wrong thread.
59 if (context_.get())
60 context_->DecrementBlobRefCount(blob_data_->uuid());
61 blob_data_->Release();
62 return;
63 }
64
65 io_task_runner_->PostTask(
66 FROM_HERE,
67 base::Bind(&DeleteHelper, context_, base::Unretained(blob_data_)));
68 }
69
70 BlobData* BlobDataHandle::data() const {
71 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
72 return blob_data_;
73 }
74
75 // static
76 void BlobDataHandle::DeleteHelper(
77 base::WeakPtr<BlobStorageContext> context,
78 BlobData* blob_data) {
79 if (context.get())
80 context->DecrementBlobRefCount(blob_data->uuid());
81 blob_data->Release();
82 }
83
84 //-----------------------------------------------------------------------
85 // BlobStorageHost
86 //-----------------------------------------------------------------------
87
88 BlobStorageHost::BlobStorageHost(BlobStorageContext* context)
89 : context_(context->AsWeakPtr()) {
90 }
91
92 BlobStorageHost::~BlobStorageHost() {
93 if (!context_)
94 return;
95 for (std::set<GURL>::iterator iter = public_blob_urls_.begin();
96 iter != public_blob_urls_.end(); ++iter) {
97 context_->RevokePublicBlobURL(*iter);
98 }
99 for (BlobReferenceMap::iterator iter = blobs_inuse_map_.begin();
100 iter != blobs_inuse_map_.end(); ++iter) {
101 for (int i = 0; i < iter->second; ++i)
102 context_->DecrementBlobRefCount(iter->first);
103 }
104 }
105
106 bool BlobStorageHost::StartBuildingBlob(const std::string& uuid) {
107 if (!context_ || uuid.empty() || context_->IsInUse(uuid))
108 return false;
109 context_->StartBuildingBlob(uuid);
110 blobs_inuse_map_[uuid] = 1;
111 return true;
112 }
113
114 bool BlobStorageHost::AppendBlobDataItem(
115 const std::string& uuid, const BlobData::Item& data_item) {
116 if (!context_ || !IsBeingBuiltInHost(uuid))
117 return false;
118 context_->AppendBlobDataItem(uuid, data_item);
119 return true;
120 }
121
122 bool BlobStorageHost::CancelBuildingBlob(const std::string& uuid) {
123 if (!context_ || !IsBeingBuiltInHost(uuid))
124 return false;
125 blobs_inuse_map_.erase(uuid);
126 context_->CancelBuildingBlob(uuid);
127 return true;
128 }
129
130 bool BlobStorageHost::FinishBuildingBlob(
131 const std::string& uuid, const std::string& content_type) {
132 if (!context_ || !IsBeingBuiltInHost(uuid))
133 return false;
134 context_->FinishBuildingBlob(uuid, content_type);
135 return true;
136 }
137
138 bool BlobStorageHost::IncrementBlobRefCount(const std::string& uuid) {
139 if (!context_ || !IsInUseInHost(uuid))
140 return false;
141 context_->IncrementBlobRefCount(uuid);
142 blobs_inuse_map_[uuid] += 1;
143 return true;
144 }
145
146 bool BlobStorageHost::DecrementBlobRefCount(const std::string& uuid) {
147 if (!context_ || !IsInUseInHost(uuid))
148 return false;
149 context_->DecrementBlobRefCount(uuid);
150 blobs_inuse_map_[uuid] -= 1;
151 if (blobs_inuse_map_[uuid] == 0)
152 blobs_inuse_map_.erase(uuid);
153 return true;
154 }
155
156 bool BlobStorageHost::RegisterPublicBlobURL(
157 const GURL& blob_url, const std::string& uuid) {
158 if (!context_ || !IsInUseInHost(uuid) || context_->IsUrlRegistered(blob_url))
159 return false;
160 context_->RegisterPublicBlobURL(blob_url, uuid);
161 public_blob_urls_.insert(blob_url);
162 return true;
163 }
164
165 bool BlobStorageHost::RevokePublicBlobURL(const GURL& blob_url) {
166 if (!context_ || !IsUrlRegisteredInHost(blob_url))
167 return false;
168 context_->RevokePublicBlobURL(blob_url);
169 public_blob_urls_.erase(blob_url);
170 return true;
171 }
172
173 bool BlobStorageHost::IsInUseInHost(const std::string& uuid) {
174 return blobs_inuse_map_.find(uuid) != blobs_inuse_map_.end();
175 }
176
177 bool BlobStorageHost::IsBeingBuiltInHost(const std::string& uuid) {
178 return IsInUseInHost(uuid) && context_->IsBeingBuilt(uuid);
179 }
180
181 bool BlobStorageHost::IsUrlRegisteredInHost(const GURL& blob_url) {
182 return public_blob_urls_.find(blob_url) != public_blob_urls_.end();
183 }
184
185 //-----------------------------------------------------------------------
186 // BlobStorageContext
187 //-----------------------------------------------------------------------
188
189 BlobStorageContext::BlobMapEntry::BlobMapEntry()
190 : refcount(0), flags(0) {
191 }
192
193 BlobStorageContext::BlobMapEntry::BlobMapEntry(
194 int refcount, int flags, BlobData* data)
195 : refcount(refcount), flags(flags), data(data) {
196 }
197
198 BlobStorageContext::BlobMapEntry::~BlobMapEntry() {
199 }
200
201 BlobStorageContext::BlobStorageContext()
36 : memory_usage_(0) { 202 : memory_usage_(0) {
37 } 203 }
38 204
39 BlobStorageController::~BlobStorageController() { 205 BlobStorageContext::~BlobStorageContext() {
40 } 206 }
41 207
42 void BlobStorageController::StartBuildingBlob(const GURL& url) { 208 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID(
43 DCHECK(url.SchemeIs("blob")); 209 const std::string& uuid) {
44 DCHECK(!BlobUrlHasRef(url)); 210 scoped_ptr<BlobDataHandle> result;
45 BlobData* blob_data = new BlobData; 211 BlobMap::iterator found = blob_map_.find(uuid);
46 unfinalized_blob_map_[url.spec()] = blob_data; 212 if (found == blob_map_.end())
47 IncrementBlobDataUsage(blob_data); 213 return result.Pass();
48 } 214 if (found->second.flags & EXCEEDED_MEMORY)
49 215 return result.Pass();
50 void BlobStorageController::AppendBlobDataItem( 216 DCHECK(!(found->second.flags & BEING_BUILT));
51 const GURL& url, const BlobData::Item& item) { 217 result.reset(new BlobDataHandle(found->second.data, this,
52 DCHECK(url.SchemeIs("blob")); 218 base::MessageLoopProxy::current()));
53 DCHECK(!BlobUrlHasRef(url)); 219 return result.Pass();
54 BlobMap::iterator found = unfinalized_blob_map_.find(url.spec()); 220 }
55 if (found == unfinalized_blob_map_.end()) 221
56 return; 222 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL(
57 BlobData* target_blob_data = found->second; 223 const GURL& url) {
224 BlobURLMap::iterator found = public_blob_urls_.find(
225 BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url);
226 if (found == public_blob_urls_.end())
227 return scoped_ptr<BlobDataHandle>();
228 return GetBlobDataFromUUID(found->second);
229 }
230
231 scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob(
232 const BlobData* data) {
233 StartBuildingBlob(data->uuid());
234 for (std::vector<BlobData::Item>::const_iterator iter =
235 data->items().begin();
236 iter != data->items().end(); ++iter) {
237 AppendBlobDataItem(data->uuid(), *iter);
238 }
239 FinishBuildingBlob(data->uuid(), data->content_type());
240 scoped_ptr<BlobDataHandle> handle = GetBlobDataFromUUID(data->uuid());
241 DecrementBlobRefCount(data->uuid());
242 return handle.Pass();
243 }
244
245 void BlobStorageContext::StartBuildingBlob(const std::string& uuid) {
246 DCHECK(!IsInUse(uuid) && !uuid.empty());
247 blob_map_[uuid] = BlobMapEntry(1, BEING_BUILT, new BlobData(uuid));
248 }
249
250 void BlobStorageContext::AppendBlobDataItem(
251 const std::string& uuid, const BlobData::Item& item) {
252 DCHECK(IsBeingBuilt(uuid));
253 BlobMap::iterator found = blob_map_.find(uuid);
254 if (found == blob_map_.end())
255 return;
256 if (found->second.flags & EXCEEDED_MEMORY)
257 return;
258 BlobData* target_blob_data = found->second.data;
58 DCHECK(target_blob_data); 259 DCHECK(target_blob_data);
59 260
60 memory_usage_ -= target_blob_data->GetMemoryUsage(); 261 memory_usage_ -= target_blob_data->GetMemoryUsage();
61 262 bool exceeded_memory = false;
62 // The blob data is stored in the "canonical" way. That is, it only contains a 263
63 // list of Data and File items. 264 // The blob data is stored in the canonical way which only contains a
64 // 1) The Data item is denoted by the raw data and the range. 265 // list of Data, File, and FileSystem items. Aggregated TYPE_BLOB items
266 // are expanded into the primitive constituent types.
267 // 1) The Data item is denoted by the raw data and length.
65 // 2) The File item is denoted by the file path, the range and the expected 268 // 2) The File item is denoted by the file path, the range and the expected
66 // modification time. 269 // modification time.
67 // 3) The FileSystem File item is denoted by the FileSystem URL, the range 270 // 3) The FileSystem File item is denoted by the FileSystem URL, the range
68 // and the expected modification time. 271 // and the expected modification time.
69 // All the Blob items in the passing blob data are resolved and expanded into 272 // 4) The Blob items are expanded.
70 // a set of Data and File items. 273 // TODO(michaeln): Would be nice to avoid copying Data items when expanding.
71 274
72 DCHECK(item.length() > 0); 275 DCHECK(item.length() > 0);
73 switch (item.type()) { 276 switch (item.type()) {
74 case BlobData::Item::TYPE_BYTES: 277 case BlobData::Item::TYPE_BYTES:
75 DCHECK(!item.offset()); 278 DCHECK(!item.offset());
76 target_blob_data->AppendData(item.bytes(), item.length()); 279 exceeded_memory = !AppendBytesItem(target_blob_data,
280 item.bytes(),
281 item.length());
77 break; 282 break;
78 case BlobData::Item::TYPE_FILE: 283 case BlobData::Item::TYPE_FILE:
79 AppendFileItem(target_blob_data, 284 AppendFileItem(target_blob_data,
80 item.path(), 285 item.path(),
81 item.offset(), 286 item.offset(),
82 item.length(), 287 item.length(),
83 item.expected_modification_time()); 288 item.expected_modification_time());
84 break; 289 break;
85 case BlobData::Item::TYPE_FILE_FILESYSTEM: 290 case BlobData::Item::TYPE_FILE_FILESYSTEM:
86 AppendFileSystemFileItem(target_blob_data, 291 AppendFileSystemFileItem(target_blob_data,
87 item.url(), 292 item.filesystem_url(),
88 item.offset(), 293 item.offset(),
89 item.length(), 294 item.length(),
90 item.expected_modification_time()); 295 item.expected_modification_time());
91 break; 296 break;
92 case BlobData::Item::TYPE_BLOB: { 297 case BlobData::Item::TYPE_BLOB: {
93 BlobData* src_blob_data = GetBlobDataFromUrl(item.url()); 298 scoped_ptr<BlobDataHandle> src = GetBlobDataFromUUID(item.blob_uuid());
94 DCHECK(src_blob_data); 299 DCHECK(src.get());
95 if (src_blob_data) 300 if (src.get())
96 AppendStorageItems(target_blob_data, 301 exceeded_memory = !ExpandStorageItems(target_blob_data,
97 src_blob_data, 302 src->data(),
98 item.offset(), 303 item.offset(),
99 item.length()); 304 item.length());
100 break; 305 break;
101 } 306 }
102 default: 307 default:
103 NOTREACHED(); 308 NOTREACHED();
104 break; 309 break;
105 } 310 }
106 311
312 // If we're using too much memory, drop this blob's data.
313 // TODO(michaeln): Blob memory storage does not yet spill over to disk,
314 // as a stop gap, we'll prevent memory usage over a max amount.
315 if (exceeded_memory) {
316 found->second.flags |= EXCEEDED_MEMORY;
317 found->second.data = new BlobData(uuid);
318 return;
319 }
320
107 memory_usage_ += target_blob_data->GetMemoryUsage(); 321 memory_usage_ += target_blob_data->GetMemoryUsage();
108
109 // If we're using too much memory, drop this blob.
110 // TODO(michaeln): Blob memory storage does not yet spill over to disk,
111 // until it does, we'll prevent memory usage over a max amount.
112 if (memory_usage_ > kMaxMemoryUsage)
113 RemoveBlob(url);
114 } 322 }
115 323
116 void BlobStorageController::FinishBuildingBlob( 324 void BlobStorageContext::FinishBuildingBlob(
117 const GURL& url, const std::string& content_type) { 325 const std::string& uuid, const std::string& content_type) {
118 DCHECK(url.SchemeIs("blob")); 326 DCHECK(IsBeingBuilt(uuid));
119 DCHECK(!BlobUrlHasRef(url)); 327 BlobMap::iterator found = blob_map_.find(uuid);
120 BlobMap::iterator found = unfinalized_blob_map_.find(url.spec()); 328 if (found == blob_map_.end())
121 if (found == unfinalized_blob_map_.end())
122 return; 329 return;
123 found->second->set_content_type(content_type); 330 found->second.data->set_content_type(content_type);
124 blob_map_[url.spec()] = found->second; 331 found->second.flags &= ~BEING_BUILT;
125 unfinalized_blob_map_.erase(found);
126 } 332 }
127 333
128 void BlobStorageController::AddFinishedBlob(const GURL& url, 334 void BlobStorageContext::CancelBuildingBlob(const std::string& uuid) {
129 const BlobData* data) { 335 DCHECK(IsBeingBuilt(uuid));
130 StartBuildingBlob(url); 336 DecrementBlobRefCount(uuid);
131 for (std::vector<BlobData::Item>::const_iterator iter =
132 data->items().begin();
133 iter != data->items().end(); ++iter) {
134 AppendBlobDataItem(url, *iter);
135 }
136 FinishBuildingBlob(url, data->content_type());
137 } 337 }
138 338
139 void BlobStorageController::CloneBlob( 339 void BlobStorageContext::IncrementBlobRefCount(const std::string& uuid) {
140 const GURL& url, const GURL& src_url) { 340 BlobMap::iterator found = blob_map_.find(uuid);
141 DCHECK(url.SchemeIs("blob")); 341 if (found == blob_map_.end()) {
142 DCHECK(!BlobUrlHasRef(url)); 342 DCHECK(false);
143
144 BlobData* blob_data = GetBlobDataFromUrl(src_url);
145 DCHECK(blob_data);
146 if (!blob_data)
147 return; 343 return;
148 344 }
149 blob_map_[url.spec()] = blob_data; 345 ++(found->second.refcount);
150 IncrementBlobDataUsage(blob_data);
151 } 346 }
152 347
153 void BlobStorageController::RemoveBlob(const GURL& url) { 348 void BlobStorageContext::DecrementBlobRefCount(const std::string& uuid) {
154 DCHECK(url.SchemeIs("blob")); 349 BlobMap::iterator found = blob_map_.find(uuid);
155 DCHECK(!BlobUrlHasRef(url)); 350 if (found == blob_map_.end())
156 351 return;
157 if (!RemoveFromMapHelper(&unfinalized_blob_map_, url)) 352 DCHECK_EQ(found->second.data->uuid(), uuid);
158 RemoveFromMapHelper(&blob_map_, url); 353 if (--(found->second.refcount) == 0) {
354 memory_usage_ -= found->second.data->GetMemoryUsage();
355 blob_map_.erase(found);
356 }
159 } 357 }
160 358
161 bool BlobStorageController::RemoveFromMapHelper( 359 void BlobStorageContext::RegisterPublicBlobURL(
162 BlobMap* map, const GURL& url) { 360 const GURL& blob_url, const std::string& uuid) {
163 BlobMap::iterator found = map->find(url.spec()); 361 DCHECK(!BlobUrlHasRef(blob_url));
164 if (found == map->end()) 362 DCHECK(IsInUse(uuid));
165 return false; 363 DCHECK(!IsUrlRegistered(blob_url));
166 if (DecrementBlobDataUsage(found->second)) 364 IncrementBlobRefCount(uuid);
167 memory_usage_ -= found->second->GetMemoryUsage(); 365 public_blob_urls_[blob_url] = uuid;
168 map->erase(found);
169 return true;
170 } 366 }
171 367
172 368 void BlobStorageContext::RevokePublicBlobURL(const GURL& blob_url) {
173 BlobData* BlobStorageController::GetBlobDataFromUrl(const GURL& url) { 369 DCHECK(!BlobUrlHasRef(blob_url));
174 BlobMap::iterator found = blob_map_.find( 370 if (!IsUrlRegistered(blob_url))
175 BlobUrlHasRef(url) ? ClearBlobUrlRef(url).spec() : url.spec()); 371 return;
176 return (found != blob_map_.end()) ? found->second : NULL; 372 DecrementBlobRefCount(public_blob_urls_[blob_url]);
373 public_blob_urls_.erase(blob_url);
177 } 374 }
178 375
179 void BlobStorageController::AppendStorageItems( 376 bool BlobStorageContext::ExpandStorageItems(
180 BlobData* target_blob_data, BlobData* src_blob_data, 377 BlobData* target_blob_data, BlobData* src_blob_data,
181 uint64 offset, uint64 length) { 378 uint64 offset, uint64 length) {
182 DCHECK(target_blob_data && src_blob_data && 379 DCHECK(target_blob_data && src_blob_data &&
183 length != static_cast<uint64>(-1)); 380 length != static_cast<uint64>(-1));
184 381
185 std::vector<BlobData::Item>::const_iterator iter = 382 std::vector<BlobData::Item>::const_iterator iter =
186 src_blob_data->items().begin(); 383 src_blob_data->items().begin();
187 if (offset) { 384 if (offset) {
188 for (; iter != src_blob_data->items().end(); ++iter) { 385 for (; iter != src_blob_data->items().end(); ++iter) {
189 if (offset >= iter->length()) 386 if (offset >= iter->length())
190 offset -= iter->length(); 387 offset -= iter->length();
191 else 388 else
192 break; 389 break;
193 } 390 }
194 } 391 }
195 392
196 for (; iter != src_blob_data->items().end() && length > 0; ++iter) { 393 for (; iter != src_blob_data->items().end() && length > 0; ++iter) {
197 uint64 current_length = iter->length() - offset; 394 uint64 current_length = iter->length() - offset;
198 uint64 new_length = current_length > length ? length : current_length; 395 uint64 new_length = current_length > length ? length : current_length;
199 if (iter->type() == BlobData::Item::TYPE_BYTES) { 396 if (iter->type() == BlobData::Item::TYPE_BYTES) {
200 target_blob_data->AppendData( 397 if (!AppendBytesItem(
201 iter->bytes() + static_cast<size_t>(iter->offset() + offset), 398 target_blob_data,
202 static_cast<uint32>(new_length)); 399 iter->bytes() + static_cast<size_t>(iter->offset() + offset),
400 static_cast<uint32>(new_length))) {
401 return false; // exceeded memory
402 }
203 } else if (iter->type() == BlobData::Item::TYPE_FILE) { 403 } else if (iter->type() == BlobData::Item::TYPE_FILE) {
204 AppendFileItem(target_blob_data, 404 AppendFileItem(target_blob_data,
205 iter->path(), 405 iter->path(),
206 iter->offset() + offset, 406 iter->offset() + offset,
207 new_length, 407 new_length,
208 iter->expected_modification_time()); 408 iter->expected_modification_time());
209 } else { 409 } else {
210 DCHECK(iter->type() == BlobData::Item::TYPE_FILE_FILESYSTEM); 410 DCHECK(iter->type() == BlobData::Item::TYPE_FILE_FILESYSTEM);
211 AppendFileSystemFileItem(target_blob_data, 411 AppendFileSystemFileItem(target_blob_data,
212 iter->url(), 412 iter->filesystem_url(),
213 iter->offset() + offset, 413 iter->offset() + offset,
214 new_length, 414 new_length,
215 iter->expected_modification_time()); 415 iter->expected_modification_time());
216 } 416 }
217 length -= new_length; 417 length -= new_length;
218 offset = 0; 418 offset = 0;
219 } 419 }
420 return true;
220 } 421 }
221 422
222 void BlobStorageController::AppendFileItem( 423 bool BlobStorageContext::AppendBytesItem(
424 BlobData* target_blob_data, const char* bytes, size_t length) {
425 if (memory_usage_ + target_blob_data->GetMemoryUsage() + length >
426 kMaxMemoryUsage) {
427 return false;
428 }
429 target_blob_data->AppendData(bytes, length);
430 return true;
431 }
432
433 void BlobStorageContext::AppendFileItem(
223 BlobData* target_blob_data, 434 BlobData* target_blob_data,
224 const base::FilePath& file_path, uint64 offset, uint64 length, 435 const base::FilePath& file_path, uint64 offset, uint64 length,
225 const base::Time& expected_modification_time) { 436 const base::Time& expected_modification_time) {
226 target_blob_data->AppendFile(file_path, offset, length, 437 target_blob_data->AppendFile(file_path, offset, length,
227 expected_modification_time); 438 expected_modification_time);
228 439
229 // It may be a temporary file that should be deleted when no longer needed. 440 // It may be a temporary file that should be deleted when no longer needed.
230 scoped_refptr<ShareableFileReference> shareable_file = 441 scoped_refptr<ShareableFileReference> shareable_file =
231 ShareableFileReference::Get(file_path); 442 ShareableFileReference::Get(file_path);
232 if (shareable_file) 443 if (shareable_file)
233 target_blob_data->AttachShareableFileReference(shareable_file); 444 target_blob_data->AttachShareableFileReference(shareable_file);
234 } 445 }
235 446
236 void BlobStorageController::AppendFileSystemFileItem( 447 void BlobStorageContext::AppendFileSystemFileItem(
237 BlobData* target_blob_data, 448 BlobData* target_blob_data,
238 const GURL& url, uint64 offset, uint64 length, 449 const GURL& filesystem_url, uint64 offset, uint64 length,
239 const base::Time& expected_modification_time) { 450 const base::Time& expected_modification_time) {
240 target_blob_data->AppendFileSystemFile(url, offset, length, 451 target_blob_data->AppendFileSystemFile(filesystem_url, offset, length,
241 expected_modification_time); 452 expected_modification_time);
242 } 453 }
243 454
244 void BlobStorageController::IncrementBlobDataUsage(BlobData* blob_data) { 455 bool BlobStorageContext::IsInUse(const std::string& uuid) {
245 blob_data_usage_count_[blob_data] += 1; 456 return blob_map_.find(uuid) != blob_map_.end();
246 } 457 }
247 458
248 bool BlobStorageController::DecrementBlobDataUsage(BlobData* blob_data) { 459 bool BlobStorageContext::IsBeingBuilt(const std::string& uuid) {
249 BlobDataUsageMap::iterator found = blob_data_usage_count_.find(blob_data); 460 BlobMap::iterator found = blob_map_.find(uuid);
michaeln 2013/04/29 18:32:48 Here's the HasUseCountOfOne replacement which is s
250 DCHECK(found != blob_data_usage_count_.end()); 461 if (found == blob_map_.end())
251 if (--(found->second)) 462 return false;
252 return false; // Still in use 463 return found->second.flags & BEING_BUILT;
253 blob_data_usage_count_.erase(found); 464 }
254 return true; 465
466 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) {
467 return public_blob_urls_.find(blob_url) != public_blob_urls_.end();
255 } 468 }
256 469
257 } // namespace webkit_blob 470 } // namespace webkit_blob
OLDNEW
« no previous file with comments | « webkit/blob/blob_storage_context.h ('k') | webkit/blob/blob_storage_context_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698