Пример #1
0
        private void JobShopScheduling(OrderOperationGraph orderOperationGraph)
        {
            IDbTransactionData dbTransactionData =
                ZppConfiguration.CacheManager.GetDbTransactionData();
            IAggregator aggregator = ZppConfiguration.CacheManager.GetAggregator();

            // some validations
            if (dbTransactionData.ProductionOrderGetAll().Any() == false)
            {
                // no JobShopScheduling needed, all Demands were satisfied without the need for a productionOrder
                return;
            }

            foreach (var productionOrder in dbTransactionData.ProductionOrderGetAll())
            {
                List <ProductionOrderOperation> operations =
                    aggregator.GetProductionOrderOperationsOfProductionOrder(
                        (ProductionOrder)productionOrder);
                if (operations == null || operations.Any() == false)
                {
                    throw new MrpRunException(
                              "How could it happen, that a productionOrder without operations exists ?");
                }
            }

            // start !
            IDirectedGraph <INode> operationGraph =
                new OperationGraph(orderOperationGraph);

            _jobShopScheduler.ScheduleWithGifflerThompsonAsZaepfel(
                new PriorityRule(operationGraph), operationGraph);
        }
Пример #2
0
        private void TraverseDemandToProviderGraph(INode node,
                                                   IStackSet <INode> visitedProductionOrders)
        {
            if (node.GetEntity().GetType() == typeof(ProductionOrderBom))
            {
                // remove, ProductionOrderBoms will be ignored and replaced by operations
                RemoveNode(node, true);
            }
            else if (node.GetEntity().GetType() == typeof(ProductionOrder) &&
                     visitedProductionOrders.Contains(node) == false)
            {
                // insert it like it is in ProductionOrderToOperationGraph

                OperationGraph operationGraph =
                    new OperationGraph((ProductionOrder)node.GetEntity());
                ReplaceNodeByDirectedGraph(node, operationGraph);
                visitedProductionOrders.Push(node);
            }

            INodes successorNodes = GetSuccessorNodes(node);

            if (successorNodes == null)
            {
                return;
            }

            foreach (var successor in successorNodes)
            {
                TraverseDemandToProviderGraph(successor, visitedProductionOrders);
            }
        }
Пример #3
0
        public static void Serialize(OperationGraph state, System.IO.BinaryWriter writer)
        {
            // Write the File Header with version
            writer.Write(new char[] { 'B', 'O', 'G', '\0' });
            writer.Write(FileVersion);

            // Write out the set of files
            var files = state.GetReferencedFiles();

            writer.Write(new char[] { 'F', 'I', 'S', '\0' });
            writer.Write((uint)files.Count);
            foreach (var file in files)
            {
                // Write the file id + path length + path
                writer.Write(file.FileId.value);
                WriteValue(writer, file.Path.ToString());
            }

            // Write out the root operation ids
            writer.Write(new char[] { 'R', 'O', 'P', '\0' });
            WriteValues(writer, state.GetRootOperationIds());

            // Write out the set of operations
            var operations = state.GetOperations();

            writer.Write(new char[] { 'O', 'P', 'S', '\0' });
            writer.Write((uint)operations.Count);
            foreach (var operationValue in state.GetOperations())
            {
                WriteOperationInfo(writer, operationValue.Value);
            }
        }
Пример #4
0
        /**
         * No need to traverse --> graph is ready, just do some modifications:
         * remove ProductionOrderBoms, replace ProductionOrder by operationGraph, ...
         */
        private DemandToProviderGraph CreateGraph3()
        {
            IDbTransactionData dbTransactionData =
                ZppConfiguration.CacheManager.GetDbTransactionData();
            DemandToProviderGraph demandToProviderGraph = new DemandToProviderGraph();


            // replace ProductionOrder by operationGraph
            foreach (var productionOrder in dbTransactionData.ProductionOrderGetAll())
            {
                if (productionOrder.IsReadOnly() == false)
                {
                    var productionOrderBomNode = new Node(productionOrder);
                    if (demandToProviderGraph.Contains(productionOrderBomNode))
                    {
                        OperationGraph operationGraph =
                            new OperationGraph((ProductionOrder)productionOrder);
                        INodes leafOfOperationGraph = operationGraph.GetLeafNodes();
                        demandToProviderGraph.ReplaceNodeByDirectedGraph(productionOrderBomNode, operationGraph);

                        /*// remove all arrows from leaf, since material must be ready to the
                         * // corresponding operation not to first operation
                         * INodes successorsOfLeaf =
                         *  demandToProviderGraph.GetSuccessorNodes(leafOfOperationGraph.GetAny());
                         * foreach (var successor in successorsOfLeaf)
                         * {
                         *  demandToProviderGraph.RemoveEdge(leafOfOperationGraph.GetAny(), successor);
                         * }*///  --> somehow not neccessary
                    }
                }
            }

            // connect every ProductionOrderBom successor to its operation
            foreach (var productionOrderBom in dbTransactionData.ProductionOrderBomGetAll())
            {
                if (productionOrderBom.IsReadOnly() == false)
                {
                    var productionOrderBomNode = new Node(productionOrderBom);
                    if (demandToProviderGraph.Contains(productionOrderBomNode))
                    {
                        ProductionOrderOperation productionOrderOperation =
                            ((ProductionOrderBom)productionOrderBom).GetProductionOrderOperation();
                        INodes successorNodes =
                            demandToProviderGraph.GetSuccessorNodes(productionOrderBom.GetId());
                        demandToProviderGraph.RemoveNode(productionOrderBomNode.GetId(), false);
                        foreach (var successor in successorNodes)
                        {
                            demandToProviderGraph.AddEdge(
                                new Edge(new Node(productionOrderOperation), successor));
                        }
                    }
                }
            }
            return(demandToProviderGraph);
        }
Пример #5
0
        /// <summary>
        /// Load the operation state from the provided directory
        /// </summary>
        public static bool TryLoadState(
            Path operationGraphFile,
            FileSystemState fileSystemState,
            out OperationGraph result)
        {
            // Verify the requested file exists
            if (!System.IO.File.Exists(operationGraphFile.ToString()))
            {
                Log.Info("Operation graph file does not exist");
                result = new OperationGraph();
                return(false);
            }

            // Open the file to read from
            using (var fileStream = System.IO.File.OpenRead(operationGraphFile.ToString()))
                using (var reader = new System.IO.BinaryReader(fileStream))
                {
                    // Read the contents of the build state file
                    try
                    {
                        var loadedResult = OperationGraphReader.Deserialize(reader);

                        // Map up the incoming file ids to the active file system state ids
                        var activeFileIdMap = new Dictionary <FileId, FileId>();
                        for (var i = 0; i < loadedResult.GetReferencedFiles().Count; i++)
                        {
                            var fileReference = loadedResult.GetReferencedFiles()[i];
                            var activeFileId  = fileSystemState.ToFileId(fileReference.Path);
                            activeFileIdMap.Add(fileReference.FileId, activeFileId);

                            // Update the referenced id
                            fileReference.FileId = activeFileId;
                        }

                        // Update all of the operations
                        foreach (var operationReference in loadedResult.GetOperations())
                        {
                            var operation = operationReference.Value;
                            UpdateFileIds(operation.DeclaredInput, activeFileIdMap);
                            UpdateFileIds(operation.DeclaredOutput, activeFileIdMap);
                            UpdateFileIds(operation.ObservedInput, activeFileIdMap);
                            UpdateFileIds(operation.ObservedOutput, activeFileIdMap);
                        }

                        result = loadedResult;
                        return(true);
                    }
                    catch
                    {
                        Log.Error("Failed to parse operation graph");
                        result = new OperationGraph();
                        return(false);
                    }
                }
        }
Пример #6
0
        private void BuildGraphColumn(
            FileSystemState fileSystemState,
            OperationGraph evaluateGraph,
            IList <IList <GraphNode> > activeGraph,
            IList <OperationId> activeIds,
            HashSet <OperationId> knownIds)
        {
            // Build up the total set of nodes in the next level
            var nextIds = new List <OperationId>();

            foreach (var operationId in activeIds)
            {
                var operation = evaluateGraph.GetOperationInfo(operationId);
                foreach (var childId in operation.Children)
                {
                    nextIds.Add(childId);
                }
            }

            // Find the depest level first
            if (nextIds.Count > 0)
            {
                BuildGraphColumn(fileSystemState, evaluateGraph, activeGraph, nextIds, knownIds);
            }

            // Build up all the nodes at this level that have not already been added
            var column = new List <GraphNode>();

            foreach (var operationId in activeIds)
            {
                if (!knownIds.Contains(operationId))
                {
                    var operation = evaluateGraph.GetOperationInfo(operationId);

                    var node = new GraphNode(operation.Title, operationId.value)
                    {
                        ChildNodes = operation.Children.Select(value => value.value).ToList(),
                    };

                    knownIds.Add(operationId);
                    column.Add(node);

                    this.operationDetailsLookup.Add(operationId.value, new OperationDetailsViewModel(fileSystemState, operation));
                }
            }

            // Add the new column at the start
            activeGraph.Insert(0, column);
        }
Пример #7
0
        /// <summary>
        /// Save the operation state for the provided directory
        /// </summary>
        public static void SaveState(
            Path operationGraphFile,
            OperationGraph state,
            FileSystemState fileSystemState)
        {
            var targetFolder = operationGraphFile.GetParent();

            // Update the operation graph referenced files
            var files = new HashSet <FileId>();

            foreach (var operationReference in state.GetOperations())
            {
                var operation = operationReference.Value;
                files.UnionWith(operation.DeclaredInput);
                files.UnionWith(operation.DeclaredOutput);
                files.UnionWith(operation.ReadAccess);
                files.UnionWith(operation.WriteAccess);
                files.UnionWith(operation.ObservedInput);
                files.UnionWith(operation.ObservedOutput);
            }

            var referencedFiles = new List <(FileId FileId, Path Path)>();

            foreach (var fileId in files)
            {
                referencedFiles.Add((fileId, fileSystemState.GetFilePath(fileId)));
            }

            state.SetReferencedFiles(referencedFiles);

            // Ensure the target directories exists
            if (!System.IO.Directory.Exists(targetFolder.ToString()))
            {
                Log.Info("Create Directory: " + targetFolder.ToString());
                System.IO.Directory.CreateDirectory(targetFolder.ToString());
            }

            // Open the file to write to
            using (var fileStream = System.IO.File.Open(operationGraphFile.ToString(), System.IO.FileMode.Create, System.IO.FileAccess.Write))
                using (var writer = new System.IO.BinaryWriter(fileStream))
                {
                    // Write the build state to the file stream
                    OperationGraphWriter.Serialize(state, writer);
                }
        }
        public void TestGraphIsComplete(string testConfigurationFileName)
        {
            InitThisTest(testConfigurationFileName);

            IDbTransactionData dbTransactionData =
                global::Zpp.ZppConfiguration.CacheManager.ReloadTransactionData();

            IDirectedGraph <INode> operationGraph =
                new OperationGraph(new OrderOperationGraph());

            IEnumerable <ProductionOrderOperation> productionOrderOperations =
                operationGraph.GetNodes().Select(x => (ProductionOrderOperation)x.GetNode().GetEntity());

            foreach (var productionOrderOperation in dbTransactionData
                     .ProductionOrderOperationGetAll())
            {
                Assert.True(productionOrderOperations.Contains(productionOrderOperation),
                            $"{productionOrderOperation} is missing.");
            }
        }
        public void TestBackwardSchedulingTransitionTimeBetweenOperationsIsCorrect(
            string testConfigurationFileName)
        {
            InitThisTest(testConfigurationFileName);

            IDbTransactionData dbTransactionData =
                ZppConfiguration.CacheManager.ReloadTransactionData();

            IDirectedGraph <INode> operationGraph =
                new OperationGraph(new OrderOperationGraph());

            IStackSet <INode> innerLeafs =
                operationGraph.GetLeafNodes().ToStackSet();
            IStackSet <INode> traversedNodes = new StackSet <INode>();

            foreach (var leaf in innerLeafs)
            {
                INodes predecessorNodesRecursive =
                    operationGraph.GetPredecessorNodesRecursive(leaf);
                IStackSet <ProductionOrderOperation> newPredecessorNodes =
                    new StackSet <ProductionOrderOperation>(
                        predecessorNodesRecursive.Select(x =>
                                                         (ProductionOrderOperation)x.GetEntity()));

                ProductionOrderOperation
                    lastOperation = (ProductionOrderOperation)leaf.GetEntity();
                ValidatePredecessorOperationsTransitionTimeIsCorrect(newPredecessorNodes,
                                                                     lastOperation, operationGraph, traversedNodes);
                traversedNodes.Push(leaf);
            }

            int expectedTraversedOperationCount =
                new Stack <ProductionOrderOperation>(
                    dbTransactionData.ProductionOrderOperationGetAll()).Count();
            int actualTraversedOperationCount = traversedNodes.Count();

            Assert.True(actualTraversedOperationCount.Equals(expectedTraversedOperationCount),
                        $"expectedTraversedOperationCount {expectedTraversedOperationCount} " +
                        $"doesn't equal actualTraversedOperationCount {actualTraversedOperationCount}'");
        }
Пример #10
0
        public static async Task <RequestGraph> ToRequestGraphAsync(OperationGraph graph, IReadOnlyList <string> sources)
        {
            var maxSourceIndex = graph.Nodes.Max(x => x.Operation.SourceIndex);

            if (maxSourceIndex >= sources.Count)
            {
                throw new ArgumentException($"The max source index in the operation graph is {maxSourceIndex} so at least {maxSourceIndex + 1} sources are required.");
            }

            var operationToRequest = await RequestBuilder.BuildAsync(sources, graph.Nodes.Select(x => x.Operation));

            // Initialize all of the request nodes.
            var requestNodes = new List <RequestNode>();
            var operationNodeToRequestNode = new Dictionary <OperationNode, RequestNode>();

            foreach (var operationNode in graph.Nodes)
            {
                var requestNode = new RequestNode(
                    operationNode.HitIndex,
                    operationToRequest[operationNode.Operation]);

                requestNodes.Add(requestNode);
                operationNodeToRequestNode.Add(operationNode, requestNode);
            }

            // Initialize dependencies.
            foreach (var operationNode in graph.Nodes)
            {
                var requestNode = operationNodeToRequestNode[operationNode];
                foreach (var dependency in operationNode.Dependencies)
                {
                    requestNode.Dependencies.Add(operationNodeToRequestNode[dependency]);
                }
            }

            return(new RequestGraph(requestNodes, sources.ToList()));
        }
Пример #11
0
        private IList <IList <GraphNode> > BuildGraph(FileSystemState fileSystemState, OperationGraph evaluateGraph)
        {
            this.operationDetailsLookup.Clear();
            var activeIds   = evaluateGraph.GetRootOperationIds();
            var activeGraph = new List <IList <GraphNode> >();
            var knownIds    = new HashSet <OperationId>();

            BuildGraphColumn(fileSystemState, evaluateGraph, activeGraph, activeIds, knownIds);

            return(activeGraph);
        }
Пример #12
0
        /// <summary>
        /// Execute the entire operation graph that is referenced by this build generate engine.
        /// </summary>
        public async Task GenerateAsync(Path soupTargetDirectory)
        {
            // Run all build operations in the correct order with incremental build checks
            Log.Diag("Build generate start");

            // Load the parameters file
            var parametersFile = soupTargetDirectory + BuildConstants.GenerateParametersFileName;

            if (!ValueTableManager.TryLoadState(parametersFile, out var parametersState))
            {
                Log.Error("Failed to load the parameter file: " + parametersFile.ToString());
                throw new InvalidOperationException("Failed to load parameter file.");
            }

            // Load the read access file
            var readAccessFile = soupTargetDirectory + BuildConstants.GenerateReadAccessFileName;
            var readAccessList = new List <Path>();

            if (!await PathListManager.TryLoadFileAsync(readAccessFile, readAccessList))
            {
                Log.Error("Failed to load the read access file: " + readAccessFile.ToString());
                throw new InvalidOperationException("Failed to load read access file.");
            }

            // Load the write access file
            var writeAccessFile = soupTargetDirectory + BuildConstants.GenerateWriteAccessFileName;
            var writeAccessList = new List <Path>();

            if (!await PathListManager.TryLoadFileAsync(writeAccessFile, writeAccessList))
            {
                Log.Error("Failed to load the write access file: " + writeAccessFile.ToString());
                throw new InvalidOperationException("Failed to load write access file.");
            }

            // Get the required input state from the parameters
            var targetDirectory  = new Path(parametersState["TargetDirectory"].AsString().ToString());
            var packageDirectory = new Path(parametersState["PackageDirectory"].AsString().ToString());

            // Load the recipe file
            var recipeFile = packageDirectory + BuildConstants.RecipeFileName;

            var(isSuccess, recipe) = await RecipeExtensions.TryLoadRecipeFromFileAsync(recipeFile);

            if (!isSuccess)
            {
                Log.Error("Failed to load the recipe: " + recipeFile.ToString());
                throw new InvalidOperationException("Failed to load recipe.");
            }

            // Combine all the dependencies shared state
            var dependenciesSharedState = LoadDependenciesSharedState(parametersState);

            // Generate the set of build extension libraries
            var buildExtensionLibraries = GenerateBuildExtensionSet(recipe, dependenciesSharedState);

            // Start a new active state that is initialized to the recipe itself
            var activeState = new ValueTable();

            // Initialize the Recipe Root Table
            var recipeState = recipe.Table;

            activeState.Add("Recipe", new Value(recipeState));

            // Initialize the Parameters Root Table
            activeState.Add("Parameters", new Value(parametersState));

            // Initialize the Dependencies Root Table
            activeState.Add("Dependencies", new Value(dependenciesSharedState));

            // Keep the extension libraries open while running the build system
            // to ensure their memory is kept alive
            var         evaluateGraph = new OperationGraph();
            IValueTable sharedState   = new ValueTable();

            {
                // Create a new build system for the requested build
                var buildTaskManager = new BuildTaskManager();

                // Run all build extension register callbacks
                foreach (var buildExtension in buildExtensionLibraries)
                {
                    var library = LoadPlugin(buildExtension);
                    FindAllCommands(library, buildTaskManager);
                }

                // Run the build
                var buildState = new BuildState(
                    activeState,
                    _fileSystemState,
                    readAccessList,
                    writeAccessList);
                buildTaskManager.Execute(buildState, soupTargetDirectory);

                // Grab the build results so the dependency libraries can be released asap
                evaluateGraph = buildState.BuildOperationGraph();
                sharedState   = buildState.SharedState;
            }

            // Save the operation graph so the evaluate phase can load it
            var evaluateGraphFile = soupTargetDirectory + BuildConstants.GenerateEvaluateOperationGraphFileName;

            OperationGraphManager.SaveState(evaluateGraphFile, evaluateGraph, _fileSystemState);

            // Save the shared state that is to be passed to the downstream builds
            var sharedStateFile = soupTargetDirectory + BuildConstants.GenerateSharedStateFileName;

            ValueTableManager.SaveState(sharedStateFile, sharedState);
            Log.Diag("Build generate end");
        }