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

Side by Side Diff: webkit/quota/quota_database.cc

Issue 9249025: Database usage adjustment for .../webkit (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge to head Created 8 years, 10 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/database/quota_table.cc ('k') | no next file » | 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/quota/quota_database.h" 5 #include "webkit/quota/quota_database.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 21 matching lines...) Expand all
32 32
33 class HistogramUniquifier { 33 class HistogramUniquifier {
34 public: 34 public:
35 static const char* name() { return "Sqlite.Quota.Error"; } 35 static const char* name() { return "Sqlite.Quota.Error"; }
36 }; 36 };
37 37
38 sql::ErrorDelegate* GetErrorHandlerForQuotaDb() { 38 sql::ErrorDelegate* GetErrorHandlerForQuotaDb() {
39 return new sql::DiagnosticErrorDelegate<HistogramUniquifier>(); 39 return new sql::DiagnosticErrorDelegate<HistogramUniquifier>();
40 } 40 }
41 41
42 bool PrepareCachedStatement(
43 sql::Connection* db, const sql::StatementID& id,
44 const char* sql, sql::Statement* statement) {
45 DCHECK(db && sql && statement);
46 statement->Assign(db->GetCachedStatement(id, sql));
47 if (!statement->is_valid()) {
48 NOTREACHED() << db->GetErrorMessage();
49 return false;
50 }
51 return true;
52 }
53
54 bool VerifyValidQuotaConfig(const char* key) { 42 bool VerifyValidQuotaConfig(const char* key) {
55 return (key != NULL && 43 return (key != NULL &&
56 (!strcmp(key, QuotaDatabase::kDesiredAvailableSpaceKey) || 44 (!strcmp(key, QuotaDatabase::kDesiredAvailableSpaceKey) ||
57 !strcmp(key, QuotaDatabase::kTemporaryQuotaOverrideKey))); 45 !strcmp(key, QuotaDatabase::kTemporaryQuotaOverrideKey)));
58 } 46 }
59 47
60 const int kCommitIntervalMs = 30000; 48 const int kCommitIntervalMs = 30000;
61 49
62 } // anonymous namespace 50 } // anonymous namespace
63 51
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 const std::string& host, StorageType type, int64* quota) { 152 const std::string& host, StorageType type, int64* quota) {
165 DCHECK(quota); 153 DCHECK(quota);
166 if (!LazyOpen(false)) 154 if (!LazyOpen(false))
167 return false; 155 return false;
168 156
169 const char* kSql = 157 const char* kSql =
170 "SELECT quota" 158 "SELECT quota"
171 " FROM HostQuotaTable" 159 " FROM HostQuotaTable"
172 " WHERE host = ? AND type = ?"; 160 " WHERE host = ? AND type = ?";
173 161
174 sql::Statement statement; 162 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
175 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
176 return false;
177
178 statement.BindString(0, host); 163 statement.BindString(0, host);
179 statement.BindInt(1, static_cast<int>(type)); 164 statement.BindInt(1, static_cast<int>(type));
180 if (!statement.Step() || !statement.Succeeded()) 165
166 if (!statement.Step())
181 return false; 167 return false;
182 168
183 *quota = statement.ColumnInt64(0); 169 *quota = statement.ColumnInt64(0);
184 return true; 170 return true;
185 } 171 }
186 172
187 bool QuotaDatabase::SetHostQuota( 173 bool QuotaDatabase::SetHostQuota(
188 const std::string& host, StorageType type, int64 quota) { 174 const std::string& host, StorageType type, int64 quota) {
189 DCHECK_GE(quota, 0); 175 DCHECK_GE(quota, 0);
190 if (!LazyOpen(true)) 176 if (!LazyOpen(true))
191 return false; 177 return false;
192 178
193 sql::Statement statement;
194 const char* kSql = 179 const char* kSql =
195 "INSERT OR REPLACE INTO HostQuotaTable" 180 "INSERT OR REPLACE INTO HostQuotaTable"
196 " (quota, host, type)" 181 " (quota, host, type)"
197 " VALUES (?, ?, ?)"; 182 " VALUES (?, ?, ?)";
198 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 183 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
199 return false;
200
201 statement.BindInt64(0, quota); 184 statement.BindInt64(0, quota);
202 statement.BindString(1, host); 185 statement.BindString(1, host);
203 statement.BindInt(2, static_cast<int>(type)); 186 statement.BindInt(2, static_cast<int>(type));
187
204 if (!statement.Run()) 188 if (!statement.Run())
205 return false; 189 return false;
206 190
207 ScheduleCommit(); 191 ScheduleCommit();
208 return true; 192 return true;
209 } 193 }
210 194
211 bool QuotaDatabase::SetOriginLastAccessTime( 195 bool QuotaDatabase::SetOriginLastAccessTime(
212 const GURL& origin, StorageType type, base::Time last_access_time) { 196 const GURL& origin, StorageType type, base::Time last_access_time) {
213 if (!LazyOpen(true)) 197 if (!LazyOpen(true))
214 return false; 198 return false;
215 199
216 sql::Statement statement; 200 sql::Statement statement;
217 201
218 int used_count = 1; 202 int used_count = 1;
219 if (FindOriginUsedCount(origin, type, &used_count)) { 203 if (FindOriginUsedCount(origin, type, &used_count)) {
220 ++used_count; 204 ++used_count;
221 const char* kSql = 205 const char* kSql =
222 "UPDATE OriginInfoTable" 206 "UPDATE OriginInfoTable"
223 " SET used_count = ?, last_access_time = ?" 207 " SET used_count = ?, last_access_time = ?"
224 " WHERE origin = ? AND type = ?"; 208 " WHERE origin = ? AND type = ?";
225 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 209 statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
226 return false;
227 } else { 210 } else {
228 const char* kSql = 211 const char* kSql =
229 "INSERT INTO OriginInfoTable" 212 "INSERT INTO OriginInfoTable"
230 " (used_count, last_access_time, origin, type)" 213 " (used_count, last_access_time, origin, type)"
231 " VALUES (?, ?, ?, ?)"; 214 " VALUES (?, ?, ?, ?)";
232 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 215 statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
233 return false;
234 } 216 }
235
236 statement.BindInt(0, used_count); 217 statement.BindInt(0, used_count);
237 statement.BindInt64(1, last_access_time.ToInternalValue()); 218 statement.BindInt64(1, last_access_time.ToInternalValue());
238 statement.BindString(2, origin.spec()); 219 statement.BindString(2, origin.spec());
239 statement.BindInt(3, static_cast<int>(type)); 220 statement.BindInt(3, static_cast<int>(type));
221
240 if (!statement.Run()) 222 if (!statement.Run())
241 return false; 223 return false;
242 224
243 ScheduleCommit(); 225 ScheduleCommit();
244 return true; 226 return true;
245 } 227 }
246 228
247 bool QuotaDatabase::SetOriginLastModifiedTime( 229 bool QuotaDatabase::SetOriginLastModifiedTime(
248 const GURL& origin, StorageType type, base::Time last_modified_time) { 230 const GURL& origin, StorageType type, base::Time last_modified_time) {
249 if (!LazyOpen(true)) 231 if (!LazyOpen(true))
250 return false; 232 return false;
251 233
252 sql::Statement statement; 234 sql::Statement statement;
253 235
254 int dummy; 236 int dummy;
255 if (FindOriginUsedCount(origin, type, &dummy)) { 237 if (FindOriginUsedCount(origin, type, &dummy)) {
256 const char* kSql = 238 const char* kSql =
257 "UPDATE OriginInfoTable" 239 "UPDATE OriginInfoTable"
258 " SET last_modified_time = ?" 240 " SET last_modified_time = ?"
259 " WHERE origin = ? AND type = ?"; 241 " WHERE origin = ? AND type = ?";
260 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 242 statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
261 return false;
262 } else { 243 } else {
263 const char* kSql = 244 const char* kSql =
264 "INSERT INTO OriginInfoTable" 245 "INSERT INTO OriginInfoTable"
265 " (last_modified_time, origin, type) VALUES (?, ?, ?)"; 246 " (last_modified_time, origin, type) VALUES (?, ?, ?)";
266 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement)) 247 statement.Assign(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
267 return false;
268 } 248 }
269
270 statement.BindInt64(0, last_modified_time.ToInternalValue()); 249 statement.BindInt64(0, last_modified_time.ToInternalValue());
271 statement.BindString(1, origin.spec()); 250 statement.BindString(1, origin.spec());
272 statement.BindInt(2, static_cast<int>(type)); 251 statement.BindInt(2, static_cast<int>(type));
252
273 if (!statement.Run()) 253 if (!statement.Run())
274 return false; 254 return false;
275 255
276 ScheduleCommit(); 256 ScheduleCommit();
277 return true; 257 return true;
278 } 258 }
279 259
280 bool QuotaDatabase::RegisterInitialOriginInfo( 260 bool QuotaDatabase::RegisterInitialOriginInfo(
281 const std::set<GURL>& origins, StorageType type) { 261 const std::set<GURL>& origins, StorageType type) {
282 if (!LazyOpen(true)) 262 if (!LazyOpen(true))
283 return false; 263 return false;
284 264
285 typedef std::set<GURL>::const_iterator itr_type; 265 typedef std::set<GURL>::const_iterator itr_type;
286 for (itr_type itr = origins.begin(), end = origins.end(); 266 for (itr_type itr = origins.begin(), end = origins.end();
287 itr != end; ++itr) { 267 itr != end; ++itr) {
288 const char* kSql = 268 const char* kSql =
289 "INSERT OR IGNORE INTO OriginInfoTable" 269 "INSERT OR IGNORE INTO OriginInfoTable"
290 " (origin, type) VALUES (?, ?)"; 270 " (origin, type) VALUES (?, ?)";
291 sql::Statement statement; 271 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
292 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
293 return false;
294
295 statement.BindString(0, itr->spec()); 272 statement.BindString(0, itr->spec());
296 statement.BindInt(1, static_cast<int>(type)); 273 statement.BindInt(1, static_cast<int>(type));
274
297 if (!statement.Run()) 275 if (!statement.Run())
298 return false; 276 return false;
299 } 277 }
300 278
301 ScheduleCommit(); 279 ScheduleCommit();
302 return true; 280 return true;
303 } 281 }
304 282
305 bool QuotaDatabase::DeleteHostQuota( 283 bool QuotaDatabase::DeleteHostQuota(
306 const std::string& host, StorageType type) { 284 const std::string& host, StorageType type) {
307 if (!LazyOpen(false)) 285 if (!LazyOpen(false))
308 return false; 286 return false;
309 287
310 const char* kSql = 288 const char* kSql =
311 "DELETE FROM HostQuotaTable" 289 "DELETE FROM HostQuotaTable"
312 " WHERE host = ? AND type = ?"; 290 " WHERE host = ? AND type = ?";
313 291
314 sql::Statement statement; 292 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
315 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
316 return false;
317
318 statement.BindString(0, host); 293 statement.BindString(0, host);
319 statement.BindInt(1, static_cast<int>(type)); 294 statement.BindInt(1, static_cast<int>(type));
295
320 if (!statement.Run()) 296 if (!statement.Run())
321 return false; 297 return false;
322 298
323 ScheduleCommit(); 299 ScheduleCommit();
324 return true; 300 return true;
325 } 301 }
326 302
327 bool QuotaDatabase::DeleteOriginInfo( 303 bool QuotaDatabase::DeleteOriginInfo(
328 const GURL& origin, StorageType type) { 304 const GURL& origin, StorageType type) {
329 if (!LazyOpen(false)) 305 if (!LazyOpen(false))
330 return false; 306 return false;
331 307
332 const char* kSql = 308 const char* kSql =
333 "DELETE FROM OriginInfoTable" 309 "DELETE FROM OriginInfoTable"
334 " WHERE origin = ? AND type = ?"; 310 " WHERE origin = ? AND type = ?";
335 311
336 sql::Statement statement; 312 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
337 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
338 return false;
339
340 statement.BindString(0, origin.spec()); 313 statement.BindString(0, origin.spec());
341 statement.BindInt(1, static_cast<int>(type)); 314 statement.BindInt(1, static_cast<int>(type));
315
342 if (!statement.Run()) 316 if (!statement.Run())
343 return false; 317 return false;
344 318
345 ScheduleCommit(); 319 ScheduleCommit();
346 return true; 320 return true;
347 } 321 }
348 322
349 bool QuotaDatabase::GetQuotaConfigValue(const char* key, int64* value) { 323 bool QuotaDatabase::GetQuotaConfigValue(const char* key, int64* value) {
350 if (!LazyOpen(false)) 324 if (!LazyOpen(false))
351 return false; 325 return false;
(...skipping 14 matching lines...) Expand all
366 SpecialStoragePolicy* special_storage_policy, 340 SpecialStoragePolicy* special_storage_policy,
367 GURL* origin) { 341 GURL* origin) {
368 DCHECK(origin); 342 DCHECK(origin);
369 if (!LazyOpen(false)) 343 if (!LazyOpen(false))
370 return false; 344 return false;
371 345
372 const char* kSql = "SELECT origin FROM OriginInfoTable" 346 const char* kSql = "SELECT origin FROM OriginInfoTable"
373 " WHERE type = ?" 347 " WHERE type = ?"
374 " ORDER BY last_access_time ASC"; 348 " ORDER BY last_access_time ASC";
375 349
376 sql::Statement statement; 350 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
377 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
378 return false;
379 statement.BindInt(0, static_cast<int>(type)); 351 statement.BindInt(0, static_cast<int>(type));
380 352
381 while (statement.Step()) { 353 while (statement.Step()) {
382 GURL url(statement.ColumnString(0)); 354 GURL url(statement.ColumnString(0));
383 if (exceptions.find(url) != exceptions.end()) 355 if (exceptions.find(url) != exceptions.end())
384 continue; 356 continue;
385 if (special_storage_policy && 357 if (special_storage_policy &&
386 special_storage_policy->IsStorageUnlimited(url)) 358 special_storage_policy->IsStorageUnlimited(url))
387 continue; 359 continue;
388 *origin = url; 360 *origin = url;
389 return true; 361 return true;
390 } 362 }
391 363
392 *origin = GURL(); 364 *origin = GURL();
393 return statement.Succeeded(); 365 return statement.Succeeded();
394 } 366 }
395 367
396 bool QuotaDatabase::GetOriginsModifiedSince( 368 bool QuotaDatabase::GetOriginsModifiedSince(
397 StorageType type, std::set<GURL>* origins, base::Time modified_since) { 369 StorageType type, std::set<GURL>* origins, base::Time modified_since) {
398 DCHECK(origins); 370 DCHECK(origins);
399 if (!LazyOpen(false)) 371 if (!LazyOpen(false))
400 return false; 372 return false;
401 373
402 const char* kSql = "SELECT origin FROM OriginInfoTable" 374 const char* kSql = "SELECT origin FROM OriginInfoTable"
403 " WHERE type = ? AND last_modified_time > ?"; 375 " WHERE type = ? AND last_modified_time > ?";
404 376
405 sql::Statement statement; 377 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
406 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
407 return false;
408 statement.BindInt(0, static_cast<int>(type)); 378 statement.BindInt(0, static_cast<int>(type));
409 statement.BindInt64(1, modified_since.ToInternalValue()); 379 statement.BindInt64(1, modified_since.ToInternalValue());
410 380
411 origins->clear(); 381 origins->clear();
412 while (statement.Step()) 382 while (statement.Step())
413 origins->insert(GURL(statement.ColumnString(0))); 383 origins->insert(GURL(statement.ColumnString(0)));
414 384
415 return statement.Succeeded(); 385 return statement.Succeeded();
416 } 386 }
417 387
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 bool QuotaDatabase::FindOriginUsedCount( 421 bool QuotaDatabase::FindOriginUsedCount(
452 const GURL& origin, StorageType type, int* used_count) { 422 const GURL& origin, StorageType type, int* used_count) {
453 DCHECK(used_count); 423 DCHECK(used_count);
454 if (!LazyOpen(false)) 424 if (!LazyOpen(false))
455 return false; 425 return false;
456 426
457 const char* kSql = 427 const char* kSql =
458 "SELECT used_count FROM OriginInfoTable" 428 "SELECT used_count FROM OriginInfoTable"
459 " WHERE origin = ? AND type = ?"; 429 " WHERE origin = ? AND type = ?";
460 430
461 sql::Statement statement; 431 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
462 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
463 return false;
464
465 statement.BindString(0, origin.spec()); 432 statement.BindString(0, origin.spec());
466 statement.BindInt(1, static_cast<int>(type)); 433 statement.BindInt(1, static_cast<int>(type));
467 if (!statement.Step() || !statement.Succeeded()) 434
435 if (!statement.Step())
468 return false; 436 return false;
469 437
470 *used_count = statement.ColumnInt(0); 438 *used_count = statement.ColumnInt(0);
471 return true; 439 return true;
472 } 440 }
473 441
474 bool QuotaDatabase::LazyOpen(bool create_if_needed) { 442 bool QuotaDatabase::LazyOpen(bool create_if_needed) {
475 if (db_.get()) 443 if (db_.get())
476 return true; 444 return true;
477 445
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 } 601 }
634 return false; 602 return false;
635 } 603 }
636 604
637 bool QuotaDatabase::DumpQuotaTable(QuotaTableCallback* callback) { 605 bool QuotaDatabase::DumpQuotaTable(QuotaTableCallback* callback) {
638 scoped_ptr<QuotaTableCallback> callback_deleter(callback); 606 scoped_ptr<QuotaTableCallback> callback_deleter(callback);
639 if (!LazyOpen(true)) 607 if (!LazyOpen(true))
640 return false; 608 return false;
641 609
642 const char* kSql = "SELECT * FROM HostQuotaTable"; 610 const char* kSql = "SELECT * FROM HostQuotaTable";
643 sql::Statement statement; 611 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
644 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
645 return false;
646 612
647 while (statement.Step()) { 613 while (statement.Step()) {
648 QuotaTableEntry entry = QuotaTableEntry( 614 QuotaTableEntry entry = QuotaTableEntry(
649 statement.ColumnString(0), 615 statement.ColumnString(0),
650 static_cast<StorageType>(statement.ColumnInt(1)), 616 static_cast<StorageType>(statement.ColumnInt(1)),
651 statement.ColumnInt64(2)); 617 statement.ColumnInt64(2));
652 618
653 if (!callback->Run(entry)) 619 if (!callback->Run(entry))
654 return true; 620 return true;
655 } 621 }
656 622
657 return statement.Succeeded(); 623 return statement.Succeeded();
658 } 624 }
659 625
660 bool QuotaDatabase::DumpOriginInfoTable( 626 bool QuotaDatabase::DumpOriginInfoTable(
661 OriginInfoTableCallback* callback) { 627 OriginInfoTableCallback* callback) {
662 scoped_ptr<OriginInfoTableCallback> callback_deleter(callback); 628 scoped_ptr<OriginInfoTableCallback> callback_deleter(callback);
663 629
664 if (!LazyOpen(true)) 630 if (!LazyOpen(true))
665 return false; 631 return false;
666 632
667 const char* kSql = "SELECT * FROM OriginInfoTable"; 633 const char* kSql = "SELECT * FROM OriginInfoTable";
668 sql::Statement statement; 634 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
669 if (!PrepareCachedStatement(db_.get(), SQL_FROM_HERE, kSql, &statement))
670 return false;
671 635
672 while (statement.Step()) { 636 while (statement.Step()) {
673 OriginInfoTableEntry entry( 637 OriginInfoTableEntry entry(
674 GURL(statement.ColumnString(0)), 638 GURL(statement.ColumnString(0)),
675 static_cast<StorageType>(statement.ColumnInt(1)), 639 static_cast<StorageType>(statement.ColumnInt(1)),
676 statement.ColumnInt(2), 640 statement.ColumnInt(2),
677 base::Time::FromInternalValue(statement.ColumnInt64(3)), 641 base::Time::FromInternalValue(statement.ColumnInt64(3)),
678 base::Time::FromInternalValue(statement.ColumnInt64(4))); 642 base::Time::FromInternalValue(statement.ColumnInt64(4)));
679 643
680 if (!callback->Run(entry)) 644 if (!callback->Run(entry))
(...skipping 17 matching lines...) Expand all
698 if (lhs.origin < rhs.origin) return true; 662 if (lhs.origin < rhs.origin) return true;
699 if (rhs.origin < lhs.origin) return false; 663 if (rhs.origin < lhs.origin) return false;
700 if (lhs.type < rhs.type) return true; 664 if (lhs.type < rhs.type) return true;
701 if (rhs.type < lhs.type) return false; 665 if (rhs.type < lhs.type) return false;
702 if (lhs.used_count < rhs.used_count) return true; 666 if (lhs.used_count < rhs.used_count) return true;
703 if (rhs.used_count < lhs.used_count) return false; 667 if (rhs.used_count < lhs.used_count) return false;
704 return lhs.last_access_time < rhs.last_access_time; 668 return lhs.last_access_time < rhs.last_access_time;
705 } 669 }
706 670
707 } // quota namespace 671 } // quota namespace
OLDNEW
« no previous file with comments | « webkit/database/quota_table.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698