findClips: avoid O(n²) lookup of clip from annotation

This doesn't make much difference for small ranges, of course.
This commit is contained in:
Will Thompson 2016-04-18 16:02:13 +01:00
parent ba00bcbf7b
commit d0129a4416
No known key found for this signature in database
GPG key ID: 3422DC0D7AD482A7

View file

@ -97,7 +97,6 @@ def findClips(request, data):
qs = qs[query['range'][0]:query['range'][1]] qs = qs[query['range'][0]:query['range'][1]]
qs = qs.select_related('item') qs = qs.select_related('item')
ids = []
layers = settings.CONFIG['layers'] layers = settings.CONFIG['layers']
subtitles = utils.get_by_key(layers, 'isSubtitles', True) subtitles = utils.get_by_key(layers, 'isSubtitles', True)
layer_ids = [k['id'] for k in layers] layer_ids = [k['id'] for k in layers]
@ -105,18 +104,17 @@ def findClips(request, data):
if filter(lambda k: k not in models.Clip.clip_keys, keys): if filter(lambda k: k not in models.Clip.clip_keys, keys):
qs = qs.select_related('item__sort') qs = qs.select_related('item__sort')
def add(p): clips = {}
ids.append(p.id) response['data']['items'] = clip_jsons = []
return p.json(keys=keys) for p in qs:
j = p.json(keys=keys)
clips[p.id] = j
clip_jsons.append(j)
response['data']['items'] = [add(p) for p in qs]
keys = data['keys'] keys = data['keys']
def clip_public_id(c):
return u'%s/%0.03f-%0.03f' % (c['public_id'].split('/')[0], c['clip__start'], c['clip__end'])
def add_annotations(key, qs, add_layer=False): def add_annotations(key, qs, add_layer=False):
values = ['public_id', 'value', 'clip__start', 'clip__end'] values = ['public_id', 'value', 'clip_id']
if subtitles or add_layer: if subtitles or add_layer:
values.append('layer') values.append('layer')
if query['filter']: if query['filter']:
@ -125,26 +123,25 @@ def findClips(request, data):
if not key in i: if not key in i:
i[key] = [] i[key] = []
for a in qs.values(*values): for a in qs.values(*values):
public_id = clip_public_id(a) i = clips[a['clip_id']]
for i in response['data']['items']: l = {
if i['id'] == public_id: 'id': a['public_id'],
l = { 'value': a['value'],
'id': a['public_id'], }
'value': a['value'], if subtitles and a['layer'] == subtitles['id'] and not a['value']:
} del l['id']
if subtitles and a['layer'] == subtitles['id'] and not a['value']: if add_layer:
del l['id'] l['layer'] = a['layer']
if add_layer: i[key].append(l)
l['layer'] = a['layer']
i[key].append(l)
if response['data']['items']: if response['data']['items']:
if 'annotations' in keys: if 'annotations' in keys:
aqs = Annotation.objects.filter(layer__in=settings.CONFIG['clipLayers'], aqs = Annotation.objects.filter(layer__in=settings.CONFIG['clipLayers'],
clip__in=ids) clip__in=clips)
add_annotations('annotations', aqs , True) add_annotations('annotations', aqs , True)
for layer in filter(lambda l: l in keys, layer_ids): for layer in filter(lambda l: l in keys, layer_ids):
aqs = Annotation.objects.filter(layer=layer, clip__in=ids) aqs = Annotation.objects.filter(layer=layer, clip__in=clips)
add_annotations(layer, aqs) add_annotations(layer, aqs)
elif 'position' in query: elif 'position' in query:
qs = order_query(qs, query['sort']) qs = order_query(qs, query['sort'])