Skip to content
This repository has been archived by the owner on Oct 15, 2021. It is now read-only.

Commit

Permalink
Merge pull request #33 from transifex/faster_recent_activity
Browse files Browse the repository at this point in the history
Speed up 'recent activity' by using a limit to the query responsible for fetching them.
  • Loading branch information
mpessas committed Apr 25, 2012
2 parents b5fcad5 + 836e3c8 commit b5ef9e5
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
26 changes: 16 additions & 10 deletions transifex/actionlog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ def _user_counting(query):
'number': entry['number']})
return result

def _distinct_action_time(query):
def _distinct_action_time(query, limit=None):
"""
Distinct rows by the 'action_time' field, keeping in the query only the
entry with the highest 'id' for the related set of entries with equal
'action_time'.
If 'limit' is set, the function will return the 'limit'-most-recent
actionlogs.
Example:
For the following query set:
Expand Down Expand Up @@ -89,22 +92,25 @@ def _distinct_action_time(query):
Rows with the same 'action_time' are eliminated, keeping the one with
highest 'id'.
"""
pks = query.values('action_time').annotate(
gid=models.Max('id')).order_by().values_list('gid', flat=True)
pks = query.values('action_time').annotate(gid=models.Max('id'))
if limit:
pks = pks.order_by('-id')[:limit]
else:
pks = pks.order_by()
pks = pks.values_list('gid', flat=True)
return LogEntry.objects.select_related('user').filter(pk__in=pks)


class LogEntryManager(models.Manager):
def by_object(self, obj):
def by_object(self, obj, limit):
"""Return LogEntries for a related object."""
ctype = ContentType.objects.get_for_model(obj)
q = self.filter(content_type__pk=ctype.pk, object_id=obj.pk)
return _distinct_action_time(q)
return _distinct_action_time(q, limit)

def by_user(self, user):
def by_user(self, user, limit):
"""Return LogEntries for a specific user."""
q = self.filter(user__pk__exact=user.pk)
return _distinct_action_time(q)
return _distinct_action_time(q, limit)

def by_object_last_week(self, obj):
"""Return LogEntries of the related object for the last week."""
Expand All @@ -113,7 +119,7 @@ def by_object_last_week(self, obj):
return self.filter(content_type__pk=ctype.pk, object_id=obj.pk,
action_time__gt=last_week_date)

def by_user_and_public_projects(self, user):
def by_user_and_public_projects(self, user, limit=None):
"""
Return LogEntries for a specific user and his actions on public projects.
"""
Expand All @@ -122,7 +128,7 @@ def by_user_and_public_projects(self, user):
ctype = ContentType.objects.get(model='project')
q = self.filter(user__pk__exact=user.pk, content_type=ctype,
object_id__in=Project.objects.filter(private=False))
return _distinct_action_time(q)
return _distinct_action_time(q, limit)

def for_projects_by_user(self, user):
"""Return project LogEntries for a related user."""
Expand Down
12 changes: 9 additions & 3 deletions transifex/actionlog/templatetags/tx_action_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,23 @@ def __repr__(self):
return "<GetLog Node>"

def render(self, context):
# XXX Should be fixed when ActionLog starts using Redis.
# XXX __init_ is executed only once (before template compilation).
# XXX NEEDS FIXING: get_public_log <limit>: limit is now useless.
self.limit = 5

if self.user is not None:
user = template.Variable(self.user).resolve(context)
if self.log_type and self.log_type == 'get_public_log':
query = LogEntry.objects.by_user_and_public_projects(user)
query = LogEntry.objects.by_user_and_public_projects(
user, self.limit)
else:
query = LogEntry.objects.by_user(user)
query = LogEntry.objects.by_user(user, self.limit)
elif self.object is not None:
obj = template.Variable(self.object).resolve(context)
query = LogEntry.objects.by_object(obj)

context[self.varname] = query[:self.limit]
context[self.varname] = query
return ''

class DoGetLog:
Expand Down

0 comments on commit b5ef9e5

Please sign in to comment.