OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "sql/connection.h" | 5 #include "sql/connection.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/dump_without_crashing.h" | 10 #include "base/debug/dump_without_crashing.h" |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 | 183 |
184 // TODO(shess): NULL in file->pMethods has been observed on android_dbg | 184 // TODO(shess): NULL in file->pMethods has been observed on android_dbg |
185 // content_unittests, even though it should not be possible. | 185 // content_unittests, even though it should not be possible. |
186 // http://crbug.com/329982 | 186 // http://crbug.com/329982 |
187 if (!*file || !(*file)->pMethods) | 187 if (!*file || !(*file)->pMethods) |
188 return SQLITE_ERROR; | 188 return SQLITE_ERROR; |
189 | 189 |
190 return rc; | 190 return rc; |
191 } | 191 } |
192 | 192 |
| 193 // Convenience to get the sqlite3_file* and the size for the "main" database. |
| 194 int GetSqlite3FileAndSize(sqlite3* db, |
| 195 sqlite3_file** file, sqlite3_int64* db_size) { |
| 196 int rc = GetSqlite3File(db, file); |
| 197 if (rc != SQLITE_OK) |
| 198 return rc; |
| 199 |
| 200 return (*file)->pMethods->xFileSize(*file, db_size); |
| 201 } |
| 202 |
193 // This should match UMA_HISTOGRAM_MEDIUM_TIMES(). | 203 // This should match UMA_HISTOGRAM_MEDIUM_TIMES(). |
194 base::HistogramBase* GetMediumTimeHistogram(const std::string& name) { | 204 base::HistogramBase* GetMediumTimeHistogram(const std::string& name) { |
195 return base::Histogram::FactoryTimeGet( | 205 return base::Histogram::FactoryTimeGet( |
196 name, | 206 name, |
197 base::TimeDelta::FromMilliseconds(10), | 207 base::TimeDelta::FromMilliseconds(10), |
198 base::TimeDelta::FromMinutes(3), | 208 base::TimeDelta::FromMinutes(3), |
199 50, | 209 50, |
200 base::HistogramBase::kUmaTargetedHistogramFlag); | 210 base::HistogramBase::kUmaTargetedHistogramFlag); |
201 } | 211 } |
202 | 212 |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 } | 518 } |
509 | 519 |
510 // Use local settings if provided, otherwise use documented defaults. The | 520 // Use local settings if provided, otherwise use documented defaults. The |
511 // actual results could be fetching via PRAGMA calls. | 521 // actual results could be fetching via PRAGMA calls. |
512 const int page_size = page_size_ ? page_size_ : 1024; | 522 const int page_size = page_size_ ? page_size_ : 1024; |
513 sqlite3_int64 preload_size = page_size * (cache_size_ ? cache_size_ : 2000); | 523 sqlite3_int64 preload_size = page_size * (cache_size_ ? cache_size_ : 2000); |
514 if (preload_size < 1) | 524 if (preload_size < 1) |
515 return; | 525 return; |
516 | 526 |
517 sqlite3_file* file = NULL; | 527 sqlite3_file* file = NULL; |
518 int rc = GetSqlite3File(db_, &file); | 528 sqlite3_int64 file_size = 0; |
| 529 int rc = GetSqlite3FileAndSize(db_, &file, &file_size); |
519 if (rc != SQLITE_OK) | 530 if (rc != SQLITE_OK) |
520 return; | 531 return; |
521 | 532 |
522 sqlite3_int64 file_size = 0; | |
523 rc = file->pMethods->xFileSize(file, &file_size); | |
524 if (rc != SQLITE_OK) | |
525 return; | |
526 | |
527 // Don't preload more than the file contains. | 533 // Don't preload more than the file contains. |
528 if (preload_size > file_size) | 534 if (preload_size > file_size) |
529 preload_size = file_size; | 535 preload_size = file_size; |
530 | 536 |
531 scoped_ptr<char[]> buf(new char[page_size]); | 537 scoped_ptr<char[]> buf(new char[page_size]); |
532 for (sqlite3_int64 pos = 0; pos < preload_size; pos += page_size) { | 538 for (sqlite3_int64 pos = 0; pos < preload_size; pos += page_size) { |
533 rc = file->pMethods->xRead(file, buf.get(), page_size, pos); | 539 rc = file->pMethods->xRead(file, buf.get(), page_size, pos); |
534 if (rc != SQLITE_OK) | 540 if (rc != SQLITE_OK) |
535 return; | 541 return; |
536 } | 542 } |
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1649 } | 1655 } |
1650 | 1656 |
1651 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) { | 1657 if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) { |
1652 bool was_poisoned = poisoned_; | 1658 bool was_poisoned = poisoned_; |
1653 Close(); | 1659 Close(); |
1654 if (was_poisoned && retry_flag == RETRY_ON_POISON) | 1660 if (was_poisoned && retry_flag == RETRY_ON_POISON) |
1655 return OpenInternal(file_name, NO_RETRY); | 1661 return OpenInternal(file_name, NO_RETRY); |
1656 return false; | 1662 return false; |
1657 } | 1663 } |
1658 | 1664 |
| 1665 // Set a reasonable chunk size for larger files. This reduces churn from |
| 1666 // remapping memory on size changes. It also reduces filesystem |
| 1667 // fragmentation. |
| 1668 // TODO(shess): It may make sense to have this be hinted by the client. |
| 1669 // Database sizes seem to be bimodal, some clients have consistently small |
| 1670 // databases (<20k) while other clients have a broad distribution of sizes |
| 1671 // (hundreds of kilobytes to many megabytes). |
| 1672 sqlite3_file* file = NULL; |
| 1673 sqlite3_int64 db_size = 0; |
| 1674 int rc = GetSqlite3FileAndSize(db_, &file, &db_size); |
| 1675 if (rc == SQLITE_OK && db_size > 16 * 1024) { |
| 1676 int chunk_size = 4 * 1024; |
| 1677 if (db_size > 128 * 1024) |
| 1678 chunk_size = 32 * 1024; |
| 1679 sqlite3_file_control(db_, NULL, SQLITE_FCNTL_CHUNK_SIZE, &chunk_size); |
| 1680 } |
| 1681 |
1659 // Enable memory-mapped access. The explicit-disable case is because SQLite | 1682 // Enable memory-mapped access. The explicit-disable case is because SQLite |
1660 // can be built to default-enable mmap. This value will be capped by | 1683 // can be built to default-enable mmap. This value will be capped by |
1661 // SQLITE_MAX_MMAP_SIZE, which could be different between 32-bit and 64-bit | 1684 // SQLITE_MAX_MMAP_SIZE, which could be different between 32-bit and 64-bit |
1662 // platforms. | 1685 // platforms. |
1663 if (mmap_disabled_) { | 1686 if (mmap_disabled_) { |
1664 ignore_result(Execute("PRAGMA mmap_size = 0")); | 1687 ignore_result(Execute("PRAGMA mmap_size = 0")); |
1665 } else { | 1688 } else { |
1666 ignore_result(Execute("PRAGMA mmap_size = 268435456")); // 256MB. | 1689 ignore_result(Execute("PRAGMA mmap_size = 268435456")); // 256MB. |
1667 } | 1690 } |
1668 | 1691 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 ignore_result(Execute(kNoWritableSchema)); | 1830 ignore_result(Execute(kNoWritableSchema)); |
1808 | 1831 |
1809 return ret; | 1832 return ret; |
1810 } | 1833 } |
1811 | 1834 |
1812 base::TimeTicks TimeSource::Now() { | 1835 base::TimeTicks TimeSource::Now() { |
1813 return base::TimeTicks::Now(); | 1836 return base::TimeTicks::Now(); |
1814 } | 1837 } |
1815 | 1838 |
1816 } // namespace sql | 1839 } // namespace sql |
OLD | NEW |