OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright 2016 The Chromium Authors. All rights reserved. | 2 # Copyright 2016 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Inspection of the prefetch predictor database. | 6 """Inspection of the prefetch predictor database. |
7 | 7 |
8 On Android, the database can be extracted using: | 8 On Android, the database can be extracted using: |
9 adb pull \ | 9 adb pull \ |
10 '/data/user/0/$package_name/app_chrome/Default/Network Action Predictor' | 10 '/data/user/0/$package_name/app_chrome/Default/Network Action Predictor' |
11 predictor_db | 11 predictor_db |
12 """ | 12 """ |
13 | 13 |
14 import argparse | 14 import argparse |
15 import sqlite3 | 15 import sqlite3 |
| 16 import os |
16 | 17 |
17 from resource_prefetch_predictor_pb2 import (PrefetchData, ResourceData) | 18 from resource_prefetch_predictor_pb2 import (PrefetchData, ResourceData) |
18 | 19 |
19 | 20 |
20 class Entry(object): | 21 class Entry(object): |
21 """Represents an entry in the predictor database.""" | 22 """Represents an entry in the predictor database.""" |
22 def __init__( | 23 def __init__( |
23 self, primary_key, proto_buffer): | 24 self, primary_key, proto_buffer): |
24 self.primary_key = primary_key | 25 self.primary_key = primary_key |
25 self.prefetch_data = PrefetchData() | 26 self.prefetch_data = PrefetchData() |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 def PrettyPrintCandidates(self): | 71 def PrettyPrintCandidates(self): |
71 """Prints the candidates for prefetch.""" | 72 """Prints the candidates for prefetch.""" |
72 print 'primary_key: %s' % self.prefetch_data.primary_key | 73 print 'primary_key: %s' % self.prefetch_data.primary_key |
73 for resource in self.prefetch_data.resources: | 74 for resource in self.prefetch_data.resources: |
74 confidence = float(resource.number_of_hits) / ( | 75 confidence = float(resource.number_of_hits) / ( |
75 resource.number_of_hits + resource.number_of_misses) | 76 resource.number_of_hits + resource.number_of_misses) |
76 if resource.number_of_hits < 2 or confidence < .7: | 77 if resource.number_of_hits < 2 or confidence < .7: |
77 continue | 78 continue |
78 self._PrettyPrintResource(resource) | 79 self._PrettyPrintResource(resource) |
79 | 80 |
| 81 # The version of python sqlite3 library we have in Ubuntu 14.04 LTS doesn't |
| 82 # support views but command line util does. |
| 83 # TODO(alexilin): get rid of this when python sqlite3 adds view support. |
| 84 def CreateCompatibleDatabaseCopy(filename): |
| 85 import tempfile, shutil, subprocess |
| 86 _, tmpfile = tempfile.mkstemp() |
| 87 shutil.copy2(filename, tmpfile) |
| 88 subprocess.call(['sqlite3', tmpfile, 'DROP VIEW MmapStatus']) |
| 89 return tmpfile |
80 | 90 |
81 def DatabaseStats(filename, domain): | 91 def DatabaseStats(filename, domain): |
82 connection = sqlite3.connect(filename) | 92 connection = sqlite3.connect(filename) |
83 c = connection.cursor() | 93 c = connection.cursor() |
84 query = ('SELECT key, proto FROM resource_prefetch_predictor_host') | 94 query = ('SELECT key, proto FROM resource_prefetch_predictor_host') |
85 entries = [Entry.FromRow(row) for row in c.execute(query)] | 95 entries = [Entry.FromRow(row) for row in c.execute(query)] |
86 for x in entries: | 96 for x in entries: |
87 if domain is None or x.primary_key == domain: | 97 if domain is None or x.primary_key == domain: |
88 x.PrettyPrintCandidates() | 98 x.PrettyPrintCandidates() |
89 | 99 |
90 | 100 |
91 def main(): | 101 def main(): |
92 parser = argparse.ArgumentParser() | 102 parser = argparse.ArgumentParser() |
93 parser.add_argument('-f', dest='database_filename', required=True, | 103 parser.add_argument('-f', dest='database_filename', required=True, |
94 help='Path to the database') | 104 help='Path to the database') |
95 parser.add_argument('-d', dest='domain', default=None, help='Domain') | 105 parser.add_argument('-d', dest='domain', default=None, help='Domain') |
96 args = parser.parse_args() | 106 args = parser.parse_args() |
97 DatabaseStats(args.database_filename, args.domain) | 107 try: |
| 108 database_copy = CreateCompatibleDatabaseCopy(args.database_filename) |
| 109 DatabaseStats(database_copy, args.domain) |
| 110 finally: |
| 111 if os.path.exists(database_copy): |
| 112 os.remove(database_copy) |
98 | 113 |
99 | 114 |
100 if __name__ == '__main__': | 115 if __name__ == '__main__': |
101 main() | 116 main() |
OLD | NEW |