# HG changeset patch # User Sylvain Thénault # Date 1479487856 -3600 # Node ID 67185e65f020a9ba4f65282b26aa5fad94c6ae1b # Parent 0849a5eb57b85f22ea026f4b066f1fae9ec4c3ab [entity/optimization] Cache rset when entity.related is called with entities=False If fail to see why we couldn't cache in this case, while this is important for optimization reason: when doing a single HTTP request, some queries are done two or three times because of predicates / uicfg or alike. Also always store tuple and not list in the cache, because: * else we get some regression * and inconsistent result type (tuple or list) * and it simply feels better to cache an unmutable object. diff -r 0849a5eb57b8 -r 67185e65f020 cubicweb/entity.py --- a/cubicweb/entity.py Wed Nov 09 16:14:17 2016 +0100 +++ b/cubicweb/entity.py Fri Nov 18 17:50:56 2016 +0100 @@ -985,11 +985,10 @@ if not safe: raise rset = self._cw.empty_rset() + if cacheable: + self.cw_set_relation_cache(rtype, role, rset) if entities: - if cacheable: - self.cw_set_relation_cache(rtype, role, rset) - return self.related(rtype, role, entities=entities) - return list(rset.entities()) + return tuple(rset.entities()) else: return rset @@ -1251,7 +1250,7 @@ def cw_set_relation_cache(self, rtype, role, rset): """set cached values for the given relation""" if rset: - related = list(rset.entities(0)) + related = tuple(rset.entities(0)) rschema = self._cw.vreg.schema.rschema(rtype) if role == 'subject': rcard = rschema.rdef(self.e_schema, related[0].e_schema).cardinality[1] diff -r 0849a5eb57b8 -r 67185e65f020 cubicweb/test/unittest_entity.py --- a/cubicweb/test/unittest_entity.py Wed Nov 09 16:14:17 2016 +0100 +++ b/cubicweb/test/unittest_entity.py Fri Nov 18 17:50:56 2016 +0100 @@ -182,10 +182,15 @@ req.create_entity('Tag', name=tag) req.execute('SET X tags Y WHERE X is Tag, Y is Personne') self.assertEqual(len(p.related('tags', 'object', limit=2)), 2) + self.assertFalse(p.cw_relation_cached('tags', 'object')) self.assertEqual(len(p.related('tags', 'object')), 4) + self.assertTrue(p.cw_relation_cached('tags', 'object')) p.cw_clear_all_caches() + self.assertFalse(p.cw_relation_cached('tags', 'object')) self.assertEqual(len(p.related('tags', 'object', entities=True, limit=2)), 2) + self.assertFalse(p.cw_relation_cached('tags', 'object')) self.assertEqual(len(p.related('tags', 'object', entities=True)), 4) + self.assertTrue(p.cw_relation_cached('tags', 'object')) def test_related_targettypes(self): with self.admin_access.web_request() as req: diff -r 0849a5eb57b8 -r 67185e65f020 cubicweb/web/test/unittest_application.py --- a/cubicweb/web/test/unittest_application.py Wed Nov 09 16:14:17 2016 +0100 +++ b/cubicweb/web/test/unittest_application.py Fri Nov 18 17:50:56 2016 +0100 @@ -503,7 +503,7 @@ self.assertTrue(cnx.find('Directory', eid=subd.eid)) self.assertTrue(cnx.find('Filesystem', eid=fs.eid)) self.assertEqual(cnx.find('Directory', eid=subd.eid).one().parent, - [topd,]) + (topd,)) def test_subject_mixed_composite_subentity_removal_2(self): """Editcontroller: detaching several subentities respects each rdef's @@ -542,7 +542,7 @@ self.assertTrue(cnx.find('Directory', eid=subd.eid)) self.assertTrue(cnx.find('Filesystem', eid=fs.eid)) self.assertEqual(cnx.find('Directory', eid=subd.eid).one().parent, - [topd,]) + (topd,)) def test_object_mixed_composite_subentity_removal_2(self): """Editcontroller: detaching several subentities respects each rdef's