Пример #1
0
        /// <summary>
        /// Calls the transformation dependency for the given computation
        /// </summary>
        /// <param name="computation">The computation that this dependency is to be called</param>
        public override void HandleDependency(Computation computation)
        {
            if (computation == null) throw new ArgumentNullException("computation");

            if (computation.IsDelayed && NeedOutput)
            {
                computation.OutputInitialized += CallComputation;
                return;
            }

            if (Filter != null && !Filter(computation)) return;
            var context = computation.TransformationContext;
            if (Selector != null)
            {
                if (computation.IsDelayed)
                {
                    var delay = computation.OutputDelay;
                    if (!NeedOutput)
                    {
                        HandleDelayedComputation(computation, context, delay);
                    }
                }
                else
                {
                    HandleNonDelayedComputation(computation, context);
                }
            }
        }
Пример #2
0
        public void InitTestContext()
        {
            ruleT1 = new TestRuleT1();
            ruleT2 = new TestRuleT2();
            ruleTN = new TestRuleTN();

            ruleDependent = new OtherRuleT1();
            transformation = new MockTransformation(ruleT1, ruleT2, ruleTN, ruleDependent);
            transformation.Initialize();
            context = CreateContext(transformation);
            trace = context.Trace;

            c_a = context.CallTransformation(ruleT1, new object[] { "a" });
            c_b = context.CallTransformation(ruleT1, new object[] { "b" });
            c_ab = context.CallTransformation(ruleT2, new object[] { "a", "b" });
            c_bc = context.CallTransformation(ruleT2, new object[] { "b", "c" });
            c_abc = context.CallTransformation(ruleTN, new object[] { "a", "b", "c" });
            c_bcd = context.CallTransformation(ruleTN, new object[] { "b", "c", "d" });

            c_a.InitializeOutput("b");
            c_b.InitializeOutput(null);
            c_ab.InitializeOutput("c");
            c_bc.InitializeOutput(null);
            c_abc.InitializeOutput("d");
            c_bcd.InitializeOutput(null);
        }
Пример #3
0
 public override void MarkRequire(Computation other, bool isRequired)
 {
     base.MarkRequire(other, isRequired);
     if (isRequired)
     {
         Interlocked.Increment(ref transformationRequirements);
         other.Computed += DecreaseTransformationRequirements;
     }
 }
 public override void MarkRequire(Computation other, bool isRequired)
 {
     base.MarkRequire(other, isRequired);
     var context = other.Context as TaskParallelComputationContext;
     if (isRequired && context != null && context != this)
     {
         if (transformationRequirements == null) transformationRequirements = new List<Task>();
         transformationRequirements.Add(context.transformTask);
     }
 }
Пример #5
0
 void ITransformationRuleDependency.HandleDependency(Computation computation)
 {
     if (computation != null)
     {
         if (computation.IsDelayed)
         {
             computation.OutputInitialized += computation_OutputInitialized;
         }
         else
         {
             HandleReadyComputation(computation);
         }
     }
 }
Пример #6
0
 /// <summary>
 /// Determines whether the current transformation rule can instantiate the output of the given computation
 /// </summary>
 /// <param name="computation">The computation that may be instantiated by the current rule</param>
 /// <returns>True, if the computation instantiates the given computation, otherwise false</returns>
 public bool IsInstantiating(Computation computation)
 {
     if (computation != null)
     {
         var rule = computation.TransformationRule;
         return HasCompliantInput(computation)
             && (rule.OutputType == OutputType || rule.OutputType.IsAssignableFrom(OutputType))
             && (BaseFilter == null || BaseFilter(computation));
     }
     else
     {
         return false;
     }
 }
        /// <summary>
        /// Handles the computation internally, i.e. calls dependencies, creates output, manages delays, etc
        /// </summary>
        /// <param name="transformationRule">The transformation rule</param>
        /// <param name="input">The input elements for this computation</param>
        /// <param name="context">The transformation context</param>
        /// <param name="computations">The computations for the input</param>
        /// <param name="originalTransformationRule">The transformation rule of the original call</param>
        /// <param name="comp">The computation</param>
        /// <param name="compCon">The computation context</param>
        private void HandleComputation(GeneralTransformationRule transformationRule, object[] input, IEnumerable context, List <ITraceEntry> computations, GeneralTransformationRule originalTransformationRule, Computation comp, ComputationContext compCon)
        {
            // The transformation output is only generated when we are handling the base transformation rule,
            // because this is always required
            if (compCon.IsDelayed)
            {
                Stack <Computation> dependantComputes = new Stack <Computation>();
                var ruleStack = Transformation.ComputeInstantiatingTransformationRulePath(comp);
                if (transformationRule != originalTransformationRule)
                {
                    ReorderStack(originalTransformationRule, comp, ruleStack);
                }
                var delayLevel = comp.Context.MinOutputDelayLevel;

                var         computes = new List <Computation>();
                Computation lastComp = null;

                while (ruleStack.Count > 0)
                {
                    var rule  = ruleStack.Pop();
                    var comp2 = FindOrCreateDependentComputation(input, computations, comp, dependantComputes, rule);

                    // in case comp2 is not yet handled, a delay does not yet exist and thus
                    // DelayLevel < minDelayLevel
                    delayLevel = Math.Max(delayLevel, Math.Max(comp2.OutputDelayLevel, comp2.Context.MinOutputDelayLevel));
                    if (lastComp != null)
                    {
                        lastComp.SetBaseComputation(comp2);
                    }
                    lastComp = comp2;
                    computes.Add(comp2);
                }

                // delay the call of dependencies
                // this prevents the issue arising from computations calling their parents that come later in the stack
                foreach (var comp2 in dependantComputes)
                {
                    CallDependencies(comp2, true);
                }

                if (delayLevel <= currentOutputDelay)
                {
                    var createRule = computes[0];

                    // Generate the output
                    var output = createRule.CreateOutput(context);

                    for (int i = computes.Count - 1; i >= 0; i--)
                    {
                        computes[i].InitializeOutput(output);
                    }
                    if (callTransformations)
                    {
                        for (int i = computes.Count - 1; i >= 0; i--)
                        {
                            computes[i].Transform();
                        }
                    }
                }
                else
                {
                    //Save computations into Delay
                    Delay(delayLevel, computes, context);
                }

                if (!callTransformations)
                {
                    for (int i = computes.Count - 1; i >= 0; i--)
                    {
                        AddToComputationOrder(computes[i], currentTransformationDelay);
                    }
                }

                for (int i = computes.Count - 1; i >= 0; i--)
                {
                    dependencyCallQueue.Enqueue(computes[i]);
                }
            }
        }
Пример #8
0
 /// <summary>
 /// Creates new event data for the given computation
 /// </summary>
 /// <param name="computation">The computation</param>
 public ComputationEventArgs(Computation computation)
 {
     Computation = computation;
 }
Пример #9
0
 public override void MarkRequire(Computation other, bool isRequired)
 {
     base.MarkRequire(other, isRequired);
     if (isRequired)
     {
         var tracingCompContext = other.Context as TracingComputationContext;
         var tracingContext = TransformationContext as TracingTransformationContext;
         if (tracingCompContext != null && tracingContext != null)
         {
             tracingContext.AppendDependency(Id, tracingCompContext.Id);
         }
     }
 }
Пример #10
0
        private void HandleDelayedDependencyInput(Computation computation, ITransformationContext context, IList list, MultipleResultAwaitingPersistor delayPersistor, object[] dependencyInput)
        {
            GeneralTransformationRule dependent = DependencyTransformation;
            var comp2 = context.CallTransformation(dependent, dependencyInput);
            if (!comp2.IsDelayed)
            {
                if (comp2.Output != null)
                {
                    if (context.IsThreadSafe)
                    {
                        lock (list)
                        {
                            list.Add(comp2.Output);
                        }
                    }
                    else
                    {
                        list.Add(comp2.Output);
                    }
                }
            }
            else
            {
                computation.DelayOutputAtLeast(comp2.Context.MinOutputDelayLevel);
                delayPersistor.WaitFor(comp2);
            }

            if (ExecuteBefore)
            {
                computation.DelayTransformationAtLeast(comp2.Context.MinTransformDelayLevel);
            }
            else
            {
                comp2.DelayTransformationAtLeast(computation.Context.MinTransformDelayLevel);
            }
        }
Пример #11
0
 private Computation FindOrCreateDependentComputation(object[] input, List<ITraceEntry> computations, Computation comp, Stack<Computation> dependantComputes, GeneralTransformationRule rule)
 {
     lock (computations)
     {
         var comp2 = computations.Where(cmp => cmp.TransformationRule == rule).OfType<Computation>().FirstOrDefault();
         if (comp2 == null)
         {
             comp2 = rule.CreateComputation(input, comp.Context);
             computations.Add(comp2);
             AddTraceEntry(comp2);
             dependantComputes.Push(comp2);
         }
         return comp2;
     }
 }
Пример #12
0
 /// <summary>
 /// Connects the computation context with the given computation
 /// </summary>
 /// <param name="computation">The computation thst is handled by this computation context</param>
 public virtual void ConnectWith(Computation computation)
 {
 }
 public override void ConnectWith(Computation computation)
 {
     computations.Add(computation);
 }
Пример #14
0
 public virtual void SetBaseComputation(Computation baseComputation) { }
        public virtual Stack <GeneralTransformationRule> ComputeInstantiatingTransformationRulePath(Computation computation)
        {
            if (computation == null)
            {
                throw new ArgumentNullException("computation");
            }

            var inputTypes = computation.TransformationRule.InputType;
            var output     = computation.TransformationRule.OutputType;
            Stack <GeneralTransformationRule> stack = new Stack <GeneralTransformationRule>();

            var current = computation.TransformationRule;

            stack.Push(current);
            while (current != null && !current.IsLeafTransformation)
            {
                current = current.Children.Where(rule => rule.IsInstantiating(computation)).FirstOrDefault();
                if (current != null)
                {
                    stack.Push(current);
                }
            }

            return(stack);
        }
Пример #16
0
 internal void MarkRequireInternal(Computation other, bool isRequired, ITransformationRuleDependency dependency)
 {
     if (other != null)
     {
         MarkRequire(other, isRequired, dependency);
         Context.MarkRequire(other, isRequired);
     }
 }
Пример #17
0
 /// <summary>
 /// Marks that this computations requires another to be transformed.
 /// </summary>
 /// <param name="other">The other computation</param>
 /// <param name="isRequired">A value indicating whether the other computation must be execute before or after the current computation</param>
 /// <param name="dependency">The dependency that required this</param>
 /// <remarks>The default implementation does nothing, so feel free to override. This method is intended to be called by NMF.Transformations, only.</remarks>
 public virtual void MarkRequire(Computation other, bool isRequired, ITransformationRuleDependency dependency) { }
Пример #18
0
        public virtual Stack<GeneralTransformationRule> ComputeInstantiatingTransformationRulePath(Computation computation)
        {
            if (computation == null) throw new ArgumentNullException("computation");

            var inputTypes = computation.TransformationRule.InputType;
            var output = computation.TransformationRule.OutputType;
            Stack<GeneralTransformationRule> stack = new Stack<GeneralTransformationRule>();

            var current = computation.TransformationRule;
            stack.Push(current);
            while (current != null && !current.IsLeafTransformation)
            {
                current = current.Children.Where(rule => rule.IsInstantiating(computation)).FirstOrDefault();
                if (current != null)
                {
                    stack.Push(current);
                }
            }

            return stack;
        }
        private static void ReorderStack(GeneralTransformationRule originalTransformationRule, Computation comp, Stack <GeneralTransformationRule> ruleStack)
        {
            var testTransformationRule = originalTransformationRule;
            var missingStack           = new Stack <GeneralTransformationRule>();

            while (!ruleStack.Contains(testTransformationRule))
            {
                missingStack.Push(testTransformationRule);
                testTransformationRule = testTransformationRule.BaseRule;
            }
            while (ruleStack.Peek() != testTransformationRule)
            {
                ruleStack.Pop();
                if (ruleStack.Count == 0)
                {
                    throw new InvalidOperationException("The rule stack from the transformation rule did not contain the base rule of the computation");
                }
            }
            while (missingStack.Count > 0)
            {
                testTransformationRule = missingStack.Pop();
                ruleStack.Push(testTransformationRule);
            }
            while (!testTransformationRule.IsLeafTransformation)
            {
                var found = false;
                foreach (var next in testTransformationRule.Children)
                {
                    if (next.IsInstantiating(comp))
                    {
                        testTransformationRule = next;
                        ruleStack.Push(next);
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    break;
                }
            }
        }
Пример #20
0
 protected abstract void HandleReadyComputation(Computation computation);
        /// <summary>
        /// Calls the transformation dependency for the given computation
        /// </summary>
        /// <param name="computation">The computation that this dependency is to be called</param>
        public override void HandleDependency(Computation computation)
        {
            if (computation == null)
            {
                throw new ArgumentNullException("computation");
            }

            if (computation.IsDelayed && NeedOutput)
            {
                computation.OutputInitialized += CallComputation;
                return;
            }

            if (Filter == null || Filter(computation))
            {
                var context = computation.TransformationContext;
                if (Selector != null)
                {
                    if (computation.IsDelayed)
                    {
                        //case delayed
                        var delay = computation.OutputDelay;
                        if (!NeedOutput)
                        {
                            object[] dependencyInput = Selector(computation);
                            if (dependencyInput != null)
                            {
                                GeneralTransformationRule dependent = DependencyTransformation;
                                var comp2 = context.CallTransformation(dependent, dependencyInput);
                                if (Persistor != null)
                                {
                                    if (!comp2.IsDelayed)
                                    {
                                        delay.Persistors.Add(new SingleItemPersistor()
                                        {
                                            Persistor = Persistor,
                                            Output    = comp2.Output
                                        });
                                    }
                                    else
                                    {
                                        computation.DelayOutputAtLeast(comp2.Context.MinOutputDelayLevel);
                                        var delayPersistor = new SingleResultAwaitingPersistor(Persistor);
                                        delayPersistor.WaitFor(comp2);
                                        delay.Persistors.Add(delayPersistor);
                                    }
                                }
                                else // persistor is null
                                {
                                    if (ExecuteBefore)
                                    {
                                        if (comp2.IsDelayed)
                                        {
                                            computation.DelayOutputAtLeast(comp2.Context.MinOutputDelayLevel);
                                        }
                                    }
                                }

                                computation.MarkRequireInternal(comp2, ExecuteBefore, this);
                            }
                        }
                    }
                    else // not delayed
                    {
                        // case output is already created
                        var      output          = computation.Output;
                        object[] dependencyInput = Selector(computation);
                        if (dependencyInput != null)
                        {
                            GeneralTransformationRule dependent = DependencyTransformation;
                            var comp2 = context.CallTransformation(dependent, dependencyInput);
                            if (Persistor != null)
                            {
                                if (!comp2.IsDelayed)
                                {
                                    Persistor(output, comp2.Output);
                                }
                                else
                                {
                                    var delay = new SingleResultAwaitingPersistor(Persistor, computation.Output);
                                    delay.WaitFor(comp2);
                                }
                            }

                            computation.MarkRequireInternal(comp2, ExecuteBefore, this);
                        }
                    }
                }
            }
        }
Пример #22
0
 protected virtual void AddTraceEntry(Computation computation)
 {
     List<ITraceEntry> comps;
     var rule = computation.TransformationRule;
     if (!computationsByTransformationRule.TryGetValue(rule, out comps))
     {
         comps = new List<ITraceEntry>();
         if (!computationsByTransformationRule.TryAdd(rule, comps))
         {
             comps = computationsByTransformationRule[rule];
         }
     }
     lock (comps)
     {
         comps.Add(computation);
     }
 }
Пример #23
0
        private void HandleNonDelayedComputation(Computation computation, ITransformationContext context)
        {
            var output = computation.Output;
            var inCollection = Selector(computation);
            if (inCollection != null)
            {
                if (Persistor != null)
                {
                    Type listType = (typeof(List<>)).MakeGenericType(DependencyTransformation.OutputType);
                    IList list = System.Activator.CreateInstance(listType) as IList;

                    MultipleResultAwaitingPersistor delayPersistor = new MultipleResultAwaitingPersistor()
                    {
                        List = list,
                        Persistor = Persistor,
                        Target = output
                    };
                    bool needDependencyPersistor = false;
                    GeneralTransformationRule dependent = DependencyTransformation;
                    if (context.IsThreadSafe)
                    {
                        Parallel.ForEach(inCollection, dependencyInput =>
                        {
                            if (HandleNonDelayedPersistedDependencyInput(computation, context, list, delayPersistor, dependent, dependencyInput))
                            {
                                needDependencyPersistor = true;
                            }
                        });
                    }
                    else
                    {
                        foreach (var dependencyInput in inCollection)
                        {
                            if (HandleNonDelayedPersistedDependencyInput(computation, context, list, delayPersistor, dependent, dependencyInput))
                            {
                                needDependencyPersistor = true;
                            }
                        }
                    }
                    if (!needDependencyPersistor) Persistor(output, list);
                }
                else
                {
                    GeneralTransformationRule dependent = DependencyTransformation;
                    if (context.IsThreadSafe)
                    {
                        Parallel.ForEach(inCollection, dependencyInput =>
                        {
                            var comp2 = context.CallTransformation(dependent, dependencyInput);
                            computation.MarkRequireInternal(comp2, ExecuteBefore, this);
                        });
                    }
                    else
                    {
                        foreach (var dependencyInput in inCollection)
                        {
                            var comp2 = context.CallTransformation(dependent, dependencyInput);
                            computation.MarkRequireInternal(comp2, ExecuteBefore, this);
                        }
                    }
                }
            }
        }
Пример #24
0
 private static void CallDependencies(Computation c, bool executeBefore)
 {
     TaskParallel.ForEach(c.TransformationRule.Dependencies, requirement =>
     {
         if (requirement.ExecuteBefore == executeBefore)
         {
             requirement.HandleDependency(c);
         }
     });
 }
Пример #25
0
        /// <summary>
        /// Handles the computation internally, i.e. calls dependencies, creates output, manages delays, etc
        /// </summary>
        /// <param name="transformationRule">The transformation rule</param>
        /// <param name="input">The input elements for this computation</param>
        /// <param name="context">The transformation context</param>
        /// <param name="computations">The computations for the input</param>
        /// <param name="originalTransformationRule">The transformation rule of the original call</param>
        /// <param name="comp">The computation</param>
        /// <param name="compCon">The computation context</param>
        private void HandleComputation(GeneralTransformationRule transformationRule, object[] input, IEnumerable context, List<ITraceEntry> computations, GeneralTransformationRule originalTransformationRule, Computation comp, ComputationContext compCon)
        {
            // The transformation output is only generated when we are handling the base transformation rule,
            // because this is always required
            if (compCon.IsDelayed)
            {
                Stack<Computation> dependantComputes = new Stack<Computation>();
                var ruleStack = Transformation.ComputeInstantiatingTransformationRulePath(comp);
                if (transformationRule != originalTransformationRule)
                {
                    ReorderStack(originalTransformationRule, comp, ruleStack);
                }
                var delayLevel = comp.Context.MinOutputDelayLevel;

                var computes = new List<Computation>();
                Computation lastComp = null;

                while (ruleStack.Count > 0)
                {
                    var rule = ruleStack.Pop();
                    var comp2 = FindOrCreateDependentComputation(input, computations, comp, dependantComputes, rule);

                    // in case comp2 is not yet handled, a delay does not yet exist and thus
                    // DelayLevel < minDelayLevel
                    delayLevel = Math.Max(delayLevel, Math.Max(comp2.OutputDelayLevel, comp2.Context.MinOutputDelayLevel));
                    if (lastComp != null)
                    {
                        lastComp.SetBaseComputation(comp2);
                    }
                    lastComp = comp2;
                    computes.Add(comp2);
                }

                // delay the call of dependencies
                // this prevents the issue arising from computations calling their parents that come later in the stack
                foreach (var comp2 in dependantComputes)
                {
                    CallDependencies(comp2, true);
                }

                if (delayLevel <= currentOutputDelay)
                {
                    var createRule = computes[0];

                    // Generate the output
                    var output = createRule.CreateOutput(context);

                    for (int i = computes.Count - 1; i >= 0; i--)
                    {
                        computes[i].InitializeOutput(output);
                    }
                    if (callTransformations)
                    {
                        for (int i = computes.Count - 1; i >= 0; i--)
                        {
                            computes[i].Transform();
                        }
                    }
                }
                else
                {
                    //Save computations into Delay
                    Delay(delayLevel, computes, context);
                }

                if (!callTransformations)
                {
                    for (int i = computes.Count - 1; i >= 0; i--)
                    {
                        AddToComputationOrder(computes[i], currentTransformationDelay);
                    }
                }

                for (int i = computes.Count - 1; i >= 0; i--)
                {
                    dependencyCallQueue.Enqueue(computes[i]);
                }
            }
        }
Пример #26
0
 public virtual void SetBaseComputation(Computation baseComputation)
 {
 }
Пример #27
0
 private static void ReorderStack(GeneralTransformationRule originalTransformationRule, Computation comp, Stack<GeneralTransformationRule> ruleStack)
 {
     var testTransformationRule = originalTransformationRule;
     var missingStack = new Stack<GeneralTransformationRule>();
     while (!ruleStack.Contains(testTransformationRule))
     {
         missingStack.Push(testTransformationRule);
         testTransformationRule = testTransformationRule.BaseRule;
     }
     while (ruleStack.Peek() != testTransformationRule)
     {
         ruleStack.Pop();
         if (ruleStack.Count == 0) throw new InvalidOperationException("The rule stack from the transformation rule did not contain the base rule of the computation");
     }
     while (missingStack.Count > 0)
     {
         testTransformationRule = missingStack.Pop();
         ruleStack.Push(testTransformationRule);
     }
     while (!testTransformationRule.IsLeafTransformation)
     {
         var found = false;
         foreach (var next in testTransformationRule.Children)
         {
             if (next.IsInstantiating(comp))
             {
                 testTransformationRule = next;
                 ruleStack.Push(next);
                 found = true;
                 break;
             }
         }
         if (!found) break;
     }
 }
Пример #28
0
 /// <summary>
 /// Waits for the given computation to initialize its output
 /// </summary>
 /// <param name="comp">The computation to wait for</param>
 public void WaitFor(Computation comp)
 {
     Remaining++;
     comp.OutputInitialized += ItemInitialized;
 }
Пример #29
0
 private void AddToComputationOrder(Computation c, byte level)
 {
     level = Math.Max(level, c.Context.MinTransformDelayLevel);
     ConcurrentQueue<Computation> list;
     if (computationOrder.Count > level)
     {
         list = computationOrder[level];
         if (list == null)
         {
             lock (_computationLevelLockObject)
             {
                 list = CreateLevel(level);
             }
         }
     }
     else
     {
         lock (_computationLevelLockObject)
         {
             if (computationOrder.Count <= level)
             {
                 while (computationOrder.Count < level)
                 {
                     computationOrder.Add(null);
                 }
                 list = new ConcurrentQueue<Computation>();
                 computationOrder.Add(list);
             }
             else
             {
                 list = CreateLevel(level);
             }
         }
     }
     list.Enqueue(c);
 }
Пример #30
0
 /// <summary>
 /// Waits for the given computation to initialize its output
 /// </summary>
 /// <param name="comp">The computation to wait for</param>
 public void WaitFor(Computation comp)
 {
     comp.OutputInitialized += comp_OutputInitialized;
 }
Пример #31
0
 /// <summary>
 /// Marks that this computations requires another to be transformed.
 /// </summary>
 /// <param name="other">The other computation</param>
 /// <param name="isRequired">A value indicating whether the other computation must be execute before or after the current computation</param>
 /// <param name="dependency">The dependency that required this</param>
 /// <remarks>The default implementation does nothing, so feel free to override. This method is intended to be called by NMF.Transformations, only.</remarks>
 public virtual void MarkRequire(Computation other, bool isRequired, ITransformationRuleDependency dependency)
 {
 }
 /// <summary>
 /// Waits for the given computation to initialize its output
 /// </summary>
 /// <param name="comp">The computation to wait for</param>
 public void WaitFor(Computation comp)
 {
     Remaining++;
     comp.OutputInitialized += ItemInitialized;
 }
Пример #33
0
 private static string PrintInputs(Computation createRule)
 {
     return(string.Join(", ", Enumerable.Range(0, createRule.InputArguments).Select(i => createRule.GetInput(i) != null ? createRule.GetInput(i).ToString() : "(null)")));
 }
Пример #34
0
 /// <summary>
 /// Connects the computation context with the given computation
 /// </summary>
 /// <param name="computation">The computation thst is handled by this computation context</param>
 public virtual void ConnectWith(Computation computation) { }
Пример #35
0
 /// <summary>
 /// Creates new event data for the given computation
 /// </summary>
 /// <param name="computation">The computation</param>
 public ComputationEventArgs(Computation computation)
 {
     Computation = computation;
 }
Пример #36
0
 /// <summary>
 /// Mark that this computation context requires another computation context to be done
 /// </summary>
 /// <param name="other">The other computation context</param>
 /// <param name="isRequired">True, if the other context is a strict requirement</param>
 public virtual void MarkRequire(Computation other, bool isRequired)
 {
     if (other == null) throw new ArgumentNullException("other");
     var otherContext = other.Context;
     if (isRequired && otherContext != this)
     {
         DelayOutputAtLeast(otherContext.MinOutputDelayLevel);
         DelayTransformationAtLeast(otherContext.MinTransformDelayLevel);
     }
 }
Пример #37
0
 /// <summary>
 /// Gets a value indicating whether the given computation has a compliant input to be instantiated by the current transformation rule
 /// </summary>
 /// <param name="computation">The computation that is a candidate for instantiation</param>
 /// <returns>True, if the input arguments match the input types of the current transformation rule, otherwise false</returns>
 public bool HasCompliantInput(Computation computation)
 {
     if (computation == null) return false;
     var inputTypes = InputType;
     if (computation.InputArguments != inputTypes.Length) return false;
     for (int i = 0; i < inputTypes.Length; i++)
     {
         var instance = computation.GetInput(i);
         if (instance != null && !inputTypes[i].IsInstanceOfType(instance)) return false;
     }
     return true;
 }
Пример #38
0
 protected virtual void AddTraceEntry(Computation computation)
 {
     List<ITraceEntry> comps;
     if (!computationsByTransformationRule.TryGetValue(computation.TransformationRule, out comps))
     {
         comps = new List<ITraceEntry>();
         computationsByTransformationRule.Add(computation.TransformationRule, comps);
     }
     comps.Add(computation);
 }
        private Computation FindOrCreateDependentComputation(object[] input, List <ITraceEntry> computations, Computation comp, Stack <Computation> dependantComputes, GeneralTransformationRule rule)
        {
            var comp2 = computations.Where(cmp => cmp.TransformationRule == rule).OfType <Computation>().FirstOrDefault();

            if (comp2 == null)
            {
                comp2 = rule.CreateComputation(input, comp.Context);
                computations.Add(comp2);
                AddTraceEntry(comp2);
                dependantComputes.Push(comp2);
            }
            return(comp2);
        }
Пример #40
0
 private void AddToComputationOrder(Computation c, byte level)
 {
     level = Math.Max(level, c.Context.MinTransformDelayLevel);
     List<Computation> list;
     if (computationOrder == null) computationOrder = new List<List<Computation>>();
     if (computationOrder.Count > level)
     {
         list = computationOrder[level];
         if (list == null)
         {
             list = new List<Computation>();
             computationOrder[level] = list;
         }
     }
     else
     {
         while (computationOrder.Count < level)
         {
             computationOrder.Add(null);
         }
         list = new List<Computation>();
         computationOrder.Add(list);
     }
     list.Add(c);
 }
        private void HandleNonDelayedComputation(Computation computation, ITransformationContext context)
        {
            var output       = computation.Output;
            var inCollection = Selector(computation);

            if (inCollection != null)
            {
                if (Persistor != null)
                {
                    Type  listType = (typeof(List <>)).MakeGenericType(DependencyTransformation.OutputType);
                    IList list     = System.Activator.CreateInstance(listType) as IList;

                    MultipleResultAwaitingPersistor delayPersistor = new MultipleResultAwaitingPersistor()
                    {
                        List      = list,
                        Persistor = Persistor,
                        Target    = output
                    };
                    bool needDependencyPersistor        = false;
                    GeneralTransformationRule dependent = DependencyTransformation;
                    if (context.IsThreadSafe)
                    {
                        Parallel.ForEach(inCollection, dependencyInput =>
                        {
                            if (HandleNonDelayedPersistedDependencyInput(computation, context, list, delayPersistor, dependent, dependencyInput))
                            {
                                needDependencyPersistor = true;
                            }
                        });
                    }
                    else
                    {
                        foreach (var dependencyInput in inCollection)
                        {
                            if (HandleNonDelayedPersistedDependencyInput(computation, context, list, delayPersistor, dependent, dependencyInput))
                            {
                                needDependencyPersistor = true;
                            }
                        }
                    }
                    if (!needDependencyPersistor)
                    {
                        Persistor(output, list);
                    }
                }
                else
                {
                    GeneralTransformationRule dependent = DependencyTransformation;
                    if (context.IsThreadSafe)
                    {
                        Parallel.ForEach(inCollection, dependencyInput =>
                        {
                            var comp2 = context.CallTransformation(dependent, dependencyInput);
                            computation.MarkRequireInternal(comp2, ExecuteBefore, this);
                        });
                    }
                    else
                    {
                        foreach (var dependencyInput in inCollection)
                        {
                            var comp2 = context.CallTransformation(dependent, dependencyInput);
                            computation.MarkRequireInternal(comp2, ExecuteBefore, this);
                        }
                    }
                }
            }
        }
Пример #42
0
 private static void CallDependencies(Computation c, bool executeBefore)
 {
     foreach (var requirement in c.TransformationRule.Dependencies)
     {
         if (requirement.ExecuteBefore == executeBefore)
         {
             requirement.HandleDependency(c);
         }
     }
 }