r2602 - performance: introduce global parse cache and use it in considerConfiguredCo...
authorDenis Ovsienko <infrastation@yandex.ru>
Fri, 3 Apr 2009 17:14:35 +0000 (17:14 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Fri, 3 Apr 2009 17:14:35 +0000 (17:14 +0000)
 - performance: make predicate table global var and compute it only once
 - performance: getObjectInfo(): add "faster" mode and employ it where appropriate
 - bugfix: generateEntityAutoTags(): fetch less data about current object to desist stack overflow provocation
 - generateEntityAutoTags(): validate the same string we are going to actually use just to be sure
 - scanIPv4Space(): set 'id' field in structure passed to displayedName(), because it expects it there
 - getFileLinks(): use 'dname' field, since it was provided anyways
 - getObjectPortsAndLinks(): don't call displayedName(), the data is already in structure

inc/database.php
inc/functions.php
inc/gateways.php
inc/init.php
inc/ophandlers.php
inc/pagetitles.php
inc/snmp.php
inc/triggers.php

index 5c9808e18387f9cddf287e685264727bc82f9d33..7e467a0fca567b92aa6030b93d1b94ab43cbff53 100644 (file)
@@ -323,7 +323,7 @@ function getRackData ($rack_id = 0, $silent = FALSE)
 }
 
 // This is a popular helper.
-function getObjectInfo ($object_id = 0)
+function getObjectInfo ($object_id = 0, $set_dname = TRUE)
 {
        if ($object_id == 0)
        {
@@ -350,7 +350,8 @@ function getObjectInfo ($object_id = 0)
                $ret['objtype_id'] = $row['objtype_id'];
                $ret['has_problems'] = $row['has_problems'];
                $ret['asset_no'] = $row['asset_no'];
-               $ret['dname'] = displayedName ($ret);
+               if ($set_dname)
+                       $ret['dname'] = displayedName ($ret);
                $ret['comment'] = $row['comment'];
        }
        $result->closeCursor();
@@ -420,7 +421,7 @@ function getObjectPortsAndLinks ($object_id = 0)
                        if (empty ($ret[$tmpkey]['remote_object_name']) and !empty ($ret[$tmpkey]['remote_object_id']))
                        {
                                $oi = getObjectInfo ($ret[$tmpkey]['remote_object_id']);
-                               $ret[$tmpkey]['remote_object_name'] = displayedName ($oi);
+                               $ret[$tmpkey]['remote_object_name'] = $oi['dname'];
                        }
                }
        }
@@ -1127,6 +1128,7 @@ function scanIPv4Space ($pairlist)
                        $ret[$ip_bin] = constructIPv4Address ($row['ip']);
                if (!isset ($dnamecache[$row['object_id']]))
                {
+                       $quasiobject['id'] = $row['object_id'];
                        $quasiobject['name'] = $row['object_name'];
                        $quasiobject['objtype_id'] = $row['objtype_id'];
                        $quasiobject['objtype_name'] = $row['objtype_name'];
@@ -3641,7 +3643,7 @@ function getFileLinks ($file_id = 0)
                                $page = 'object';
                                $id_name = 'object_id';
                                $parent = getObjectInfo($row['entity_id']);
-                               $name = $parent['name'];
+                               $name = $parent['dname'];
                                break;
                        case 'rack':
                                $page = 'rack';
index 8cf0be9505049bea9a7805382a0c511ecdadb2a0..378a733032d9b51189b838e3110df1e1928bca6e 100644 (file)
@@ -373,7 +373,7 @@ function markupObjectProblems (&$rackData)
                for ($locidx = 0; $locidx < 3; $locidx++)
                        if ($rackData[$i][$locidx]['state'] == 'T')
                        {
-                               $object = getObjectInfo ($rackData[$i][$locidx]['object_id']);
+                               $object = getObjectInfo ($rackData[$i][$locidx]['object_id'], FALSE);
                                if ($object['has_problems'] == 'yes')
                                {
                                        // Object can be already highlighted.
@@ -987,11 +987,11 @@ function generateEntityAutoTags ($entity_realm = '', $bypass_value = '')
                        $ret[] = array ('tag' => '$any_rack');
                        break;
                case 'object':
-                       $oinfo = getObjectInfo ($bypass_value);
+                       $oinfo = getObjectInfo ($bypass_value, FALSE);
                        $ret[] = array ('tag' => '$id_' . $bypass_value);
                        $ret[] = array ('tag' => '$typeid_' . $oinfo['objtype_id']);
                        $ret[] = array ('tag' => '$any_object');
-                       if (validTagName ($oinfo['name']))
+                       if (validTagName ('$cn_' . $oinfo['name']))
                                $ret[] = array ('tag' => '$cn_' . $oinfo['name']);
                        if (!count (getResidentRacksData ($bypass_value, FALSE)))
                                $ret[] = array ('tag' => '$unmounted');
@@ -1346,7 +1346,7 @@ function buildLVSConfig ($object_id = 0)
                showError ('Invalid argument', __FUNCTION__);
                return;
        }
-       $oInfo = getObjectInfo ($object_id);
+       $oInfo = getObjectInfo ($object_id, FALSE);
        $lbconfig = getSLBConfig ($object_id);
        if ($lbconfig === NULL)
        {
@@ -1937,15 +1937,16 @@ function filterEntityList ($list_in, $realm, $expression = array())
        global $rackCode;
        $list_out = array();
        foreach ($list_in as $item_key => $item_value)
-               if (TRUE === judgeEntity ($realm, $item_key, $expression, buildPredicateTable ($rackCode)))
+               if (TRUE === judgeEntity ($realm, $item_key, $expression))
                        $list_out[$item_key] = $item_value;
        return $list_out;
 }
 
 // Tell, if the given expression is true for the given entity.
-function judgeEntity ($realm, $id, $expression, $ptable)
+function judgeEntity ($realm, $id, $expression)
 {
        $item_explicit_tags = loadEntityTags ($realm, $id);
+       global $pTable;
        return eval_expression
        (
                $expression,
@@ -1955,7 +1956,7 @@ function judgeEntity ($realm, $id, $expression, $ptable)
                        getImplicitTags ($item_explicit_tags),
                        generateEntityAutoTags ($realm, $id)
                ),
-               $ptable,
+               $pTable,
                TRUE
        );
 }
@@ -1975,18 +1976,19 @@ function interpretPredicate ($pname)
        return $ret;
 }
 
-// Tell, if a constraint from config option permits giben record.
+// Tell, if a constraint from config option permits given record.
 function considerConfiguredConstraint ($entity_realm, $entity_id, $varname)
 {
-       // Compile the same text, which was used for making the decision.
-       $filtertext = getConfigVar ($varname);
-       if (!strlen ($filtertext))
+       if (!strlen (getConfigVar ($varname)))
                return TRUE; // no restriction
-       $filter = spotPayload ($filtertext, 'SYNT_EXPR');
-       if ($filter['result'] != 'ACK')
-               return FALSE; // constraint set, but cannot be used
-       global $rackCode;
-       return judgeEntity ($entity_realm, $entity_id, $filter['load'], buildPredicateTable ($rackCode));
+       global $parseCache;
+       if (!isset ($parseCache[$varname]))
+               // getConfigVar() doesn't re-read the value from DB because of its
+               // own cache, so there is no race condition here between two calls.
+               $parseCache[$varname] = spotPayload (getConfigVar ($varname), 'SYNT_EXPR');
+       if ($parseCache[$varname]['result'] != 'ACK')
+               return FALSE; // constraint set, but cannot be used due to compilation error
+       return judgeEntity ($entity_realm, $entity_id, $parseCache[$varname]['load']);
 }
 
 ?>
index e4ef876245555f6082880f0457487d14cb95ccee..70a977d1099b2a92b319eec7f57a58b6a78e4196 100644 (file)
@@ -73,7 +73,7 @@ function getSwitchVLANs ($object_id = 0)
                showError ('Invalid object_id', __FUNCTION__);
                return;
        }
-       $objectInfo = getObjectInfo ($object_id);
+       $objectInfo = getObjectInfo ($object_id, FALSE);
        $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
        if (count ($endpoints) == 0)
        {
@@ -159,7 +159,7 @@ function setSwitchVLANs ($object_id = 0, $setcmd)
        global $remote_username;
        if ($object_id <= 0)
                return oneLiner (160); // invalid arguments
-       $objectInfo = getObjectInfo ($object_id);
+       $objectInfo = getObjectInfo ($object_id, FALSE);
        $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
        if (count ($endpoints) == 0)
                return oneLiner (161); // endpoint not found
@@ -268,7 +268,7 @@ function gwSendFileToObject ($object_id = 0, $handlername, $filetext = '')
        global $remote_username;
        if ($object_id <= 0 or empty ($handlername))
                return oneLiner (160); // invalid arguments
-       $objectInfo = getObjectInfo ($object_id);
+       $objectInfo = getObjectInfo ($object_id, FALSE);
        $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
        if (count ($endpoints) == 0)
                return oneLiner (161); // endpoint not found
@@ -283,7 +283,7 @@ function gwRecvFileFromObject ($object_id = 0, $handlername, &$output)
        global $remote_username;
        if ($object_id <= 0 or empty ($handlername))
                return oneLiner (160); // invalid arguments
-       $objectInfo = getObjectInfo ($object_id);
+       $objectInfo = getObjectInfo ($object_id, FALSE);
        $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
        if (count ($endpoints) == 0)
                return oneLiner (161); // endpoint not found
index 8d881912e7c6da54bf80346bd12f72b64dfbc658..f0f39898a802c7647e2d0e0ddd4e408bba4d317d 100644 (file)
@@ -125,6 +125,12 @@ if ($rackCode['result'] != 'ACK')
        exit (1);
 }
 $rackCode = $rackCode['load'];
+// Only call buildPredicateTable() once and save the result, because it will remain
+// constant during one execution for constraints processing.
+$pTable = buildPredicateTable ($rackCode);
+// Constraints parse trees aren't cached in the database, so the least to keep
+// things running is to maintain application cache for them.
+$parseCache = array();
 
 require_once 'inc/auth.php';
 $auto_tags = array();
index 8c354bc2707b6f3a57f8ce1e5d512116f03b6a19..26d55d5e1ece21f0a131e4cd20bb19626c41be6c 100644 (file)
@@ -1265,7 +1265,7 @@ function generateAutoPorts ()
 {
        global $pageno;
        assertUIntArg ('object_id', __FUNCTION__);
-       $info = getObjectInfo ($_REQUEST['object_id']);
+       $info = getObjectInfo ($_REQUEST['object_id'], FALSE);
        // Navigate away in case of success, stay at the place otherwise.
        if (executeAutoPorts ($_REQUEST['object_id'], $info['objtype_id']))
                return buildRedirectURL (__FUNCTION__, 'OK', array(), $pageno, 'ports');
index 74044362a3eec232d5921b32d2dd9968decc2350..6e7c8d5fb232b4b1a790daf5ca73222f2f5b4844 100644 (file)
@@ -169,7 +169,7 @@ function dynamic_title_objgroup ()
                        break;
                case 'object':
                        assertUIntArg ('object_id', __FUNCTION__);
-                       $objectInfo = getObjectInfo ($_REQUEST['object_id']);
+                       $objectInfo = getObjectInfo ($_REQUEST['object_id'], FALSE);
                        if ($objectInfo == NULL)
                        {
                                showError ('getObjectInfo() failed', __FUNCTION__);
index 487653c3e21371f66d06d4f7bfb9b02349911e2c..4e4e593ef509f923eff145a2e2d156eb6357cb82 100644 (file)
@@ -91,7 +91,7 @@ function doSNMPmining ($object_id, $community)
                61 => 24,  // 10/100/1000BaseT => RJ-45/1000Base-T
        );
 
-       $objectInfo = getObjectInfo ($object_id);
+       $objectInfo = getObjectInfo ($object_id, FALSE);
        $endpoints = findAllEndpoints ($object_id, $objectInfo['name']);
        $sysName = substr (snmpget ($endpoints[0], $community, 'sysName.0'), strlen ('STRING: '));
        $sysDescr = snmpget ($endpoints[0], $community, 'sysDescr.0');
index fce1fecfbf36216deabf2741e5f8b7540c613c1c..0e17e3ed3e2183db14c2e0b0197e353059e836c5 100644 (file)
@@ -19,7 +19,7 @@ function trigger_livevlans ()
 {
        assertUIntArg ('object_id', __FUNCTION__);
        $object_id = $_REQUEST['object_id'];
-       $object = getObjectInfo ($object_id);
+       $object = getObjectInfo ($object_id, FALSE);
        if ($object['objtype_id'] != 8)
                return FALSE;
        $values = getAttrValues ($object_id);
@@ -89,7 +89,7 @@ function trigger_autoports ()
        assertUIntArg ('object_id', __FUNCTION__);
        if (!objectIsPortless ($_REQUEST['object_id']))
                return FALSE;
-       $info = getObjectInfo ($_REQUEST['object_id']);
+       $info = getObjectInfo ($_REQUEST['object_id'], FALSE);
        return count (getAutoPorts ($info['objtype_id'])) != 0;
 }