Chromium Code Reviews| 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 current version of python sqilte3 library doesn't support views but | |
|
Benoit L
2017/01/11 09:36:45
Not sure about the "current" version, at least the
alexilin
2017/01/11 12:39:07
Done.
| |
| 82 # 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 | |
| 86 _, tmpfile = tempfile.mkstemp() | |
| 87 shutil.copy2(filename, tmpfile) | |
| 88 os.system('sqlite3 %s "DROP VIEW MmapStatus"' % (tmpfile,)) | |
|
Benoit L
2017/01/11 09:36:45
nit: why not subprocess.call(['sqlite3', tmpfile,
alexilin
2017/01/11 12:39:07
Done.
| |
| 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 database_copy = CreateCompatibleDatabaseCopy(args.database_filename) |
|
Benoit L
2017/01/11 09:36:45
nit:
try:
bla bla
finally:
os.remove(database
alexilin
2017/01/11 12:39:07
Done.
| |
| 108 DatabaseStats(database_copy, args.domain) | |
| 109 os.remove(database_copy) | |
| 98 | 110 |
| 99 | 111 |
| 100 if __name__ == '__main__': | 112 if __name__ == '__main__': |
| 101 main() | 113 main() |
| OLD | NEW |