From bf7986421192be9018c662e016fabb02d2dad0da Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Thu, 20 Jun 2019 16:16:02 -0400 Subject: Speed up Booking Stats Refactors the bookings stats function to use the database less. Runs in around 1/3 the time as the current version Change-Id: I4f367b96374511d2f669d4554919a65912f304f8 Signed-off-by: Parker Berberian --- dashboard/src/booking/stats.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/dashboard/src/booking/stats.py b/dashboard/src/booking/stats.py index b706577..62ba648 100644 --- a/dashboard/src/booking/stats.py +++ b/dashboard/src/booking/stats.py @@ -25,7 +25,7 @@ class StatisticsManager(object): some point in the given date span is the number of days to plot. The last x value will always be the current time """ - x_set = set() + data = [] x = [] y = [] users = [] @@ -33,26 +33,26 @@ class StatisticsManager(object): delta = datetime.timedelta(days=span) end = now - delta bookings = Booking.objects.filter(start__lte=now, end__gte=end) - for booking in bookings: - x_set.add(booking.start) - if booking.end < now: - x_set.add(booking.end) + for booking in bookings: # collect data from each booking + user_list = [u.pk for u in booking.collaborators.all()] + user_list.append(booking.owner.pk) + data.append((booking.start, 1, user_list)) + data.append((booking.end, -1, user_list)) - x_set.add(now) - x_set.add(end) + # sort based on time + data.sort(key=lambda i: i[0]) - x_list = list(x_set) - x_list.sort(reverse=True) - for time in x_list: - x.append(str(time)) - active = Booking.objects.filter(start__lte=time, end__gt=time) - booking_count = len(active) - users_set = set() - for booking in active: - users_set.add(booking.owner) - for user in booking.collaborators.all(): - users_set.add(user) - y.append(booking_count) - users.append(len(users_set)) + # collect data + count = 0 + active_users = {} + for datum in data: + x.append(str(datum[0])) # time + count += datum[1] # booking count + y.append(count) + for pk in datum[2]: # maintain count of each user's active bookings + active_users[pk] = active_users.setdefault(pk, 0) + datum[1] + if active_users[pk] == 0: + del active_users[pk] + users.append(len([x for x in active_users.values() if x > 0])) return {"booking": [x, y], "user": [x, users]} -- cgit 1.2.3-korg