Esempio n. 1
0
 internal MSAst.MethodCallExpression CreateLocalContext(MSAst.Expression parentContext) {
     var closureVariables = _closureVariables;
     if (_closureVariables == null) {
         closureVariables = new ClosureInfo[0];
     }
     return Ast.Call(
         AstMethods.CreateLocalContext,
         parentContext,
         MutableTuple.Create(ArrayUtils.ConvertAll(closureVariables, x => GetClosureCell(x))),
         Ast.Constant(ArrayUtils.ConvertAll(closureVariables, x => x.AccessedInScope ? x.Variable.Name : null))
     );
 }
Esempio n. 2
0
 private void DecrementRunningFuncCounter(string methodId = "")
 {
     Interlocked.Decrement(
         ref _methodIdCounters.GetOrAdd(
             methodId,
             x => MutableTuple.Create(0)
             ).Item1
         );
     if (Interlocked.Decrement(ref _runningFuncCounter) <= 0)
     {
         _zeroFuncTrigger.OnNext(null);
     }
 }
Esempio n. 3
0
 private void IncrementRunningFuncCounter(string methodId = "")
 {
     Interlocked.Increment(ref _runningFuncCounter);
     Interlocked.Increment(
         ref _methodIdCounters.GetOrAdd(
             methodId,
             x => MutableTuple.Create(0)
             ).Item1
         );
     if (_state != EDisposableObjectState.Initialized)
     {
         Interlocked.Decrement(ref _runningFuncCounter);
         Interlocked.Decrement(
             ref _methodIdCounters.GetOrAdd(
                 methodId,
                 x => MutableTuple.Create(0)
                 ).Item1
             );
         throw new WrongDisposableObjectStateException()
               {
                   ActualState = _state
               };
     }
 }
Esempio n. 4
0
        internal Expression Reduce(bool shouldInterpret, bool emitDebugSymbols, int compilationThreshold,
                                   IList <ParameterExpression> parameters, Func <Expression <Func <MutableTuple, object> >,
                                                                                 Expression <Func <MutableTuple, object> > > bodyConverter)
        {
            _state   = LiftVariable(Expression.Parameter(typeof(int), "state"));
            _current = LiftVariable(Expression.Parameter(typeof(object), "current"));

            // lift the parameters into the tuple
            foreach (ParameterExpression pe in parameters)
            {
                LiftVariable(pe);
            }
            DelayedTupleExpression liftedGen = LiftVariable(_generatorParam);
            // Visit body
            Expression body = Visit(_body);

            Debug.Assert(_returnLabels.Count == 1);

            // Add the switch statement to the body
            int count = _yields.Count;
            var cases = new SwitchCase[count + 1];

            for (int i = 0; i < count; i++)
            {
                cases[i] = Expression.SwitchCase(Expression.Goto(_yields[i].Label), AstUtils.Constant(_yields[i].State));
            }
            cases[count] = Expression.SwitchCase(Expression.Goto(_returnLabels.Peek()), AstUtils.Constant(Finished));

            // Create the lambda for the PythonGeneratorNext, hoisting variables
            // into a tuple outside the lambda
            Expression[] tupleExprs = new Expression[_vars.Count];
            foreach (var variable in _orderedVars)
            {
                // first 2 are our state & out var
                if (variable.Value.Index >= 2 && variable.Value.Index < (parameters.Count + 2))
                {
                    tupleExprs[variable.Value.Index] = parameters[variable.Value.Index - 2];
                }
                else
                {
                    tupleExprs[variable.Value.Index] = Expression.Default(variable.Key.Type);
                }
            }

            Expression          newTuple  = MutableTuple.Create(tupleExprs);
            Type                tupleType = _tupleType.Value = newTuple.Type;
            ParameterExpression tupleExpr = _tupleExpr.Value = Expression.Parameter(tupleType, "tuple");
            ParameterExpression tupleArg  = Expression.Parameter(typeof(MutableTuple), "tupleArg");

            _temps.Add(_gotoRouter);
            _temps.Add(tupleExpr);

            // temps for the outer lambda
            ParameterExpression tupleTmp = Expression.Parameter(tupleType, "tuple");
            ParameterExpression ret      = Expression.Parameter(typeof(PythonGenerator), "ret");

            var innerLambda = Expression.Lambda <Func <MutableTuple, object> >(
                Expression.Block(
                    _temps.ToArray(),
                    Expression.Assign(
                        tupleExpr,
                        Expression.Convert(
                            tupleArg,
                            tupleType
                            )
                        ),
                    Expression.Switch(Expression.Assign(_gotoRouter, _state), cases),
                    body,
                    MakeAssign(_state, AstUtils.Constant(Finished)),
                    Expression.Label(_returnLabels.Peek()),
                    _current
                    ),
                _name,
                new ParameterExpression[] { tupleArg }
                );

            // Generate a call to PythonOps.MakeGeneratorClosure(Tuple data, object generatorCode)
            return(Expression.Block(
                       new[] { tupleTmp, ret },
                       Expression.Assign(
                           ret,
                           Expression.Call(
                               typeof(PythonOps).GetMethod("MakeGenerator"),
                               parameters[0],
                               Expression.Assign(tupleTmp, newTuple),
                               emitDebugSymbols ?
                               (Expression)bodyConverter(innerLambda) :
                               (Expression)Expression.Constant(
                                   new LazyCode <Func <MutableTuple, object> >(
                                       bodyConverter(innerLambda),
                                       shouldInterpret,
                                       compilationThreshold
                                       ),
                                   typeof(object)
                                   )
                               )
                           ),
                       new DelayedTupleAssign(
                           new DelayedTupleExpression(liftedGen.Index, new StrongBox <ParameterExpression>(tupleTmp), _tupleType, typeof(PythonGenerator)),
                           ret
                           ),
                       ret
                       ));
        }
Esempio n. 5
0
        private async void ProcessNewChangedArgs()
        {
            try
            {
                using (_stateHelper.GetFuncWrapper())
                {
                    var lockSemCalledWrapper = _lockSem.GetCalledWrapper();
                    lockSemCalledWrapper.Called = true;
                    using (await _lockSem.GetDisposable(true).ConfigureAwait(false))
                    {
                        while (!_cts.IsCancellationRequested && lockSemCalledWrapper.Called)
                        {
                            lockSemCalledWrapper.Called = false;
                            var currentChangesNumInDictToRemove =
                                _changedArgsDict.Keys.Where(_ => _ <= _prevChangesCounter).ToList();
                            foreach (long key in currentChangesNumInDictToRemove)
                            {
                                MyNotifyCollectionChangedArgs <TItem> removedArgs;
                                _changedArgsDict.TryRemove(key, out removedArgs);
                            }
                            MyNotifyCollectionChangedArgs <TItem> nextArgs;
                            if (
                                _changedArgsDict.TryRemove(
                                    _prevChangesCounter + 1,
                                    out nextArgs
                                    )
                                )
                            {
                                lockSemCalledWrapper.Called = true;
                                if (nextArgs.ChangedAction == EMyCollectionChangedAction.Reset)
                                {
                                    await ResetActionAsync().ConfigureAwait(false);
                                }
                                else if (nextArgs.ChangedAction == EMyCollectionChangedAction.NewItemsRangeInserted)
                                {
                                    var insertIndex = nextArgs.NewItemsIndices[0];
                                    var insertCount = nextArgs.NewItems.Count;
                                    if (insertCount > 0)
                                    {
                                        var insertArgs = new List <MutableTuple <int, TItem> >();
                                        for (int i = 0; i < insertCount; i++)
                                        {
                                            insertArgs.Add(
                                                MutableTuple.Create(
                                                    i + insertIndex,
                                                    nextArgs.NewItems[i]
                                                    )
                                                );
                                        }
                                        await _resultCollection.InsertRangeAtAsync(
                                            insertIndex,
                                            insertArgs
                                            ).ConfigureAwait(false);

                                        _originCollectionCopy.InsertRange(
                                            insertIndex,
                                            nextArgs.NewItems
                                            );
                                        /**/
                                        var currentResultCount = _originCollectionCopy.Count;
                                        var bulkUpdateArgs     = new List <Tuple <int, MutableTuple <int, TItem> > >();
                                        for (int i = insertIndex + insertCount; i < currentResultCount; i++)
                                        {
                                            bulkUpdateArgs.Add(
                                                Tuple.Create(
                                                    i,
                                                    MutableTuple.Create(
                                                        i,
                                                        _originCollectionCopy[i]
                                                        )
                                                    )
                                                );
                                        }
                                        if (bulkUpdateArgs.Any())
                                        {
                                            await _resultCollection.ReplaceBulkAsync(
                                                bulkUpdateArgs
                                                ).ConfigureAwait(false);
                                        }
                                    }
                                    _prevChangesCounter++;
                                }
                                else if (nextArgs.ChangedAction == EMyCollectionChangedAction.ItemsRangeRemoved)
                                {
                                    var removeIndex = nextArgs.OldItemsIndices[0];
                                    var removeCount = nextArgs.OldItems.Count;
                                    if (removeCount > 0)
                                    {
                                        await _resultCollection.RemoveRangeAsync(
                                            removeIndex,
                                            removeCount
                                            ).ConfigureAwait(false);

                                        _originCollectionCopy.RemoveRange(
                                            removeIndex,
                                            removeCount
                                            );
                                        /**/
                                        var currentResultCount = _originCollectionCopy.Count;
                                        var bulkUpdateArgs     = new List <Tuple <int, MutableTuple <int, TItem> > >();
                                        for (int i = removeIndex; i < currentResultCount; i++)
                                        {
                                            bulkUpdateArgs.Add(
                                                Tuple.Create(
                                                    i,
                                                    MutableTuple.Create(
                                                        i,
                                                        _originCollectionCopy[i]
                                                        )
                                                    )
                                                );
                                        }
                                        if (bulkUpdateArgs.Any())
                                        {
                                            await _resultCollection.ReplaceBulkAsync(
                                                bulkUpdateArgs
                                                ).ConfigureAwait(false);
                                        }
                                    }
                                    _prevChangesCounter++;
                                }
                                else if (nextArgs.ChangedAction == EMyCollectionChangedAction.ItemsChanged)
                                {
                                    var count          = nextArgs.NewItems.Count;
                                    var bulkUpdateArgs = new List <Tuple <int, MutableTuple <int, TItem> > >();
                                    for (int i = 0; i < count; i++)
                                    {
                                        _originCollectionCopy[nextArgs.NewItemsIndices[i]] = nextArgs.NewItems[i];
                                        bulkUpdateArgs.Add(
                                            Tuple.Create(
                                                nextArgs.NewItemsIndices[i],
                                                MutableTuple.Create(
                                                    nextArgs.NewItemsIndices[i],
                                                    nextArgs.NewItems[i]
                                                    )
                                                )
                                            );
                                    }
                                    if (bulkUpdateArgs.Any())
                                    {
                                        await _resultCollection.ReplaceBulkAsync(
                                            bulkUpdateArgs
                                            ).ConfigureAwait(false);
                                    }
                                    _prevChangesCounter++;
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (WrongDisposableObjectStateException)
            {
            }
            catch (Exception exc)
            {
                MiscFuncs.HandleUnexpectedError(exc, _log);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Processa os vértices restantes na pesquisa em profundidade.
        /// </summary>
        /// <param name="stack">A pilha auxiliar.</param>
        /// <param name="visited">Os vértices visitados.</param>
        /// <param name="processedEdges">As arestas processadas.</param>
        /// <param name="connectedVerticesFunc">
        /// A função que é executada aquando da visita a um vértice.
        /// </param>
        private void ProcessDepthSearchVertex(
            Stack <MutableTuple <VertexType, VertexType, EdgeType, List <EdgeType>, int> > stack,
            Dictionary <VertexType, bool> visited,
            Dictionary <EdgeType, bool> processedEdges,
            Action <VertexType, VertexType, bool, EdgeType> connectedVerticesFunc)
        {
            while (stack.Count > 0)
            {
                var pair       = stack.Peek();
                var currVertex = pair.Item1;
                var currEdges  = pair.Item4;
                var pointer    = pair.Item5;

                if (pointer < currEdges.Count)
                {
                    var currEdge = currEdges[pointer];
                    if (!processedEdges.ContainsKey(currEdge))
                    {
                        var reverse = true;
                        if (currEdge.InitialVertex.Equals(currVertex))
                        {
                            reverse = false;
                        }

                        if (reverse)
                        {
                            if (!directed)
                            {
                                var otherVertex = currEdge.InitialVertex;
                                processedEdges.Add(currEdge, true);
                                if (visited.ContainsKey(otherVertex))
                                {
                                    connectedVerticesFunc.Invoke(
                                        otherVertex,
                                        currEdge.FinalVertex,
                                        true,
                                        currEdge);
                                }
                                else
                                {
                                    visited.Add(otherVertex, true);
                                    stack.Push(MutableTuple.Create(
                                                   otherVertex,
                                                   currVertex,
                                                   currEdge,
                                                   this.vertices[otherVertex],
                                                   0));
                                }
                            }
                        }
                        else
                        {
                            var otherVertex = currEdge.FinalVertex;
                            processedEdges.Add(currEdge, true);
                            if (visited.ContainsKey(otherVertex))
                            {
                                connectedVerticesFunc.Invoke(
                                    otherVertex,
                                    currEdge.InitialVertex,
                                    true,
                                    currEdge);
                            }
                            else
                            {
                                visited.Add(otherVertex, true);
                                stack.Push(MutableTuple.Create(
                                               otherVertex,
                                               currVertex,
                                               currEdge,
                                               this.vertices[otherVertex],
                                               0));
                            }
                        }
                    }

                    pair.Item5 = pointer + 1;
                }
                else
                {
                    stack.Pop();
                    connectedVerticesFunc.Invoke(
                        currVertex,
                        pair.Item2,
                        false,
                        pair.Item3);
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Efectua uma pesquisa em profunidade sobre o grafo.
        /// </summary>
        /// <param name="vertices">Os vértices de partida.</param>
        /// <param name="initialVerticesFunc">
        /// A função a ser executada nos vértices de entrada.
        /// </param>
        /// <param name="connectedVerticesFunc">
        /// A função que é executada aquando da visita a um vértice conectado
        /// recebe, como argumentos, o vértice que está a ser visitado, o vértice anterior,
        /// um valor que indica se o vértice corrente já foi visitado e a aresta seguida.
        /// </param>
        public void DepthFirstSearch(
            IEnumerable <VertexType> vertices,
            Action <VertexType> initialVerticesFunc,
            Action <VertexType, VertexType, bool, EdgeType> connectedVerticesFunc)
        {
            if (vertices == null)
            {
                throw new ArgumentNullException("vertices");
            }
            else if (initialVerticesFunc == null)
            {
                throw new ArgumentNullException("initialVerticesFunc");
            }
            else if (connectedVerticesFunc == null)
            {
                throw new ArgumentNullException("connectedVerticesFunc");
            }
            else
            {
                this.CheckVertices(vertices);
                var stack = new Stack <MutableTuple <VertexType, VertexType, EdgeType, List <EdgeType>, int> >();
                Dictionary <VertexType, bool> visited        = new Dictionary <VertexType, bool>();
                Dictionary <EdgeType, bool>   processedEdges = new Dictionary <EdgeType, bool>();
                var verticesEnumerator = vertices.GetEnumerator();

                while (verticesEnumerator.MoveNext())
                {
                    var currVertex = verticesEnumerator.Current;
                    if (!visited.ContainsKey(currVertex))
                    {
                        visited.Add(currVertex, true);
                        var innerEdges  = this.vertices[currVertex];
                        var edgesLength = innerEdges.Count;
                        var isTerminal  = true;
                        for (var i = 0; i < edgesLength; ++i)
                        {
                            var currEdge = innerEdges[i];
                            if (!processedEdges.ContainsKey(currEdge))
                            {
                                var reverse = true;
                                if (currEdge.InitialVertex.Equals(currVertex))
                                {
                                    reverse = false;
                                }

                                if (reverse)
                                {
                                    if (!directed)
                                    {
                                        var otherVertex = currEdge.InitialVertex;
                                        processedEdges.Add(currEdge, true);
                                        if (visited.ContainsKey(otherVertex))
                                        {
                                            connectedVerticesFunc.Invoke(
                                                otherVertex,
                                                currVertex,
                                                true,
                                                currEdge);
                                        }
                                        else
                                        {
                                            visited.Add(otherVertex, true);
                                            stack.Push(MutableTuple.Create(
                                                           otherVertex,
                                                           currEdge.FinalVertex,
                                                           currEdge,
                                                           this.vertices[otherVertex],
                                                           0));
                                            this.ProcessDepthSearchVertex(
                                                stack,
                                                visited,
                                                processedEdges,
                                                connectedVerticesFunc);
                                        }
                                    }
                                }
                                else
                                {
                                    var otherVertex = currEdge.FinalVertex;
                                    processedEdges.Add(currEdge, true);
                                    if (visited.ContainsKey(otherVertex))
                                    {
                                        connectedVerticesFunc.Invoke(
                                            otherVertex,
                                            currVertex,
                                            true,
                                            currEdge);
                                    }
                                    else
                                    {
                                        visited.Add(otherVertex, true);
                                        stack.Push(MutableTuple.Create(
                                                       otherVertex,
                                                       currEdge.InitialVertex,
                                                       currEdge,
                                                       this.vertices[otherVertex],
                                                       0));
                                        this.ProcessDepthSearchVertex(
                                            stack,
                                            visited,
                                            processedEdges,
                                            connectedVerticesFunc);
                                    }
                                }
                            }
                        }

                        if (isTerminal)
                        {
                            initialVerticesFunc.Invoke(
                                currVertex);
                        }
                    } // !visited
                }     // while
            }
        }