[BUGFIX] Container calls Cache too often
authorDaniel Pötzinger <poetzinger@aoemedia.de>
Fri, 13 Apr 2012 19:13:04 +0000 (21:13 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sat, 21 Jul 2012 12:56:14 +0000 (14:56 +0200)
The Container Classes Cache call is very expensive - and when
using a database backend, this is even slowing down
compared to a NullBackend.

One reason is that for every cache request the cache is
called 3 times: 1 time has and 2 times get.
This can be avoided and be reduced to one get call -
which reduces request time by 10-20% for a bigger Extbase request.

Change-Id: I43a0ebf7e0bfd067f3e48c0e7c27f12660b4cb7c
Resolves: #36008
Releases: 1.3, 1.4, 4.7, 6.0
Reviewed-on: http://review.typo3.org/10438
Reviewed-by: Daniel Lorenz
Tested-by: Daniel Lorenz
Reviewed-by: Schmidt Timo
Tested-by: Schmidt Timo
Reviewed-by: Tymoteusz Motylewski
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/extbase/Classes/Object/Container/Container.php
typo3/sysext/extbase/Tests/Unit/Object/Container/ContainerTest.php

index baa7ca0..d096f51 100644 (file)
@@ -335,15 +335,15 @@ class Tx_Extbase_Object_Container_Container implements t3lib_Singleton {
         */
        private function getClassInfo($className) {
                $classNameHash = sha1($className);
+               $classInfo = $this->getClassInfoCache()->get($classNameHash);
 
-                       // we also need to make sure that the cache is returning a vaild object
-                       // in case something went wrong with unserialization etc..
-               if (!$this->getClassInfoCache()->has($classNameHash) || !is_object($this->getClassInfoCache()->get($classNameHash))) {
-                       $this->getClassInfoCache()->set($classNameHash, $this->getClassInfoFactory()->buildClassInfoFromClassName($className));
+               if (!$classInfo instanceof Tx_Extbase_Object_Container_ClassInfo) {
+                       $classInfo = $this->getClassInfoFactory()->buildClassInfoFromClassName($className);
+                       $this->getClassInfoCache()->set($classNameHash, $classInfo);
                }
 
-               return $this->getClassInfoCache()->get($classNameHash);
+               return $classInfo;
        }
 }
 
-?>
\ No newline at end of file
+?>
index dd6dbc6..6b2eaff 100644 (file)
@@ -47,10 +47,11 @@ class Tx_Extbase_Tests_Unit_Object_Container_ContainerTest extends Tx_Extbase_Te
 
        public function setUp() {
                        //our mocked cache will allways indicate that he has nothing in the cache to force that we get the real classinfo
-               $mockedCache = $this->getMock('Tx_Extbase_Object_Container_ClassInfoCache',array('has'));
-               $mockedCache->expects($this->any())->method('has')->will($this->returnValue(false));
+               $mockedCache = $this->getMock('Tx_Extbase_Object_Container_ClassInfoCache', array('get'));
+               $mockedCache->expects($this->any())->method('get')->will($this->returnValue(FALSE));
+               $mockedCache->expects($this->never())->method('has');
 
-               $this->container = $this->getMock('Tx_Extbase_Object_Container_Container', array('log','getClassInfoCache'));
+               $this->container = $this->getMock('Tx_Extbase_Object_Container_Container', array('log', 'getClassInfoCache'));
                $this->container->expects($this->any())->method('getClassInfoCache')->will($this->returnValue($mockedCache));
        }
 
@@ -190,11 +191,14 @@ class Tx_Extbase_Tests_Unit_Object_Container_ContainerTest extends Tx_Extbase_Te
                $container = $this->getMock('Tx_Extbase_Object_Container_Container', array('log', 'getClassInfoCache'));
                $container->expects($this->any())->method('getClassInfoCache')->will($this->returnValue($mockedCache));
 
-               $mockedCache->expects($this->any())->method('has')->will($this->returnValue(FALSE));
+               $mockedCache->expects($this->never())->method('has');
+               $mockedCache->expects($this->once())->method('get')->with($classNameHash)->will($this->returnValue(FALSE));
                $mockedCache->expects($this->once())->method('set')->with($classNameHash, $this->anything())->will($this->returnCallback(array($this, 'setClassInfoCacheCallback')));
-               $mockedCache->expects($this->once())->method('get')->with($classNameHash)->will($this->returnCallback(array($this, 'getClassInfoCacheCallback')));
 
                $container->getInstance($className);
+
+               $this->assertInstanceOf('Tx_Extbase_Object_Container_ClassInfo', $this->cachedClassInfo);
+               $this->assertEquals($className, $this->cachedClassInfo->getClassName());
        }
 
        /**
@@ -209,16 +213,6 @@ class Tx_Extbase_Tests_Unit_Object_Container_ContainerTest extends Tx_Extbase_Te
        }
 
        /**
-        * Callback for getInstanceUsesClassNameSha1AsCacheKey
-        *
-        * @param string $id
-        * @return Tx_Extbase_Object_Container_ClassInfo
-        */
-       public function getClassInfoCacheCallback($id) {
-               return $this->cachedClassInfo;
-       }
-
-       /**
         * @test
         */
        public function getEmptyObjectReturnsInstanceOfSimpleClass() {