Chromium Code Reviews| Index: tools/resource_prefetch_predictor/prefetch_predictor_tool.py |
| diff --git a/tools/resource_prefetch_predictor/prefetch_predictor_tool.py b/tools/resource_prefetch_predictor/prefetch_predictor_tool.py |
| new file mode 100755 |
| index 0000000000000000000000000000000000000000..01abed8b42a1e821bfffffdf98cdd03cbd1d1a25 |
| --- /dev/null |
| +++ b/tools/resource_prefetch_predictor/prefetch_predictor_tool.py |
| @@ -0,0 +1,82 @@ |
| +#!/usr/bin/python |
| +# Copyright 2016 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +"""Inspection of the prefetch predictor database.""" |
| + |
| +import argparse |
| +import operator |
| +import sqlite3 |
| + |
| +class ResourceType(object): |
| + STYLESHEET = 2 |
| + SCRIPT = 3 |
| + |
| + |
| +class Entry(object): |
| + def __init__( |
| + self, main_page_url, resource_url, resource_type, number_of_hits, |
| + number_of_misses, consecutive_misses, average_position): |
| + self.main_page_url = main_page_url |
| + self.resource_url = resource_url |
| + self.resource_type = resource_type |
| + self.number_of_hits = int(number_of_hits) |
| + self.number_of_misses = int(number_of_misses) |
| + self.consecutive_misses = int(consecutive_misses) |
| + self.average_position = int(average_position) |
| + self.confidence = float(number_of_hits) / ( |
| + number_of_hits + number_of_misses) |
| + self.score = self._Score() |
| + |
| + def _Score(self): |
|
mattcary
2016/07/21 14:04:29
Add a comment about where this score calculation c
Benoit L
2016/07/21 14:48:42
/facepalm
Forgot to upload the latest revision of
|
| + multiplier = 1 |
| + if self.resource_type in (ResourceType.STYLESHEET, ResourceType.SCRIPT): |
| + multiplier = 2 |
| + return multiplier * 100 - self.average_position |
| + |
| + @classmethod |
| + def FromRow(cls, row): |
| + return Entry(*row) |
| + |
| + HEADER = ( |
| + 'score,main_page_url,resource_type,number_of_hits,number_of_misses,' |
| + 'consecutive_misses,average_position,confidence,resource_url') |
| + |
| + def __str__(self): |
| + return '%f,%s,%d,%d,%d,%d,%d,%f\t%s' % ( |
| + self.score, self.main_page_url, self.resource_type, |
| + self.number_of_hits, self.number_of_misses, self.consecutive_misses, |
| + self.average_position, self.confidence, self.resource_url) |
| + |
| + |
| +def FilterAndSort(entries, domain): |
| + result = filter( |
|
mattcary
2016/07/21 14:04:29
Ditto about where these threshold come from.
Benoit L
2016/07/21 14:48:42
Done.
|
| + lambda x: ((domain is None or x.main_page_url == domain) |
| + and x.confidence > .7 |
| + and x.number_of_hits >= 2), entries) |
| + return sorted(result, key=operator.attrgetter('score'), reverse=True) |
| + |
| + |
| +def DatabaseStats(filename, domain): |
| + connection = sqlite3.connect(filename) |
| + c = connection.cursor() |
| + query = 'SELECT * FROM resource_prefetch_predictor_host' |
|
mattcary
2016/07/21 14:04:29
It would be safer to name the fields that you're e
Benoit L
2016/07/21 14:48:42
Thanks!
Done.
|
| + entries = [Entry.FromRow(row) for row in c.execute(query)] |
| + prefetched = FilterAndSort(entries, domain) |
| + print Entry.HEADER |
| + for x in prefetched: |
| + print x |
| + |
| + |
| +def main(): |
| + parser = argparse.ArgumentParser() |
| + parser.add_argument('-f', dest='database_filename', required=True, |
| + help='Path to the database') |
| + parser.add_argument('-d', dest='domain', default=None, help='Domain') |
| + args = parser.parse_args() |
| + DatabaseStats(args.database_filename, args.domain) |
| + |
| + |
| +if __name__ == '__main__': |
| + main() |