diff options
-rw-r--r-- | content/browser/quota/quota_database_unittest.cc | 50 | ||||
-rw-r--r-- | content/browser/quota/quota_manager_unittest.cc | 35 | ||||
-rw-r--r-- | storage/browser/quota/quota_database.cc | 27 | ||||
-rw-r--r-- | storage/browser/quota/quota_database.h | 45 | ||||
-rw-r--r-- | storage/browser/quota/quota_manager.cc | 21 | ||||
-rw-r--r-- | storage/browser/quota/quota_manager.h | 2 | ||||
-rw-r--r-- | tools/metrics/histograms/histograms.xml | 16 |
7 files changed, 161 insertions, 35 deletions
diff --git a/content/browser/quota/quota_database_unittest.cc b/content/browser/quota/quota_database_unittest.cc index 4bfdd8b..8365e64 100644 --- a/content/browser/quota/quota_database_unittest.cc +++ b/content/browser/quota/quota_database_unittest.cc @@ -306,8 +306,8 @@ class QuotaDatabaseTest : public testing::Test { const GURL kOrigin3("http://c/"); base::Time last_eviction_time; - EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary, - &last_eviction_time)); + EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary, + &last_eviction_time)); EXPECT_EQ(base::Time(), last_eviction_time); // Report last eviction time for the test origins. @@ -337,14 +337,14 @@ class QuotaDatabaseTest : public testing::Test { db.DeleteOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary)); last_eviction_time = base::Time(); - EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary, - &last_eviction_time)); + EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin1, kStorageTypeTemporary, + &last_eviction_time)); EXPECT_EQ(base::Time(), last_eviction_time); - EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin2, kStorageTypeTemporary, - &last_eviction_time)); + EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin2, kStorageTypeTemporary, + &last_eviction_time)); EXPECT_EQ(base::Time(), last_eviction_time); - EXPECT_TRUE(db.GetOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary, - &last_eviction_time)); + EXPECT_FALSE(db.GetOriginLastEvictionTime(kOrigin3, kStorageTypeTemporary, + &last_eviction_time)); EXPECT_EQ(base::Time(), last_eviction_time); // Deleting an origin that is not present should not fail. @@ -445,6 +445,36 @@ class QuotaDatabaseTest : public testing::Test { EXPECT_TRUE(verifier.table.empty()); } + void GetOriginInfo(const base::FilePath& kDbFile) { + const GURL kOrigin = GURL("http://go/"); + typedef QuotaDatabase::OriginInfoTableEntry Entry; + Entry kTableEntries[] = { + Entry(kOrigin, kStorageTypeTemporary, 100, base::Time(), base::Time())}; + Entry* begin = kTableEntries; + Entry* end = kTableEntries + arraysize(kTableEntries); + + QuotaDatabase db(kDbFile); + EXPECT_TRUE(db.LazyOpen(true)); + AssignOriginInfoTable(db.db_.get(), begin, end); + db.Commit(); + + { + Entry entry; + EXPECT_TRUE(db.GetOriginInfo(kOrigin, kStorageTypeTemporary, &entry)); + EXPECT_EQ(kTableEntries[0].type, entry.type); + EXPECT_EQ(kTableEntries[0].origin, entry.origin); + EXPECT_EQ(kTableEntries[0].used_count, entry.used_count); + EXPECT_EQ(kTableEntries[0].last_access_time, entry.last_access_time); + EXPECT_EQ(kTableEntries[0].last_modified_time, entry.last_modified_time); + } + + { + Entry entry; + EXPECT_FALSE(db.GetOriginInfo(GURL("http://notpresent.org/"), + kStorageTypeTemporary, &entry)); + } + } + private: template <typename Iterator> void AssignQuotaTable(sql::Connection* db, Iterator itr, Iterator end) { @@ -645,6 +675,10 @@ TEST_F(QuotaDatabaseTest, DumpOriginInfoTable) { DumpOriginInfoTable(base::FilePath()); } +TEST_F(QuotaDatabaseTest, GetOriginInfo) { + GetOriginInfo(base::FilePath()); +} + TEST_F(QuotaDatabaseTest, OpenCorruptedDatabase) { base::ScopedTempDir data_dir; ASSERT_TRUE(data_dir.CreateUniqueTempDir()); diff --git a/content/browser/quota/quota_manager_unittest.cc b/content/browser/quota/quota_manager_unittest.cc index 6a7d1d9..a2b3a42 100644 --- a/content/browser/quota/quota_manager_unittest.cc +++ b/content/browser/quota/quota_manager_unittest.cc @@ -1361,7 +1361,7 @@ TEST_F(QuotaManagerTest, EvictOriginData) { } TEST_F(QuotaManagerTest, EvictOriginDataHistogram) { - const GURL kOrigin = GURL("http://foo.com"); + const GURL kOrigin = GURL("http://foo.com/"); static const MockOriginData kData[] = { {"http://foo.com/", kTemp, 1}, }; @@ -1374,31 +1374,52 @@ TEST_F(QuotaManagerTest, EvictOriginDataHistogram) { GetGlobalUsage(kTemp); base::RunLoop().RunUntilIdle(); - EvictOriginData(GURL("http://foo.com/"), kTemp); + EvictOriginData(kOrigin, kTemp); base::RunLoop().RunUntilIdle(); + // Ensure used count and time since access are recorded. + histograms.ExpectTotalCount( + QuotaManager::kEvictedOriginAccessedCountHistogram, 1); + histograms.ExpectBucketCount( + QuotaManager::kEvictedOriginAccessedCountHistogram, 0, 1); + histograms.ExpectTotalCount( + QuotaManager::kEvictedOriginTimeSinceAccessHistogram, 1); + // First eviction has no 'last' time to compare to. histograms.ExpectTotalCount( QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, 0); - client->AddOriginAndNotify(GURL("http://foo.com"), kTemp, 100); + client->AddOriginAndNotify(kOrigin, kTemp, 100); + + // Change the used count of the origin. + quota_manager()->NotifyStorageAccessed(QuotaClient::kUnknown, GURL(kOrigin), + kTemp); + base::RunLoop().RunUntilIdle(); GetGlobalUsage(kTemp); base::RunLoop().RunUntilIdle(); - EvictOriginData(GURL("http://foo.com/"), kTemp); + EvictOriginData(kOrigin, kTemp); base::RunLoop().RunUntilIdle(); - // Second eviction should log a histogram sample. + // The new used count should be logged. + histograms.ExpectTotalCount( + QuotaManager::kEvictedOriginAccessedCountHistogram, 2); + histograms.ExpectBucketCount( + QuotaManager::kEvictedOriginAccessedCountHistogram, 1, 1); + histograms.ExpectTotalCount( + QuotaManager::kEvictedOriginTimeSinceAccessHistogram, 2); + + // Second eviction should log a 'time between repeated eviction' sample. histograms.ExpectTotalCount( QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, 1); - client->AddOriginAndNotify(GURL("http://foo.com"), kTemp, 100); + client->AddOriginAndNotify(kOrigin, kTemp, 100); GetGlobalUsage(kTemp); base::RunLoop().RunUntilIdle(); - DeleteOriginFromDatabase(GURL("http://foo.com"), kTemp); + DeleteOriginFromDatabase(kOrigin, kTemp); // Deletion from non-eviction source should not log a histogram sample. histograms.ExpectTotalCount( diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc index 5fcacd5..36632c6 100644 --- a/storage/browser/quota/quota_database.cc +++ b/storage/browser/quota/quota_database.cc @@ -275,7 +275,7 @@ bool QuotaDatabase::GetOriginLastEvictionTime(const GURL& origin, statement.BindInt(1, static_cast<int>(type)); if (!statement.Step()) - return statement.Succeeded(); + return false; *last_modified_time = base::Time::FromInternalValue(statement.ColumnInt64(0)); return true; @@ -346,6 +346,31 @@ bool QuotaDatabase::RegisterInitialOriginInfo( return true; } +bool QuotaDatabase::GetOriginInfo(const GURL& origin, + StorageType type, + QuotaDatabase::OriginInfoTableEntry* entry) { + if (!LazyOpen(false)) + return false; + + const char* kSql = + "SELECT * FROM OriginInfoTable" + " WHERE origin = ? AND type = ?"; + sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql)); + statement.BindString(0, origin.spec()); + statement.BindInt(1, static_cast<int>(type)); + + if (!statement.Step()) + return false; + + *entry = OriginInfoTableEntry( + GURL(statement.ColumnString(0)), + static_cast<StorageType>(statement.ColumnInt(1)), statement.ColumnInt(2), + base::Time::FromInternalValue(statement.ColumnInt64(3)), + base::Time::FromInternalValue(statement.ColumnInt64(4))); + + return true; +} + bool QuotaDatabase::DeleteHostQuota( const std::string& host, StorageType type) { if (!LazyOpen(false)) diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h index e95fba8..dae5581 100644 --- a/storage/browser/quota/quota_database.h +++ b/storage/browser/quota/quota_database.h @@ -36,6 +36,20 @@ class SpecialStoragePolicy; // All the methods of this class must run on the DB thread. class STORAGE_EXPORT_PRIVATE QuotaDatabase { public: + struct STORAGE_EXPORT_PRIVATE OriginInfoTableEntry { + OriginInfoTableEntry(); + OriginInfoTableEntry(const GURL& origin, + StorageType type, + int used_count, + const base::Time& last_access_time, + const base::Time& last_modified_time); + GURL origin; + StorageType type; + int used_count; + base::Time last_access_time; + base::Time last_modified_time; + }; + // Constants for {Get,Set}QuotaConfigValue keys. static const char kDesiredAvailableSpaceKey[]; static const char kTemporaryQuotaOverrideKey[]; @@ -46,7 +60,10 @@ class STORAGE_EXPORT_PRIVATE QuotaDatabase { void CloseConnection(); + // Returns whether the record could be found. bool GetHostQuota(const std::string& host, StorageType type, int64* quota); + + // Returns whether the operation succeeded. bool SetHostQuota(const std::string& host, StorageType type, int64 quota); bool DeleteHostQuota(const std::string& host, StorageType type); @@ -58,9 +75,14 @@ class STORAGE_EXPORT_PRIVATE QuotaDatabase { StorageType type, base::Time last_modified_time); + // Gets the time |origin| was last evicted. Returns whether the record could + // be found. bool GetOriginLastEvictionTime(const GURL& origin, StorageType type, base::Time* last_eviction_time); + + // Sets the time the origin was last evicted. Returns whether the operation + // succeeded. bool SetOriginLastEvictionTime(const GURL& origin, StorageType type, base::Time last_eviction_time); @@ -72,6 +94,12 @@ class STORAGE_EXPORT_PRIVATE QuotaDatabase { bool RegisterInitialOriginInfo( const std::set<GURL>& origins, StorageType type); + // Gets the OriginInfoTableEntry for |origin|. Returns whether the record + // could be found. + bool GetOriginInfo(const GURL& origin, + StorageType type, + OriginInfoTableEntry* entry); + bool DeleteOriginInfo(const GURL& origin, StorageType type); bool GetQuotaConfigValue(const char* key, int64* value); @@ -87,7 +115,7 @@ class STORAGE_EXPORT_PRIVATE QuotaDatabase { GURL* origin); // Populates |origins| with the ones that have been modified since - // the |modified_since|. + // the |modified_since|. Returns whether the operation succeeded. bool GetOriginsModifiedSince(StorageType type, std::set<GURL>* origins, base::Time modified_since); @@ -111,21 +139,6 @@ class STORAGE_EXPORT_PRIVATE QuotaDatabase { }; friend STORAGE_EXPORT_PRIVATE bool operator <( const QuotaTableEntry& lhs, const QuotaTableEntry& rhs); - - struct STORAGE_EXPORT_PRIVATE OriginInfoTableEntry { - OriginInfoTableEntry(); - OriginInfoTableEntry( - const GURL& origin, - StorageType type, - int used_count, - const base::Time& last_access_time, - const base::Time& last_modified_time); - GURL origin; - StorageType type; - int used_count; - base::Time last_access_time; - base::Time last_modified_time; - }; friend STORAGE_EXPORT_PRIVATE bool operator <( const OriginInfoTableEntry& lhs, const OriginInfoTableEntry& rhs); diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc index 0052f2d..c0f7560 100644 --- a/storage/browser/quota/quota_manager.cc +++ b/storage/browser/quota/quota_manager.cc @@ -76,6 +76,10 @@ const int QuotaManager::kEvictionIntervalInMilliSeconds = const char QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram[] = "Quota.TimeBetweenRepeatedOriginEvictions"; +const char QuotaManager::kEvictedOriginAccessedCountHistogram[] = + "Quota.EvictedOriginAccessCount"; +const char QuotaManager::kEvictedOriginTimeSinceAccessHistogram[] = + "Quota.EvictedOriginTimeSinceAccess"; // Heuristics: assuming average cloud server allows a few Gigs storage // on the server side and the storage needs to be shared for user data @@ -159,6 +163,19 @@ bool DeleteOriginInfoOnDBThread(const GURL& origin, bool is_eviction, QuotaDatabase* database) { DCHECK(database); + + base::Time now = base::Time::Now(); + + if (is_eviction) { + QuotaDatabase::OriginInfoTableEntry entry; + database->GetOriginInfo(origin, type, &entry); + UMA_HISTOGRAM_COUNTS(QuotaManager::kEvictedOriginAccessedCountHistogram, + entry.used_count); + UMA_HISTOGRAM_LONG_TIMES( + QuotaManager::kEvictedOriginTimeSinceAccessHistogram, + now - entry.last_access_time); + } + if (!database->DeleteOriginInfo(origin, type)) return false; @@ -168,10 +185,8 @@ bool DeleteOriginInfoOnDBThread(const GURL& origin, return database->DeleteOriginLastEvictionTime(origin, type); base::Time last_eviction_time; - if (!database->GetOriginLastEvictionTime(origin, type, &last_eviction_time)) - return false; + database->GetOriginLastEvictionTime(origin, type, &last_eviction_time); - base::Time now = base::Time::Now(); if (last_eviction_time != base::Time()) { UMA_HISTOGRAM_LONG_TIMES( QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram, diff --git a/storage/browser/quota/quota_manager.h b/storage/browser/quota/quota_manager.h index bacf80b..2f9f16f 100644 --- a/storage/browser/quota/quota_manager.h +++ b/storage/browser/quota/quota_manager.h @@ -277,6 +277,8 @@ class STORAGE_EXPORT QuotaManager static const int kEvictionIntervalInMilliSeconds; static const char kTimeBetweenRepeatedOriginEvictionsHistogram[]; + static const char kEvictedOriginAccessedCountHistogram[]; + static const char kEvictedOriginTimeSinceAccessHistogram[]; // These are kept non-const so that test code can change the value. // TODO(kinuko): Make this a real const value and add a proper way to set diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 42330e5..3dcdb6e 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -36986,11 +36986,27 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. </summary> </histogram> +<histogram name="Quota.EvictedOriginAccessCount"> + <owner>calamity@chromium.org</owner> + <summary> + The number of times the evicted origin was accessed. Logged when the origin + is evicted. + </summary> +</histogram> + <histogram name="Quota.EvictedOriginsPerHour"> <owner>tzik@chromium.org</owner> <summary>Number of evicted origins in an hour.</summary> </histogram> +<histogram name="Quota.EvictedOriginTimeSinceAccess"> + <owner>calamity@chromium.org</owner> + <summary> + The time since the evicted origin was last accessed. Logged when the origin + is evicted. + </summary> +</histogram> + <histogram name="Quota.EvictionRoundsPerHour"> <owner>tzik@chromium.org</owner> <summary>Number of eviction rounds in an hour.</summary> |