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)) ); }
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); } }
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 }; } }
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 )); }
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); } }
/// <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); } } }
/// <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 } }