Merge lp:~wgrant/launchpad/die-spr-spn into lp:launchpad

Proposed by William Grant on 2012-05-14
Status: Merged
Approved by: William Grant on 2012-05-14
Approved revision: no longer in the source branch.
Merged at revision: 15242
Proposed branch: lp:~wgrant/launchpad/die-spr-spn
Merge into: lp:launchpad
Diff against target: 469 lines (+78/-118)
10 files modified
lib/lp/registry/model/distribution.py (+2/-3)
lib/lp/registry/model/distributionsourcepackage.py (+9/-12)
lib/lp/registry/model/distroseries.py (+23/-47)
lib/lp/registry/model/sourcepackage.py (+17/-16)
lib/lp/soyuz/adapters/overrides.py (+5/-7)
lib/lp/soyuz/model/archive.py (+4/-5)
lib/lp/soyuz/model/distributionsourcepackagecache.py (+5/-11)
lib/lp/soyuz/model/distroseriesdifferencejob.py (+7/-12)
lib/lp/soyuz/tests/test_hasbuildrecords.py (+5/-0)
lib/lp/translations/model/vpoexport.py (+1/-5)
To merge this branch: bzr merge lp:~wgrant/launchpad/die-spr-spn
Reviewer Review Type Date Requested Status
Steve Kowalik (community) code 2012-05-14 Approve on 2012-05-14
Review via email: mp+105597@code.launchpad.net

Commit Message

Port lots of queries to SourcePackagePublishingHistory.sourcepackagename for speed.

Description of the Change

This branch enables more widespread use of the relatively new denormalised SourcePackagePublishingHistory.sourcepackagename column. Many queries want to find a SourcePackagePublishingHistory for a particular name in a given archive and distroseries -- this column and its indices let that be satisfied very quickly, rather than having to slowly join 25000 rows through SourcePackageRelease.

I grepped for SourcePackageRelease.sourcepackagename and replaced it with SPPH.spn in queries that primarily filter based on SPPH. In many cases the SPR join goes away entirely; in others it just becomes a secondary filter or sort. A few cases were left untouched because it wasn't an obvious substantial improvement; they'll need case-by-case analysis later.

To post a comment you must log in.
Steve Kowalik (stevenk) wrote :

This looks excellent.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/model/distribution.py'
2--- lib/lp/registry/model/distribution.py 2012-05-01 10:20:07 +0000
3+++ lib/lp/registry/model/distribution.py 2012-05-14 05:23:21 +0000
4@@ -1249,9 +1249,8 @@
5 # timeouts).
6 SourcePackagePublishingHistory.archiveID.is_in(
7 self.all_distro_archive_ids),
8- SourcePackagePublishingHistory.sourcepackagereleaseID ==
9- SourcePackageRelease.id,
10- SourcePackageRelease.sourcepackagename == sourcepackagename,
11+ SourcePackagePublishingHistory.sourcepackagename ==
12+ sourcepackagename,
13 SourcePackagePublishingHistory.status.is_in(
14 (PackagePublishingStatus.PUBLISHED,
15 PackagePublishingStatus.PENDING)
16
17=== modified file 'lib/lp/registry/model/distributionsourcepackage.py'
18--- lib/lp/registry/model/distributionsourcepackage.py 2012-02-08 06:00:46 +0000
19+++ lib/lp/registry/model/distributionsourcepackage.py 2012-05-14 05:23:21 +0000
20@@ -105,9 +105,7 @@
21 SourcePackagePublishingHistory.distroseriesID ==
22 DistroSeries.id,
23 DistroSeries.distributionID == obj.distribution.id,
24- SourcePackagePublishingHistory.sourcepackagereleaseID ==
25- SourcePackageRelease.id,
26- SourcePackageRelease.sourcepackagenameID ==
27+ SourcePackagePublishingHistory.sourcepackagenameID ==
28 obj.sourcepackagename.id).order_by(
29 Desc(SourcePackagePublishingHistory.id)).first()
30 obj._new(obj.distribution, obj.sourcepackagename,
31@@ -233,9 +231,7 @@
32 spph = SourcePackagePublishingHistory.selectFirst("""
33 SourcePackagePublishingHistory.distroseries = DistroSeries.id AND
34 DistroSeries.distribution = %s AND
35- SourcePackagePublishingHistory.sourcepackagerelease =
36- SourcePackageRelease.id AND
37- SourcePackageRelease.sourcepackagename = %s AND
38+ SourcePackagePublishingHistory.sourcepackagename = %s AND
39 SourcePackagePublishingHistory.archive IN %s AND
40 pocket NOT IN (%s, %s) AND
41 status in (%s, %s)""" %
42@@ -401,9 +397,9 @@
43 SourcePackagePublishingHistory.archive IN %s AND
44 SourcePackagePublishingHistory.distroseries =
45 DistroSeries.id AND
46- SourcePackagePublishingHistory.sourcepackagerelease =
47- SourcePackageRelease.id AND
48- SourcePackageRelease.sourcepackagename = %s
49+ SourcePackagePublishingHistory.sourcepackagename = %s AND
50+ SourcePackageRelease.id =
51+ SourcePackagePublishingHistory.sourcepackagerelease
52 """ % sqlvalues(self.distribution,
53 self.distribution.all_distro_archive_ids,
54 self.sourcepackagename)
55@@ -426,9 +422,10 @@
56 DistroSeries.distribution == self.distribution,
57 SourcePackagePublishingHistory.archiveID.is_in(
58 self.distribution.all_distro_archive_ids),
59- SourcePackagePublishingHistory.sourcepackagerelease ==
60- SourcePackageRelease.id,
61- SourcePackageRelease.sourcepackagename == self.sourcepackagename)
62+ SourcePackagePublishingHistory.sourcepackagename ==
63+ self.sourcepackagename,
64+ SourcePackageRelease.id ==
65+ SourcePackagePublishingHistory.sourcepackagereleaseID)
66 result.order_by(
67 Desc(SourcePackageRelease.id),
68 Desc(SourcePackagePublishingHistory.datecreated),
69
70=== modified file 'lib/lp/registry/model/distroseries.py'
71--- lib/lp/registry/model/distroseries.py 2012-04-05 14:39:45 +0000
72+++ lib/lp/registry/model/distroseries.py 2012-05-14 05:23:21 +0000
73@@ -738,49 +738,27 @@
74
75 def updatePackageCount(self):
76 """See `IDistroSeries`."""
77-
78- # first update the source package count
79- query = """
80- SourcePackagePublishingHistory.distroseries = %s AND
81- SourcePackagePublishingHistory.archive IN %s AND
82- SourcePackagePublishingHistory.status IN %s AND
83- SourcePackagePublishingHistory.pocket = %s AND
84- SourcePackagePublishingHistory.sourcepackagerelease =
85- SourcePackageRelease.id AND
86- SourcePackageRelease.sourcepackagename =
87- SourcePackageName.id
88- """ % sqlvalues(
89- self,
90- self.distribution.all_distro_archive_ids,
91- active_publishing_status,
92- PackagePublishingPocket.RELEASE)
93- self.sourcecount = SourcePackageName.select(
94- query, distinct=True,
95- clauseTables=['SourcePackageRelease',
96- 'SourcePackagePublishingHistory']).count()
97-
98- # next update the binary count
99- clauseTables = ['DistroArchSeries', 'BinaryPackagePublishingHistory',
100- 'BinaryPackageRelease']
101- query = """
102- BinaryPackagePublishingHistory.binarypackagerelease =
103- BinaryPackageRelease.id AND
104- BinaryPackageRelease.binarypackagename =
105- BinaryPackageName.id AND
106- BinaryPackagePublishingHistory.status IN %s AND
107- BinaryPackagePublishingHistory.pocket = %s AND
108- BinaryPackagePublishingHistory.distroarchseries =
109- DistroArchSeries.id AND
110- DistroArchSeries.distroseries = %s AND
111- BinaryPackagePublishingHistory.archive IN %s
112- """ % sqlvalues(
113- active_publishing_status,
114- PackagePublishingPocket.RELEASE,
115- self,
116- self.distribution.all_distro_archive_ids)
117- ret = BinaryPackageName.select(
118- query, distinct=True, clauseTables=clauseTables).count()
119- self.binarycount = ret
120+ self.sourcecount = IStore(SourcePackagePublishingHistory).find(
121+ SourcePackagePublishingHistory.sourcepackagenameID,
122+ SourcePackagePublishingHistory.distroseries == self,
123+ SourcePackagePublishingHistory.archiveID.is_in(
124+ self.distribution.all_distro_archive_ids),
125+ SourcePackagePublishingHistory.status.is_in(
126+ active_publishing_status),
127+ SourcePackagePublishingHistory.pocket ==
128+ PackagePublishingPocket.RELEASE).config(distinct=True).count()
129+
130+ self.binarycount = IStore(BinaryPackagePublishingHistory).find(
131+ BinaryPackagePublishingHistory.binarypackagenameID,
132+ DistroArchSeries.distroseries == self,
133+ BinaryPackagePublishingHistory.distroarchseriesID ==
134+ DistroArchSeries.id,
135+ BinaryPackagePublishingHistory.archiveID.is_in(
136+ self.distribution.all_distro_archive_ids),
137+ BinaryPackagePublishingHistory.status.is_in(
138+ active_publishing_status),
139+ BinaryPackagePublishingHistory.pocket ==
140+ PackagePublishingPocket.RELEASE).config(distinct=True).count()
141
142 @property
143 def architecturecount(self):
144@@ -1201,9 +1179,7 @@
145 archives = self.distribution.getArchiveIDList(archive)
146
147 clause = """
148- SourcePackagePublishingHistory.sourcepackagerelease=
149- SourcePackageRelease.id AND
150- SourcePackageRelease.sourcepackagename=
151+ SourcePackagePublishingHistory.sourcepackagename=
152 SourcePackageName.id AND
153 SourcePackagePublishingHistory.distroseries=%s AND
154 SourcePackagePublishingHistory.archive IN %s AND
155@@ -1217,7 +1193,7 @@
156 % sqlvalues(component))
157
158 orderBy = ['SourcePackageName.name']
159- clauseTables = ['SourcePackageRelease', 'SourcePackageName']
160+ clauseTables = ['SourcePackageName']
161
162 return SourcePackagePublishingHistory.select(
163 clause, orderBy=orderBy, clauseTables=clauseTables)
164
165=== modified file 'lib/lp/registry/model/sourcepackage.py'
166--- lib/lp/registry/model/sourcepackage.py 2012-02-07 07:37:27 +0000
167+++ lib/lp/registry/model/sourcepackage.py 2012-05-14 05:23:21 +0000
168@@ -17,7 +17,7 @@
169 from storm.locals import (
170 And,
171 Desc,
172- Select,
173+ Join,
174 Store,
175 )
176 from zope.component import getUtility
177@@ -245,7 +245,7 @@
178 clauses.append(
179 """SourcePackagePublishingHistory.sourcepackagerelease =
180 SourcePackageRelease.id AND
181- SourcePackageRelease.sourcepackagename = %s AND
182+ SourcePackagePublishingHistory.sourcepackagename = %s AND
183 SourcePackagePublishingHistory.distroseries = %s AND
184 SourcePackagePublishingHistory.archive IN %s
185 """ % sqlvalues(
186@@ -380,21 +380,22 @@
187
188 The results are ordered by descending version.
189 """
190- subselect = Select(
191- SourcePackageRelease.id, And(
192+ return IStore(SourcePackageRelease).using(
193+ SourcePackageRelease,
194+ Join(
195+ SourcePackagePublishingHistory,
196+ SourcePackagePublishingHistory.sourcepackagereleaseID ==
197+ SourcePackageRelease.id)
198+ ).find(
199+ SourcePackageRelease,
200+ SourcePackagePublishingHistory.archiveID.is_in(
201+ self.distribution.all_distro_archive_ids),
202 SourcePackagePublishingHistory.distroseries ==
203 self.distroseries,
204- SourcePackagePublishingHistory.sourcepackagereleaseID ==
205- SourcePackageRelease.id,
206- SourcePackageRelease.sourcepackagename ==
207- self.sourcepackagename,
208- SourcePackagePublishingHistory.archiveID.is_in(
209- self.distribution.all_distro_archive_ids)))
210-
211- return IStore(SourcePackageRelease).find(
212- SourcePackageRelease,
213- SourcePackageRelease.id.is_in(subselect)).order_by(Desc(
214- SourcePackageRelease.version))
215+ SourcePackagePublishingHistory.sourcepackagename ==
216+ self.sourcepackagename
217+ ).config(distinct=True).order_by(
218+ Desc(SourcePackageRelease.version))
219
220 @property
221 def name(self):
222@@ -644,7 +645,7 @@
223 condition_clauses = ["""
224 BinaryPackageBuild.source_package_release =
225 SourcePackageRelease.id AND
226- SourcePackageRelease.sourcepackagename = %s AND
227+ SourcePackagePublishingHistory.sourcepackagename = %s AND
228 SourcePackagePublishingHistory.distroseries = %s AND
229 SourcePackagePublishingHistory.archive IN %s AND
230 SourcePackagePublishingHistory.sourcepackagerelease =
231
232=== modified file 'lib/lp/soyuz/adapters/overrides.py'
233--- lib/lp/soyuz/adapters/overrides.py 2012-01-06 11:08:30 +0000
234+++ lib/lp/soyuz/adapters/overrides.py 2012-05-14 05:23:21 +0000
235@@ -191,7 +191,6 @@
236 def calculateSourceOverrides(self, archive, distroseries, pocket, spns,
237 source_component=None):
238 # Avoid circular imports.
239- from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
240 from lp.soyuz.model.publishing import SourcePackagePublishingHistory
241
242 def eager_load(rows):
243@@ -201,7 +200,7 @@
244 store = IStore(SourcePackagePublishingHistory)
245 already_published = DecoratedResultSet(
246 store.find(
247- (SourcePackageRelease.sourcepackagenameID,
248+ (SourcePackagePublishingHistory.sourcepackagenameID,
249 SourcePackagePublishingHistory.componentID,
250 SourcePackagePublishingHistory.sectionID),
251 SourcePackagePublishingHistory.archiveID == archive.id,
252@@ -209,15 +208,14 @@
253 distroseries.id,
254 SourcePackagePublishingHistory.status.is_in(
255 active_publishing_status),
256- SourcePackageRelease.id ==
257- SourcePackagePublishingHistory.sourcepackagereleaseID,
258- SourcePackageRelease.sourcepackagenameID.is_in(
259+ SourcePackagePublishingHistory.sourcepackagenameID.is_in(
260 spn.id for spn in spns)).order_by(
261- SourcePackageRelease.sourcepackagenameID,
262+ SourcePackagePublishingHistory.sourcepackagenameID,
263 Desc(SourcePackagePublishingHistory.datecreated),
264 Desc(SourcePackagePublishingHistory.id),
265 ).config(
266- distinct=(SourcePackageRelease.sourcepackagenameID,)),
267+ distinct=(
268+ SourcePackagePublishingHistory.sourcepackagenameID,)),
269 id_resolver((SourcePackageName, Component, Section)),
270 pre_iter_hook=eager_load)
271 return [
272
273=== modified file 'lib/lp/soyuz/model/archive.py'
274--- lib/lp/soyuz/model/archive.py 2012-05-04 12:02:44 +0000
275+++ lib/lp/soyuz/model/archive.py 2012-05-14 05:23:21 +0000
276@@ -514,7 +514,7 @@
277 SourcePackagePublishingHistory.archiveID == self.id,
278 SourcePackagePublishingHistory.sourcepackagereleaseID ==
279 SourcePackageRelease.id,
280- SourcePackageRelease.sourcepackagenameID ==
281+ SourcePackagePublishingHistory.sourcepackagenameID ==
282 SourcePackageName.id,
283 ]
284 orderBy = [
285@@ -624,7 +624,7 @@
286 SourcePackagePublishingHistory.archive = %s AND
287 SourcePackagePublishingHistory.sourcepackagerelease =
288 SourcePackageRelease.id AND
289- SourcePackageRelease.sourcepackagename =
290+ SourcePackagePublishingHistory.sourcepackagename =
291 SourcePackageName.id
292 """ % sqlvalues(self)]
293
294@@ -2493,9 +2493,8 @@
295 SourcePackagePublishingHistory.archive == Archive.id,
296 (SourcePackagePublishingHistory.status ==
297 PackagePublishingStatus.PUBLISHED),
298- (SourcePackagePublishingHistory.sourcepackagerelease ==
299- SourcePackageRelease.id),
300- SourcePackageRelease.sourcepackagename == source_package_name,
301+ SourcePackagePublishingHistory.sourcepackagename ==
302+ source_package_name,
303 SourcePackagePublishingHistory.distroseries == DistroSeries.id,
304 DistroSeries.distribution == distribution,
305 )
306
307=== modified file 'lib/lp/soyuz/model/distributionsourcepackagecache.py'
308--- lib/lp/soyuz/model/distributionsourcepackagecache.py 2011-12-30 06:14:56 +0000
309+++ lib/lp/soyuz/model/distributionsourcepackagecache.py 2012-05-14 05:23:21 +0000
310@@ -95,9 +95,7 @@
311 DistroSeries.distribution = %s AND
312 Archive.id = %s AND
313 SourcePackagePublishingHistory.archive = Archive.id AND
314- SourcePackagePublishingHistory.sourcepackagerelease =
315- SourcePackageRelease.id AND
316- SourcePackageRelease.sourcepackagename =
317+ SourcePackagePublishingHistory.sourcepackagename =
318 SourcePackageName.id AND
319 SourcePackagePublishingHistory.dateremoved is NULL AND
320 Archive.enabled = TRUE
321@@ -106,8 +104,7 @@
322 clauseTables=[
323 'Archive',
324 'DistroSeries',
325- 'SourcePackagePublishingHistory',
326- 'SourcePackageRelease']))
327+ 'SourcePackagePublishingHistory']))
328
329 # Remove the cache entries for packages we no longer publish.
330 for cache in cls._find(distro, archive):
331@@ -128,9 +125,9 @@
332
333 # Get the set of published sourcepackage releases.
334 sprs = list(SourcePackageRelease.select("""
335- SourcePackageRelease.sourcepackagename = %s AND
336 SourcePackageRelease.id =
337 SourcePackagePublishingHistory.sourcepackagerelease AND
338+ SourcePackagePublishingHistory.sourcepackagename = %s AND
339 SourcePackagePublishingHistory.distroseries =
340 DistroSeries.id AND
341 DistroSeries.distribution = %s AND
342@@ -219,16 +216,13 @@
343 DistroSeries.id AND
344 DistroSeries.distribution = %s AND
345 SourcePackagePublishingHistory.archive = %s AND
346- SourcePackagePublishingHistory.sourcepackagerelease =
347- SourcePackageRelease.id AND
348- SourcePackageRelease.sourcepackagename =
349+ SourcePackagePublishingHistory.sourcepackagename =
350 SourcePackageName.id AND
351 SourcePackagePublishingHistory.dateremoved is NULL
352 """ % sqlvalues(distro, archive),
353 distinct=True,
354 orderBy="name",
355- clauseTables=['SourcePackagePublishingHistory', 'DistroSeries',
356- 'SourcePackageRelease']))
357+ clauseTables=['SourcePackagePublishingHistory', 'DistroSeries']))
358
359 number_of_updates = 0
360 chunk_size = 0
361
362=== modified file 'lib/lp/soyuz/model/distroseriesdifferencejob.py'
363--- lib/lp/soyuz/model/distroseriesdifferencejob.py 2012-04-13 20:58:40 +0000
364+++ lib/lp/soyuz/model/distroseriesdifferencejob.py 2012-05-14 05:23:21 +0000
365@@ -41,7 +41,6 @@
366 DistributionJobDerived,
367 )
368 from lp.soyuz.model.publishing import SourcePackagePublishingHistory
369-from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
370
371
372 FEATURE_FLAG_ENABLE_MODULE = u"soyuz.derived_series_jobs.enabled"
373@@ -85,21 +84,17 @@
374 `derived_series`.
375 :return: A list of newly-created `DistributionJob` ids.
376 """
377- store = IStore(SourcePackageRelease)
378- source_package_releases = store.find(
379- SourcePackageRelease,
380- SourcePackagePublishingHistory.sourcepackagerelease ==
381- SourcePackageRelease.id,
382+ store = IStore(SourcePackagePublishingHistory)
383+ spn_ids = store.find(
384+ SourcePackagePublishingHistory.sourcepackagenameID,
385 SourcePackagePublishingHistory.distroseries == derived_series.id,
386 SourcePackagePublishingHistory.status.is_in(active_publishing_status))
387- nb_jobs = source_package_releases.count()
388+ spn_ids = list(spn_ids)
389
390- if nb_jobs == 0:
391+ if len(spn_ids) == 0:
392 return []
393
394- sourcepackagenames = source_package_releases.values(
395- SourcePackageRelease.sourcepackagenameID)
396- job_ids = Job.createMultiple(store, nb_jobs)
397+ job_ids = Job.createMultiple(store, len(spn_ids))
398 return bulk.create(
399 (DistributionJob.distribution, DistributionJob.distroseries,
400 DistributionJob.job_type, DistributionJob.job_id,
401@@ -107,7 +102,7 @@
402 [(derived_series.distribution, derived_series,
403 DistributionJobType.DISTROSERIESDIFFERENCE, job_id,
404 make_metadata(spn_id, parent_series.id))
405- for job_id, spn_id in zip(job_ids, sourcepackagenames)],
406+ for job_id, spn_id in zip(job_ids, spn_ids)],
407 get_primary_keys=True)
408
409
410
411=== modified file 'lib/lp/soyuz/tests/test_hasbuildrecords.py'
412--- lib/lp/soyuz/tests/test_hasbuildrecords.py 2012-04-16 23:02:44 +0000
413+++ lib/lp/soyuz/tests/test_hasbuildrecords.py 2012-05-14 05:23:21 +0000
414@@ -22,6 +22,7 @@
415 from lp.registry.interfaces.person import IPersonSet
416 from lp.registry.interfaces.pocket import PackagePublishingPocket
417 from lp.registry.model.sourcepackage import SourcePackage
418+from lp.services.database.lpstorm import IStore
419 from lp.soyuz.enums import ArchivePurpose
420 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuild
421 from lp.soyuz.interfaces.buildrecords import (
422@@ -29,6 +30,7 @@
423 IncompatibleArguments,
424 )
425 from lp.soyuz.model.processor import ProcessorFamilySet
426+from lp.soyuz.model.publishing import SourcePackagePublishingHistory
427 from lp.soyuz.tests.test_binarypackagebuild import BaseTestCaseWithThreeBuilds
428 from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
429 from lp.testing import (
430@@ -281,6 +283,9 @@
431 for build in self.builds[1:3]:
432 spr = build.source_package_release
433 removeSecurityProxy(spr).sourcepackagename = gedit_name
434+ IStore(SourcePackagePublishingHistory).find(
435+ SourcePackagePublishingHistory, sourcepackagerelease=spr
436+ ).set(sourcepackagenameID=gedit_name.id)
437
438 # Set them as sucessfully built
439 for build in self.builds:
440
441=== modified file 'lib/lp/translations/model/vpoexport.py'
442--- lib/lp/translations/model/vpoexport.py 2011-12-24 17:49:30 +0000
443+++ lib/lp/translations/model/vpoexport.py 2012-05-14 05:23:21 +0000
444@@ -26,7 +26,6 @@
445 )
446 from lp.soyuz.model.component import Component
447 from lp.soyuz.model.publishing import SourcePackagePublishingHistory
448-from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
449 from lp.translations.interfaces.vpoexport import (
450 IVPOExport,
451 IVPOExportSet,
452@@ -66,16 +65,13 @@
453 if component is not None:
454 tables.extend([
455 SourcePackagePublishingHistory,
456- SourcePackageRelease,
457 Component,
458 ])
459 conditions.extend([
460 SourcePackagePublishingHistory.distroseries == series,
461- SourcePackagePublishingHistory.sourcepackagerelease ==
462- SourcePackageRelease.id,
463 SourcePackagePublishingHistory.component == Component.id,
464 POTemplate.sourcepackagename ==
465- SourcePackageRelease.sourcepackagenameID,
466+ SourcePackagePublishingHistory.sourcepackagenameID,
467 Component.name == component,
468 SourcePackagePublishingHistory.dateremoved == None,
469 SourcePackagePublishingHistory.archive == series.main_archive,