From 193989cec807120307cda50c616118dca4025b8a Mon Sep 17 00:00:00 2001 From: Alexandru DAMIAN Date: Tue, 10 Mar 2015 17:38:00 +0000 Subject: bitbake: toastergui: tables display optimizations This patch brings in a new set of optimizations in the tables pages, with the focus of reducing the number of SQL queries performed per row. (Bitbake rev: a1ad86febb9d8a4ee7f15aa726f267d64b8e0dc4) Signed-off-by: Alexandru DAMIAN Signed-off-by: Richard Purdie --- bitbake/lib/toaster/orm/models.py | 40 ++++++++++++---------- .../lib/toaster/toastergui/templates/targets.html | 2 +- bitbake/lib/toaster/toastergui/views.py | 14 +++++--- 3 files changed, 33 insertions(+), 23 deletions(-) (limited to 'bitbake') diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py index b941d4ab20..2132f8799c 100644 --- a/bitbake/lib/toaster/orm/models.py +++ b/bitbake/lib/toaster/orm/models.py @@ -182,7 +182,7 @@ class Project(models.Model): # returns a set of layer-equivalent set of layers already in project def projectlayer_equivalent_set(self): - return [j for i in [x.layercommit.get_equivalents_wpriority(self) for x in self.projectlayer_set.all()] for j in i] + return [j for i in [x.layercommit.get_equivalents_wpriority(self) for x in self.projectlayer_set.all().select_related("up_branch")] for j in i] def schedule_build(self): from bldcontrol.models import BuildRequest, BRTarget, BRLayer, BRVariable, BRBitbake @@ -545,11 +545,6 @@ class Recipe(models.Model): bugtracker = models.URLField(blank=True) file_path = models.FilePathField(max_length=255) - def get_vcs_link_url(self): - if self.layer_version.layer.vcs_web_file_base_url is None: - return "" - return self.layer_version.layer.vcs_web_file_base_url.replace('%path%', self.file_path).replace('%branch%', self.layer_version.up_branch.name) - def get_layersource_view_url(self): if self.layer_source is None: return "" @@ -708,8 +703,6 @@ class LayerIndexLayerSource(LayerSource): self.sourcetype = LayerSource.TYPE_LAYERINDEX def get_object_view(self, branch, objectype, upid): - if self != branch.layer_source: - raise Exception("Invalid branch specification") return self.apiurl + "../branch/" + branch.name + "/" + objectype + "/?q=" + str(upid) def update(self): @@ -1044,14 +1037,6 @@ class Layer_Version(models.Model): def get_equivalents_wpriority(self, project): """ Returns an ordered layerversion list that satisfies a LayerVersionDependency using the layer name and the current Project Releases' LayerSource priority """ - def _get_ls_priority(ls): - try: - # if there is no layer source, we have minus infinite priority, as we don't want this layer selected - if ls == None: - return -10000 - return ls.releaselayersourcepriority_set.get(release=project.release).priority - except ReleaseLayerSourcePriority.DoesNotExist: - raise # layers created for this project, or coming from a build inthe project query = Q(project = project) | Q(build__project = project) @@ -1062,8 +1047,27 @@ class Layer_Version(models.Model): # or we have a layer in the project that's similar to mine (See the layer.name constraint below) query |= Q(projectlayer__project=project) - return sorted( - Layer_Version.objects.filter(layer__name = self.layer.name).filter(query).select_related('layer_source', 'layer').order_by("-id"), + candidate_layer_versions = list(Layer_Version.objects.filter(layer__name = self.layer.name).filter(query).select_related('layer_source', 'layer', 'up_branch').order_by("-id")) + + # optimization - if we have only one, we don't need no stinking sort + if len(candidate_layer_versions) == 1: + return candidate_layer_versions + +# raise Exception(candidate_layer_versions) + + release_priorities = map(lambda x: (x.layer_source_id, x.priority), project.release.releaselayersourcepriority_set.all().order_by("-priority")) + + + def _get_ls_priority(ls): + # if there is no layer source, we have minus infinite priority, as we don't want this layer selected + if ls == None: + return -10000 + try: + return release_priorities[ls.id] + except IndexError: + raise Exception("Unknown %d %s" % (ls.id, release_priorities)) + + return sorted( candidate_layer_versions , key = lambda x: _get_ls_priority(x.layer_source), reverse = True) diff --git a/bitbake/lib/toaster/toastergui/templates/targets.html b/bitbake/lib/toaster/toastergui/templates/targets.html index 690c6a5d36..f918d6cff2 100644 --- a/bitbake/lib/toaster/toastergui/templates/targets.html +++ b/bitbake/lib/toaster/toastergui/templates/targets.html @@ -60,7 +60,7 @@ {% if o.description %}{{o.description}}{% else %}{{o.summary}}{%endif%} {{o.file_path}} - + {{o.section}} {{o.license}} diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py index 90d47c640c..541b16ab1d 100755 --- a/bitbake/lib/toaster/toastergui/views.py +++ b/bitbake/lib/toaster/toastergui/views.py @@ -515,17 +515,19 @@ def target_common( request, build_id, target_id, variant ): packages_sum = queryset.aggregate( Sum( 'installed_size' )) queryset = _get_queryset( Package, queryset, filter_string, search_term, ordering_string, 'name' ) + queryset = queryset.select_related("recipe", "recipe__layer_version", "recipe__layer_version__layer") packages = _build_page_range( Paginator(queryset, pagesize), request.GET.get( 'page', 1 )) + build = Build.objects.get( pk = build_id ) # bring in package dependencies for p in packages.object_list: p.runtime_dependencies = p.package_dependencies_source.filter( - target_id = target_id, dep_type=Package_Dependency.TYPE_TRDEPENDS ) + target_id = target_id, dep_type=Package_Dependency.TYPE_TRDEPENDS ).select_related("depends_on") p.reverse_runtime_dependencies = p.package_dependencies_target.filter( - target_id = target_id, dep_type=Package_Dependency.TYPE_TRDEPENDS ) + target_id = target_id, dep_type=Package_Dependency.TYPE_TRDEPENDS ).select_related("package") tc_package = { 'name' : 'Package', 'qhelp' : 'Packaged output resulting from building a recipe included in this image', @@ -2755,7 +2757,7 @@ if toastermain.settings.MANAGED: # get unique values for 'name', and select the maximum ID for each entry (the max id is the newest one) queryset_with_search_maxids = queryset_with_search.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id') - queryset_with_search = queryset_with_search.filter(id__in=queryset_with_search_maxids).select_related('layer_version', 'layer_version__layer', 'layer_version__up_branch') + queryset_with_search = queryset_with_search.filter(id__in=queryset_with_search_maxids).select_related('layer_version', 'layer_version__layer', 'layer_version__up_branch', 'layer_source') # retrieve the objects that will be displayed in the table; targets a paginator and gets a page range to display @@ -2763,7 +2765,11 @@ if toastermain.settings.MANAGED: for e in target_info.object_list: e.preffered_layerversion = e.layer_version.get_equivalents_wpriority(prj)[0] - + e.vcs_link_url = Layer.objects.filter(name = e.preffered_layerversion.layer.name).exclude(vcs_web_file_base_url__isnull=True)[0].vcs_web_file_base_url + if e.vcs_link_url != None: + fp = e.preffered_layerversion.dirpath + "/" + e.file_path + e.vcs_link_url = e.vcs_link_url.replace('%path%', fp) + e.vcs_link_url = e.vcs_link_url.replace('%branch%', e.preffered_layerversion.up_branch.name) context = { 'projectlayerset' : jsonfilter(map(lambda x: x.layercommit.id, prj.projectlayer_set.all().select_related("layercommit"))), -- cgit v1.2.3-54-g00ecf