Fixing build: GetViewContainer changed name from under me. :)
[chromium-blink-merge.git] / chrome / browser / visitedlink_perftest.cc
blob4f7dc4ae9acc17373bb75e464828b37e9c31084e
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <algorithm>
6 #include <string>
7 #include <vector>
9 #include "base/file_util.h"
10 #include "base/perftimer.h"
11 #include "base/shared_memory.h"
12 #include "base/string_util.h"
13 #include "chrome/browser/visitedlink_master.h"
14 #include "chrome/test/test_file_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace {
19 // how we generate URLs, note that the two strings should be the same length
20 const int add_count = 10000;
21 const int load_test_add_count = 250000;
22 const char added_prefix[] = "http://www.google.com/stuff/something/foo?session=85025602345625&id=1345142319023&seq=";
23 const char unadded_prefix[] = "http://www.google.org/stuff/something/foo?session=39586739476365&id=2347624314402&seq=";
25 // Returns a URL with the given prefix and index
26 GURL TestURL(const char* prefix, int i) {
27 return GURL(StringPrintf("%s%d", prefix, i));
30 // we have no slaves, so this broadcase is a NOP
31 VisitedLinkMaster::PostNewTableEvent DummyBroadcastNewTableEvent;
32 void DummyBroadcastNewTableEvent(SharedMemory *table) {
35 // Call at the beginning of the test to retrieve the database name and to
36 // delete any old databases left by previous unit tests. The input buffer
37 // should be MAX_PATH long.
38 void InitDBName(wchar_t* db_name) {
39 ASSERT_TRUE(GetCurrentDirectory(MAX_PATH, db_name));
40 if (db_name[wcslen(db_name) - 1] != file_util::kPathSeparator)
41 wcsncat_s(db_name, MAX_PATH, &file_util::kPathSeparator, 1);
42 wcscat_s(db_name, MAX_PATH, L"TempVisitedLinks");
45 // this checks IsVisited for the URLs starting with the given prefix and
46 // within the given range
47 void CheckVisited(VisitedLinkMaster& master, const char* prefix,
48 int begin, int end) {
49 for (int i = begin; i < end; i++)
50 master.IsVisited(TestURL(prefix, i));
53 // Fills that master's table with URLs starting with the given prefix and
54 // within the given range
55 void FillTable(VisitedLinkMaster& master, const char* prefix,
56 int begin, int end) {
57 for (int i = begin; i < end; i++)
58 master.AddURL(TestURL(prefix, i));
61 class VisitedLink : public testing::Test {
62 protected:
63 wchar_t db_name_[MAX_PATH];
64 virtual void SetUp() {
65 InitDBName(db_name_);
66 DeleteFile(db_name_);
68 virtual void TearDown() {
69 DeleteFile(db_name_);
73 } // namespace
75 // This test tests adding many things to a database, and how long it takes
76 // to query the database with different numbers of things in it. The time
77 // is the total time to do all the operations, and as such, it is only
78 // useful for a regression test. If there is a regression, it might be
79 // useful to make another set of tests to test these things in isolation.
80 TEST_F(VisitedLink, TestAddAndQuery) {
81 // init
82 VisitedLinkMaster master(NULL, DummyBroadcastNewTableEvent, NULL, true,
83 db_name_, 0);
84 ASSERT_TRUE(master.Init());
86 PerfTimeLogger timer("Visited_link_add_and_query");
88 // first check without anything in the table
89 CheckVisited(master, added_prefix, 0, add_count);
91 // now fill half the table
92 const int half_size = add_count / 2;
93 FillTable(master, added_prefix, 0, half_size);
95 // check the table again, half of these URLs will be visited, the other half
96 // will not
97 CheckVisited(master, added_prefix, 0, add_count);
99 // fill the rest of the table
100 FillTable(master, added_prefix, half_size, add_count);
102 // check URLs, doing half visited, half unvisited
103 CheckVisited(master, added_prefix, 0, add_count);
104 CheckVisited(master, unadded_prefix, 0, add_count);
107 // Tests how long it takes to write and read a large database to and from disk.
108 TEST_F(VisitedLink, TestLoad) {
109 // create a big DB
111 PerfTimeLogger table_initialization_timer("Table_initialization");
113 VisitedLinkMaster master(NULL, DummyBroadcastNewTableEvent, NULL, true,
114 db_name_, 0);
116 // time init with empty table
117 PerfTimeLogger initTimer("Empty_visited_link_init");
118 bool success = master.Init();
119 initTimer.Done();
120 ASSERT_TRUE(success);
122 // add a bunch of stuff
123 // TODO(maruel): This is very inefficient because the file gets rewritten
124 // many time and this is the actual bottleneck of this test. The file should
125 // only get written that the end of the FillTable call, not 4169(!) times.
126 FillTable(master, added_prefix, 0, load_test_add_count);
128 // time writing the file out out
129 PerfTimeLogger flushTimer("Visited_link_database_flush");
130 master.RewriteFile();
131 // TODO(maruel): Without calling FlushFileBuffers(master.file_); you don't
132 // know really how much time it took to write the file.
133 flushTimer.Done();
135 table_initialization_timer.Done();
138 // test loading the DB back, we do this several times since the flushing is
139 // not very reliable.
140 const int load_count = 5;
141 std::vector<double> cold_load_times;
142 std::vector<double> hot_load_times;
143 for (int i = 0; i < load_count; i++)
145 // make sure the file has to be re-loaded
146 file_util::EvictFileFromSystemCache(db_name_);
148 // cold load (no OS cache, hopefully)
150 PerfTimer cold_timer;
152 VisitedLinkMaster master(NULL, DummyBroadcastNewTableEvent, NULL, true,
153 db_name_, 0);
154 bool success = master.Init();
155 TimeDelta elapsed = cold_timer.Elapsed();
156 ASSERT_TRUE(success);
158 cold_load_times.push_back(elapsed.InMillisecondsF());
161 // hot load (with OS caching the file in memory)
163 PerfTimer hot_timer;
165 VisitedLinkMaster master(NULL, DummyBroadcastNewTableEvent, NULL, true,
166 db_name_, 0);
167 bool success = master.Init();
168 TimeDelta elapsed = hot_timer.Elapsed();
169 ASSERT_TRUE(success);
171 hot_load_times.push_back(elapsed.InMillisecondsF());
175 // We discard the max and return the average time.
176 cold_load_times.erase(std::max_element(cold_load_times.begin(),
177 cold_load_times.end()));
178 hot_load_times.erase(std::max_element(hot_load_times.begin(),
179 hot_load_times.end()));
181 double cold_sum = 0, hot_sum = 0;
182 for (int i = 0; i < static_cast<int>(cold_load_times.size()); i++) {
183 cold_sum += cold_load_times[i];
184 hot_sum += hot_load_times[i];
186 LogPerfResult("Visited_link_cold_load_time",
187 cold_sum / cold_load_times.size(), "ms");
188 LogPerfResult("Visited_link_hot_load_time",
189 hot_sum / hot_load_times.size(), "ms");