Пример #1
0
 private void AddToEventList(DependicyInfo opt, string[] deps, Hashtable optimizables, Hashtable eventGraph, Hashtable objectMap, Hashtable processed)
 {
     // (03.01.2007 21:06)
     // //(29.11.2006 12:15)
     // if (processed.Contains(opt))
     // {
     // return;
     // }
     foreach (string depName in deps)
     {
         DependicyInfo depOpt = (DependicyInfo)optimizables[depName];
         //Only properties on object that implements IOptimizable can give messages.
         //If depOpt.Type = DependicyInfo.DEPENDICY_TYPE.PROPERTY Then
         //Add to event graph.
         if (!eventGraph.Contains(depName))
         {
             string varName = depName.Substring(0, depName.IndexOf(Calculator.PROPERTY_CHAR));
             IOptimizable optObj = (IOptimizable)m_calculator.Variable(varName);
             if (!objectMap.Contains(optObj))
             {
                 //(06.05.2006 20:44)
                 //Add event if no events added earlier.
                 // TODO: Check that this works.
                 optObj.PropertyChanged += new PropertyChangedEventHandler(PropertyChanged);
                 objectMap.Add(optObj, varName);
             }
             eventGraph.Add(depName, new ArrayList());
         }
         //Add to event list.
         ArrayList events = (ArrayList)eventGraph[depName];
         if (!events.Contains(opt.Key))
         {
             events.Add(m_calculator.GetExpressionObject(opt.Key));
         }
         //ElseIf depOpt.Type = DependicyInfo.DEPENDICY_TYPE.EXPRESSION Then
         if (depOpt.Type == DependicyInfo.DEPENDICY_TYPE_EXPRESSION)
         {
             //An expression depends on another expressions.
             AddToEventList(opt, depOpt.Deps, optimizables, eventGraph, objectMap, processed);
         }
     }
     //Tell the dependicy is processed.
     processed[opt] = true;
 }
Пример #2
0
 //Removes recursive.
 //Returns true if this is recursive.
 private bool RemoveRecursive(DependicyInfo opt, Hashtable optimized, Hashtable notOptimized, SortedList history, Hashtable processed)
 {
     //(29.11.2006 12:15)
     if (processed.Contains(opt))
     {
         return (bool)processed[opt];
     }
     if (notOptimized[opt.Key] == null)
     {
         if (opt.Deps == null)
         {
             processed[opt] = false;
             return false;
         }
         bool recursive = false;
         //Check each dependicy if it is recursive.
         foreach (string depName in opt.Deps)
         {
             string historyKey = opt.Key + " " + depName;
             if (history[historyKey] != null)
             {
                 //Recursive.
                 //(B001)
                 notOptimized[depName] = depName;
                 recursive = true;
             }
             else
             {
                 //Check with property dependicy.
                 int propIndex = depName.IndexOf(Calculator.PROPERTY_CHAR);
                 string variableName = depName.Substring(0, propIndex);
                 object depObj = m_calculator.Variable(variableName);
                 if (depObj is IOptimizable)
                 {
                     IOptimizable depOpt = (IOptimizable)depObj;
                     if (depOpt.PropertyDependices != null)
                     {
                         foreach (PropertyDependicy propertyDep in depOpt.PropertyDependices)
                         {
                             if (propertyDep.ChildProperty == depName.Substring(propIndex + 1))
                             {
                                 string parentKey = variableName + Calculator.PROPERTY_CHAR + propertyDep.ParentProperty;
                                 if (history[opt.Key + " " + parentKey] != null)
                                 {
                                     //Recursive.
                                     //(B001)
                                     notOptimized[depName] = depName;
                                     recursive = true;
                                 }
                             }
                         }
                     }
                 }
             }
         }
         //Search in each not-recursive dependicy.
         foreach (string depName in opt.Deps)
         {
             string historyKey = opt.Key + " " + depName;
             if (notOptimized[depName] == null)
             {
                 history.Add(historyKey, true);
                 if (this.RemoveRecursive((DependicyInfo)optimized[depName], optimized, notOptimized, history, processed))
                 {
                     recursive = true;
                 }
                 else
                 {
                     history.Remove(historyKey);
                 }
             }
         }
         if (recursive)
         {
             if (notOptimized[opt.Key] == null)
             {
                 notOptimized.Add(opt.Key, opt.Key);
             }
         }
         processed[opt] = recursive;
         return recursive;
     }
     else
     {
         processed[opt] = true;
         return true;
     }
 }
Пример #3
0
        public void Optimize()
        {
            if (m_calculator == null)
            {
                System.Diagnostics.Debug.WriteLine("OptimizeManager.Optimize: m_calculator == null");
                return;
            }

            //Contains dependices linked to expressions in calculator.
            Hashtable optimizables = new Hashtable();
            // If FindDependices returns false, the key is marked as not-optimizable.
            Hashtable notOptimizables = new Hashtable();
            //(28.07.2006 11:58)
            //Reduce unecessary calls to the property.
            m_functions = m_calculator.Functions;

            #region "Finding Dependicies"
            //Find all dependicies.
            Expression[] expressions = m_calculator.GetExpressions();
            foreach (Expression exp in expressions)
            {
                ArrayList deps = new ArrayList();
                // Get all the dependices of expression.
                // Use the variable name of expression key as relative.
                if (!FindDependices(exp.Key, exp.Tree, deps, exp.Key.Substring(0, exp.Key.IndexOf(Calculator.PROPERTY_CHAR)), null, false))
                {
                    // Mark as not optimizable.
                    if (!notOptimizables.Contains(exp.Key))
                    {
                        notOptimizables.Add(exp.Key, exp.Key);
                    }
                }
                else
                {
                    // Check for direct property dependence.
                    object expObject = exp.Variable;
                    if (expObject is IOptimizable)
                    {
                        IOptimizable expOpt = (IOptimizable)expObject;
                        PropertyDependicy[] propDeps = expOpt.PropertyDependices;
                        if (propDeps != null)
                        {
                            foreach (PropertyDependicy propDep in propDeps)
                            {
                                if (propDep.ParentProperty == exp.PropName)
                                {
                                    deps.Add(exp.Variable.Name + Calculator.PROPERTY_CHAR + propDep.ChildProperty);
                                }
                            }
                        }
                    }
                    if (deps.Count != 0)
                    {
                        DependicyInfo dependicy = new DependicyInfo();
                        dependicy.Key = exp.Key;
                        //Analyse each dependicy.
                        string[] depsTable = new string[deps.Count];
                        bool optimizable = true;
                        for (int i = 0; i <= depsTable.Length - 1; i++)
                        {
                            string nodeValue = (string)deps[i];
                            if (!optimizables.Contains(nodeValue))
                            {
                                //Create dependicy info.
                                DependicyInfo depNode = new DependicyInfo();
                                depNode.Key = nodeValue;
                                //Detect type.
                                depNode.Type = DependicyType(nodeValue);
                                //See if the dependicy is not optimizable.
                                if (depNode.Type == DependicyInfo.DEPENDICY_TYPE_NOT_LEGAL)
                                {
                                    optimizable = false;
                                    break;
                                }
                                else if (depNode.Type == DependicyInfo.DEPENDICY_TYPE_VARIABLE)
                                {
                                    //See if variable inherits from IOptimizable.
                                    object obj = m_calculator.Variable(depNode.Key);
                                    if (!(obj is IOptimizable))
                                    {
                                        optimizable = false;
                                        break;
                                    }
                                }
                                else if (depNode.Type == DependicyInfo.DEPENDICY_TYPE_PROPERTY)
                                {
                                    //See if variable inherits from IOptimizable.
                                    int dotIndex = depNode.Key.IndexOf(Calculator.PROPERTY_CHAR);
                                    string varName = depNode.Key.Substring(0, dotIndex);
                                    object obj = m_calculator.Variable(varName);
                                    if (!(obj is IOptimizable))
                                    {
                                        optimizable = false;
                                        break;
                                    }
                                }
                                //Add dependicy as optimizable.
                                optimizables.Add(nodeValue, depNode);
                                depsTable[i] = depNode.Key;
                            }
                            else
                            {
                                //Optimizable already exists.
                                depsTable[i] = nodeValue;
                            }
                        }
                        if (!optimizable)
                        {
                            notOptimizables.Add(exp.Key, exp.Key);
                        }
                        else
                        {
                            //Add as optimizable.
                            dependicy.Type = DependicyInfo.DEPENDICY_TYPE_EXPRESSION;
                            dependicy.Deps = depsTable;
                            //Remove temporary optimizable.
                            if (optimizables.Contains(exp.Key))
                            {
                                optimizables.Remove(exp.Key);
                            }
                            optimizables.Add(exp.Key, dependicy);
                        }
                    }
                    else
                    {
                        // Expression depends on no other.
                        DependicyInfo dep = new DependicyInfo();
                        dep.Deps = new string[] {};
                        dep.Type = DependicyInfo.DEPENDICY_TYPE_EXPRESSION;
                        dep.Key = exp.Key;
                        // Remove temporary optimizable.
                        if (optimizables.Contains(exp.Key))
                        {
                            optimizables.Remove(exp.Key);
                        }
                        optimizables.Add(dep.Key, dep);
                    }
                }
            }
            #endregion

            // Remove all not-optimizables from optimizables.
            foreach (string key in notOptimizables.Values)
            {
                if (optimizables.Contains(key))
                {
                    optimizables.Remove(key);
                }
            }
            //Remove all optimalizables that depends on not-optimalizables.
            Hashtable lastNotOptimizables = notOptimizables;
            //Continue to remove optimizables that depends on not-optimizables
            //until table of optimizables is clean.
            while (lastNotOptimizables.Count != 0)
            {
                //Find all optimizables that depends on newly removed optimizables.
                Hashtable tempNotOptimizables = new Hashtable();
                foreach (DependicyInfo dep in optimizables.Values)
                {
                    if (dep.Type == DependicyInfo.DEPENDICY_TYPE_EXPRESSION)
                    {
                        foreach (string depName in dep.Deps)
                        {
                            if (lastNotOptimizables[depName] != null)
                            {
                                tempNotOptimizables.Add(dep.Key, dep.Key);
                                //Remove child property dependices of dependicy.
                                int propIndex = depName.IndexOf(Calculator.PROPERTY_CHAR);
                                string variableName = depName.Substring(0, propIndex);
                                object obj = m_calculator.Variable(variableName);
                                if (obj is IOptimizable)
                                {
                                    IOptimizable opt = (IOptimizable)obj;
                                    if (opt.PropertyDependices != null)
                                    {
                                        foreach (PropertyDependicy propertyDep in opt.PropertyDependices)
                                        {
                                            if (propertyDep.ParentProperty == depName.Substring(propIndex + 1))
                                            {
                                                string childKey = variableName + Calculator.PROPERTY_CHAR + propertyDep.ChildProperty;
                                                if (!tempNotOptimizables.Contains(childKey))
                                                {
                                                    tempNotOptimizables.Add(childKey, childKey);
                                                }
                                            }
                                        }
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
                //Remove from optimizables in end to not get enumeration exception.
                foreach (string expName in tempNotOptimizables.Values)
                {
                    optimizables.Remove(expName);
                    if (!notOptimizables.Contains(expName))
                        notOptimizables.Add(expName, expName);
                }
                lastNotOptimizables = tempNotOptimizables;
            }
            //Remove recursive.
            foreach (DependicyInfo opt in optimizables.Values)
            {
                SortedList history = new SortedList();
                Hashtable processed = new Hashtable(optimizables.Count);
                RemoveRecursive(opt, optimizables, notOptimizables, history, processed);
            }
            //Remove all not-optimizables from optimizables.
            foreach (string key in notOptimizables.Values)
            {
                if (optimizables.Contains(key))
                {
                    optimizables.Remove(key);
                }
            }

            IVariable[] variables = m_calculator.GetVariables();
            foreach (IVariable variable in variables)
            {
                if (variable is IOptimizable)
                {
                    IOptimizable obj = (IOptimizable)variable;
                    obj.PropertyChanged -= new PropertyChangedEventHandler(PropertyChanged);
                }
            }

            #region "Dependicy Reversing"
            //Build optimize graphs.
            //Reverse the dependices.
            Hashtable eventGraph = new Hashtable();
            Hashtable objectMap = new Hashtable();
            //(29.11.2006 12:15)
            Hashtable processedEvents = new Hashtable();
            foreach (DependicyInfo opt in optimizables.Values)
            {
                if (opt.Deps != null)
                {
                    AddToEventList(opt, opt.Deps, optimizables, eventGraph, objectMap, processedEvents);
                    //An expression should update it self if it differ from it's previous value.
                    if (opt.Type == DependicyInfo.DEPENDICY_TYPE_EXPRESSION)
                    {
                        string varName = opt.Key.Substring(0, opt.Key.IndexOf(Calculator.PROPERTY_CHAR));
                        object obj = m_calculator.Variable(varName);
                        if (obj is IOptimizable)
                        {
                            IOptimizable optObj = (IOptimizable)obj;
                            if (!eventGraph.Contains(opt.Key))
                            {
                                if (!objectMap.Contains(optObj))
                                {
                                    optObj.PropertyChanged += new PropertyChangedEventHandler(PropertyChanged);
                                    objectMap.Add(optObj, varName);
                                }
                                eventGraph.Add(opt.Key, new ArrayList());
                            }
                            //Add to event list.
                            ArrayList events = (ArrayList)eventGraph[opt.Key];
                            if (!events.Contains(opt.Key))
                            {
                                events.Add(m_calculator.GetExpressionObject(opt.Key));
                            }
                        }
                    }
                }
            }
            #endregion

            m_computeList = new ComputeList();
            m_eventGraph = eventGraph;

            #region "Single Object Reference"
            //Single expressions using object references, are not necessary to compute.
            ArrayList objectReferences = new ArrayList();
            foreach (string key in notOptimizables.Values)
            {
                string exp = m_calculator.GetExpression(key);
                if (exp != null && System.Text.RegularExpressions.Regex.IsMatch(exp.Trim(), Calculator.NAME_REGEX))
                {
                    objectReferences.Add(key);
                }
            }
            foreach (string key in objectReferences)
            {
                notOptimizables.Remove(key);
            }
            //Remember the object references for later use.
            m_objectReferences = objectReferences;
            //Create list of not optimizable expressions.
            ArrayList expressionList = new ArrayList();
            foreach (string key in notOptimizables.Values)
            {
                Expression exp = m_calculator.GetExpressionObject(key);
                if (exp != null)
                {
                    expressionList.Add(exp);
                }
            }
            #endregion

            m_notOptimizables = new Expression[expressionList.Count];
            expressionList.CopyTo(m_notOptimizables);
        }