[bitbake-devel] [PATCH 09/17] toastergui: tables display optimizations

Alex DAMIAN alexandru.damian at intel.com
Thu Mar 12 10:46:42 UTC 2015


From: Alexandru DAMIAN <alexandru.damian at intel.com>

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.

Signed-off-by: Alexandru DAMIAN <alexandru.damian at intel.com>
---
 lib/toaster/orm/models.py                     | 40 +++++++++++++++------------
 lib/toaster/toastergui/templates/targets.html |  2 +-
 lib/toaster/toastergui/views.py               | 14 +++++++---
 3 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/lib/toaster/orm/models.py b/lib/toaster/orm/models.py
index b941d4a..2132f87 100644
--- a/lib/toaster/orm/models.py
+++ b/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/lib/toaster/toastergui/templates/targets.html b/lib/toaster/toastergui/templates/targets.html
index 690c6a5..f918d6c 100644
--- a/lib/toaster/toastergui/templates/targets.html
+++ b/lib/toaster/toastergui/templates/targets.html
@@ -60,7 +60,7 @@
         <td class="description">{% if o.description %}{{o.description}}{% else %}{{o.summary}}{%endif%}</td>
         <td class="recipe-file">
                 <code>{{o.file_path}}</code>
-                <a href="{{o.get_vcs_link_url}}{{o.file_path}}" target="_blank"><i class="icon-share get-info"></i></a>
+                <a href="{{o.vcs_link_url}}" target="_blank"><i class="icon-share get-info"></i></a>
         </td>
         <td class="target-section">{{o.section}}</td>
         <td class="license">{{o.license}}</td>
diff --git a/lib/toaster/toastergui/views.py b/lib/toaster/toastergui/views.py
index 90d47c6..541b16a 100755
--- a/lib/toaster/toastergui/views.py
+++ b/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"))),
-- 
1.9.1




More information about the bitbake-devel mailing list