Quellcode durchsuchen

N.1065 Fix performance issues (caches added on query build)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@4943 a333f486-631f-4898-b8df-5754b55c2be0
eespie vor 7 Jahren
Ursprung
Commit
9e56c1be9c

+ 14 - 15
core/dbobjectsearch.class.php

@@ -1,9 +1,9 @@
 <?php
-// Copyright (C) 2010-2017 Combodo SARL
+// Copyright (c) 2010-2017 Combodo SARL
 //
 //   This file is part of iTop.
 //
-//   iTop is free software; you can redistribute it and/or modify	
+//   iTop is free software; you can redistribute it and/or modify
 //   it under the terms of the GNU Affero General Public License as published by
 //   the Free Software Foundation, either version 3 of the License, or
 //   (at your option) any later version.
@@ -15,14 +15,7 @@
 //
 //   You should have received a copy of the GNU Affero General Public License
 //   along with iTop. If not, see <http://www.gnu.org/licenses/>
-
-
-/**
- * Define filters for a given class of objects (formerly named "filter") 
- *
- * @copyright   Copyright (C) 2010-2017 Combodo SARL
- * @license     http://opensource.org/licenses/AGPL-3.0
- */
+//
 
 // Dev hack for disabling the some query build optimizations (Folding/Merging)
 define('ENABLE_OPT', true);
@@ -1623,9 +1616,9 @@ class DBObjectSearch extends DBSearch
 
 		$bIsOnQueriedClass = array_key_exists($sClassAlias, $oBuild->GetRootFilter()->GetSelectedClasses());
 
-		self::DbgTrace("Entering: ".$this->ToOQL().", ".($bIsOnQueriedClass ? "MAIN" : "SECONDARY"));
+		//self::DbgTrace("Entering: ".$this->ToOQL().", ".($bIsOnQueriedClass ? "MAIN" : "SECONDARY"));
 
-		$sRootClass = MetaModel::GetRootClass($sClass);
+		//$sRootClass = MetaModel::GetRootClass($sClass);
 		$sKeyField = MetaModel::DBGetKey($sClass);
 
 		if ($bIsOnQueriedClass)
@@ -1679,9 +1672,9 @@ class DBObjectSearch extends DBSearch
 				}
 			}
 		}
-//echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."</pre></p>\n";
+		//echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."</pre></p>\n";
 		$aExpectedAtts = array(); // array of (attcode => fieldexpression)
-//echo "<p>".__LINE__.": GetUnresolvedFields($sClassAlias, ...)</p>\n";
+		//echo "<p>".__LINE__.": GetUnresolvedFields($sClassAlias, ...)</p>\n";
 		$oBuild->m_oQBExpressions->GetUnresolvedFields($sClassAlias, $aExpectedAtts);
 
 		// Compute a clear view of required joins (from the current class)
@@ -2159,8 +2152,14 @@ class DBObjectSearch extends DBSearch
 	 *	Get the expression for the class and its subclasses (if finalclass = 'subclass' ...)
 	 *	Simplifies the final expression by grouping classes having the same expression
 	 */
-	static protected function GetPolymorphicExpression($sClass, $sAttCode)
+	static public function GetPolymorphicExpression($sClass, $sAttCode)
 	{
+		$oExpression = ExpressionCache::GetCachedExpression($sClass, $sAttCode);
+		if (!empty($oExpression))
+		{
+			return $oExpression;
+		}
+
 		// 1st step - get all of the required expressions (instantiable classes)
 		//            and group them using their OQL representation
 		//

+ 110 - 0
core/expressioncache.class.inc.php

@@ -0,0 +1,110 @@
+<?php
+// Copyright (c) 2010-2017 Combodo SARL
+//
+//   This file is part of iTop.
+//
+//   iTop is free software; you can redistribute it and/or modify
+//   it under the terms of the GNU Affero General Public License as published by
+//   the Free Software Foundation, either version 3 of the License, or
+//   (at your option) any later version.
+//
+//   iTop is distributed in the hope that it will be useful,
+//   but WITHOUT ANY WARRANTY; without even the implied warranty of
+//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//   GNU Affero General Public License for more details.
+//
+//   You should have received a copy of the GNU Affero General Public License
+//   along with iTop. If not, see <http://www.gnu.org/licenses/>
+//
+
+class ExpressionCache
+{
+	static private $aCache = array();
+
+	static public function GetCachedExpression($sClass, $sAttCode)
+	{
+		// read current cache
+		@include_once (static::GetCacheFileName());
+
+		$oExpr = null;
+		$sKey = static::GetKey($sClass, $sAttCode);
+		if (array_key_exists($sKey, static::$aCache))
+		{
+			$oExpr =  static::$aCache[$sKey];
+		}
+		else
+		{
+			if (class_exists('ExpressionCacheData'))
+			{
+				if (array_key_exists($sKey, ExpressionCacheData::$aCache))
+				{
+					$sVal = ExpressionCacheData::$aCache[$sKey];
+					$oExpr = unserialize($sVal);
+					static::$aCache[$sKey] = $oExpr;
+				}
+			}
+		}
+		return $oExpr;
+	}
+
+
+	static public function Warmup()
+	{
+		$sFilePath = static::GetCacheFileName();
+
+		if (!is_file($sFilePath))
+		{
+			$content = <<<EOF
+<?php
+// Copyright (c) 2010-2017 Combodo SARL
+// Generated Expression Cache file
+
+class ExpressionCacheData
+{
+	static \$aCache =  array(
+EOF;
+
+			foreach(MetaModel::GetClasses() as $sClass)
+			{
+				$content .= static::GetSerializedExpression($sClass, 'friendlyname');
+				if (MetaModel::IsObsoletable($sClass))
+				{
+					$content .= static::GetSerializedExpression($sClass, 'obsolescence_flag');
+				}
+			}
+
+			$content .= <<<EOF
+	);
+}
+EOF;
+
+			file_put_contents($sFilePath, $content);
+		}
+	}
+
+	static private function GetSerializedExpression($sClass, $sAttCode)
+	{
+		$sKey = static::GetKey($sClass, $sAttCode);
+		$oExpr = DBObjectSearch::GetPolymorphicExpression($sClass, $sAttCode);
+		return "'".$sKey."' => '".serialize($oExpr)."',\n";
+	}
+
+	/**
+	 * @param $sClass
+	 * @param $sAttCode
+	 * @return string
+	 */
+	static private function GetKey($sClass, $sAttCode)
+	{
+		return $sClass.'::'.$sAttCode;
+	}
+
+	public static function GetCacheFileName()
+	{
+		return utils::GetCachePath().'expressioncache.php';
+	}
+
+}
+
+
+

+ 16 - 5
core/metamodel.class.php

@@ -1,9 +1,9 @@
 <?php
-// Copyright (C) 2010-2017 Combodo SARL
+// Copyright (c) 2010-2017 Combodo SARL
 //
 //   This file is part of iTop.
 //
-//   iTop is free software; you can redistribute it and/or modify	
+//   iTop is free software; you can redistribute it and/or modify
 //   it under the terms of the GNU Affero General Public License as published by
 //   the Free Software Foundation, either version 3 of the License, or
 //   (at your option) any later version.
@@ -15,6 +15,7 @@
 //
 //   You should have received a copy of the GNU Affero General Public License
 //   along with iTop. If not, see <http://www.gnu.org/licenses/>
+//
 
 require_once(APPROOT.'core/modulehandler.class.inc.php');
 require_once(APPROOT.'core/querybuildercontext.class.inc.php');
@@ -23,6 +24,7 @@ require_once(APPROOT.'core/metamodelmodifier.inc.php');
 require_once(APPROOT.'core/computing.inc.php');
 require_once(APPROOT.'core/relationgraph.class.inc.php');
 require_once(APPROOT.'core/apc-compat.php');
+require_once(APPROOT.'core/expressioncache.class.inc.php');
 
 /**
  * Metamodel
@@ -331,9 +333,16 @@ abstract class MetaModel
 	}
 	final static public function GetObsolescenceExpression($sClass)
 	{
-		self::_check_subclass($sClass);
-		$sOql = self::$m_aClassParams[$sClass]['obsolescence_expression'];
-		$oRet = Expression::FromOQL("COALESCE($sOql, 0)");
+		if (self::IsObsoletable($sClass))
+		{
+			self::_check_subclass($sClass);
+			$sOql = self::$m_aClassParams[$sClass]['obsolescence_expression'];
+			$oRet = Expression::FromOQL("COALESCE($sOql, 0)");
+		}
+		else
+		{
+			$oRet = Expression::FromOQL("0");
+		}
 		return $oRet;
 	}
 	final static public function GetNameSpec($sClass)
@@ -4394,6 +4403,8 @@ abstract class MetaModel
 			echo "Debug<br/>\n";
 			self::static_var_dump();
 		}
+
+		ExpressionCache::Warmup();
 	}
 
 	public static function LoadConfig($oConfiguration, $bAllowCache = false)

+ 11 - 12
core/oql/expression.class.inc.php

@@ -1,9 +1,9 @@
 <?php
-// Copyright (C) 2010-2017 Combodo SARL
+// Copyright (c) 2010-2017 Combodo SARL
 //
 //   This file is part of iTop.
 //
-//   iTop is free software; you can redistribute it and/or modify	
+//   iTop is free software; you can redistribute it and/or modify
 //   it under the terms of the GNU Affero General Public License as published by
 //   the Free Software Foundation, either version 3 of the License, or
 //   (at your option) any later version.
@@ -15,16 +15,9 @@
 //
 //   You should have received a copy of the GNU Affero General Public License
 //   along with iTop. If not, see <http://www.gnu.org/licenses/>
+//
 
-
-/**
- * General definition of an expression tree (could be OQL, SQL or whatever) 
- *
- * @copyright   Copyright (C) 2010-2017 Combodo SARL
- * @license     http://opensource.org/licenses/AGPL-3.0
- */
-
-class MissingQueryArgument extends CoreException
+lass MissingQueryArgument extends CoreException
 {
 }
 
@@ -89,9 +82,15 @@ abstract class Expression
 	 */
 	static public function FromOQL($sConditionExpr)
 	{
+		static $aCache = array();
+		if (array_key_exists($sConditionExpr, $aCache))
+		{
+			return $aCache[$sConditionExpr];
+		}
 		$oOql = new OqlInterpreter($sConditionExpr);
 		$oExpression = $oOql->ParseExpression();
-		
+		$aCache[$sConditionExpr] = $oExpression;
+
 		return $oExpression;
 	}