blob: 1160f5f3a108505cfa20615fbccb5e881286ee22 [file] [log] [blame]
#!/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.
On Android, the database can be extracted using:
adb pull \
'/data/user/0/$package_name/app_chrome/Default/Network Action Predictor'
predictor_db
"""
import argparse
import sqlite3
from resource_prefetch_predictor_pb2 import (PrefetchData, ResourceData)
class Entry(object):
"""Represents an entry in the predictor database."""
def __init__(
self, primary_key, proto_buffer):
self.primary_key = primary_key
self.prefetch_data = PrefetchData()
self.prefetch_data.ParseFromString(proto_buffer)
@classmethod
def _ComputeResourceScore(cls, resource):
"""Mirrors ResourcePrefetchPredictorTables::ComputeResourceScore.
Args:
resource: ResourceData.
Return:
The resource score (int).
"""
priority_multiplier = 1
type_multiplier = 1
if resource.priority == ResourceData.REQUEST_PRIORITY_HIGHEST:
priority_multiplier = 3
elif resource.priority == ResourceData.REQUEST_PRIORITY_MEDIUM:
priority_multiplier = 2
if resource.resource_type in (ResourceData.RESOURCE_TYPE_STYLESHEET,
ResourceData.RESOURCE_TYPE_SCRIPT):
type_multiplier = 3
elif resource.resource_type == ResourceData.RESOURCE_TYPE_FONT_RESOURCE:
type_multiplier = 2
return (100 * (priority_multiplier * 100 + type_multiplier * 10)
- resource.average_position)
@classmethod
def FromRow(cls, row):
"""Builds an entry from a database row."""
return Entry(*row)
@classmethod
def _PrettyPrintResource(cls, resource):
"""Pretty-prints a resource to stdout.
Args:
resource: ResourceData.
"""
print 'score: %d' % cls._ComputeResourceScore(resource)
print resource
def PrettyPrintCandidates(self):
"""Prints the candidates for prefetch."""
print 'primary_key: %s' % self.prefetch_data.primary_key
for resource in self.prefetch_data.resources:
confidence = float(resource.number_of_hits) / (
resource.number_of_hits + resource.number_of_misses)
if resource.number_of_hits < 2 or confidence < .7:
continue
self._PrettyPrintResource(resource)
def DatabaseStats(filename, domain):
connection = sqlite3.connect(filename)
c = connection.cursor()
query = ('SELECT key, proto FROM resource_prefetch_predictor_host')
entries = [Entry.FromRow(row) for row in c.execute(query)]
for x in entries:
if domain is None or x.primary_key == domain:
x.PrettyPrintCandidates()
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()