calculate top 95% for app/version combos (bug 675810)

This commit is contained in:
Jeff Balogh 2011-09-30 13:34:22 -07:00
Родитель 5e3cc599eb
Коммит 0cdfc1020a
3 изменённых файлов: 45 добавлений и 12 удалений

Просмотреть файл

@ -1,7 +1,8 @@
import collections
import logging
from collections import defaultdict
from django.db.models import Sum, Max
from django.conf import settings
from django.db.models import Max
import cronjobs
import elasticutils
@ -11,6 +12,7 @@ import amo
import amo.utils
from addons.models import Addon
from stats.models import UpdateCount
from versions.compare import version_int as vint
from .models import AppCompat
@ -20,7 +22,7 @@ log = logging.getLogger('z.compat')
@cronjobs.register
def compatibility_report():
redis = redisutils.connections['master']
docs = collections.defaultdict(dict)
docs = defaultdict(dict)
# Gather all the data for the index.
for app in amo.APP_USAGE:
@ -30,10 +32,7 @@ def compatibility_report():
addon__disabled_by_user=False,
addon__status__in=amo.VALID_STATUSES,
addon___current_version__isnull=False,
date=latest).order_by('-count')
total = qs.aggregate(Sum('count'))['count__sum']
redis.hset('compat:%s' % app.id, 'total', total)
adus = 0
date=latest)
updates = dict(qs.values_list('addon', 'count'))
for chunk in amo.utils.chunked(updates.items(), 50):
@ -42,6 +41,10 @@ def compatibility_report():
doc = docs[addon.id]
doc.update(id=addon.id, slug=addon.slug, binary=addon.binary,
name=unicode(addon.name), created=addon.created)
doc['count'] = chunk[addon.id]
doc.setdefault('top_95',
defaultdict(lambda: defaultdict(dict)))
doc.setdefault('top_95_all', {})
doc.setdefault('usage', {})[app.id] = updates[addon.id]
if app not in addon.compatible_apps:
@ -51,9 +54,35 @@ def compatibility_report():
'max': compat.max.version_int}
doc.setdefault('support', {})[app.id] = d
doc.setdefault('max_version', {})[app.id] = compat.max.version
doc['top_95'] = adus > .95 * total
adus += sum(chunk.values())
total = sum(updates.values())
# Remember the total so we can show % of usage later.
redis.hset('compat:%s' % app.id, 'total', total)
# Figure out which add-ons are in the top 95% for this app.
running_total = 0
for addon, count in sorted(updates.items(), key=lambda x: x[1]):
running_total += count
if 'top_95_all' not in docs[addon]:
print docs[addon]
docs[addon]['top_95_all'][app.id] = running_total < (.95 * total)
# Mark the top 95% of add-ons compatible with the previous version for each
# app + version combo.
for compat in settings.COMPAT:
app, ver = compat['app'], vint(compat['previous'])
# Find all the docs that have a max_version compatible with ver.
supported = [doc for doc in docs.values()
if app in doc.get('support', {})
and doc['support'][app]['max'] >= ver]
# Sort by count so we can get the top 95% most-used add-ons.
supported = sorted(supported, key=lambda d: d['count'])
total = sum(doc['count'] for doc in supported)
# Figure out which add-ons are in the top 95% for this app + version.
running_total = 0
for doc in supported:
running_total += doc['count']
doc['top_95'][app][ver] = running_total < (.95 * total)
# Send it all to the index.
for chunk in amo.utils.chunked(docs.values(), 150):

Просмотреть файл

@ -29,6 +29,9 @@ class AppCompat(amo.models.ModelBase):
name: addon.name,
slug: addon.slug,
binary: addon.binary,
count: total # of update counts,
top_95_all: {APP.id: bool},
top_95: {APP.id: {version int: bool}},
max_version: {APP.id: version string},
usage: {APP.id: addon.daily_usage},
support: {APP.id: {max: version int, min: version int},

Просмотреть файл

@ -31,7 +31,7 @@ def index(request, version=None):
qs = AppCompat.search()
binary = None
initial= {'appver': '%s-%s' % (request.APP.id, version), 'type': 'all'}
initial = {'appver': '%s-%s' % (request.APP.id, version), 'type': 'all'}
initial.update(request.GET.items())
form = CompatForm(initial)
if request.GET and form.is_valid():
@ -48,9 +48,10 @@ def index(request, version=None):
compat, app = compat_dict[version], str(request.APP.id)
compat_queries = (
('prev', qs.query(top_95=True, **{
('prev', qs.query(**{
'top_95.%s.%s' % (app, vint(compat['previous'])): True,
'support.%s.max__gte' % app: vint(compat['previous'])})),
('top_95', qs.query(top_95=True)),
('top_95', qs.query(**{'top_95_all.%s' % app: True})),
('all', qs),
)
compat_levels = [(key, version_compat(qs, compat, app, binary))