public void TraceBranchM1ComputeEx1(long lGrpId) { trace.Write(TraceLevel.Debug, "CM1GroupsTree::TraceBranchM1ComputeEx1"); try { trace.Write(TraceLevel.Debug, $"Tracing branch of group: {lGrpId}"); trace.Write(TraceLevel.Debug, $"[ Group | Type | NumChilds | NumConstraits | PruneFase | Money | Minutes ]"); CM1Group pGrp = GetGroupFromGrpId(lGrpId); while (pGrp != null) { // For each group have to be a node CM1Node pNode = GetFirstNodeFromIds(pGrp.GetGrpId()); if (pNode != null) { trace.Write(TraceLevel.Debug, $"[ {pGrp.GetGrpId(),-7} | {pGrp.GetGrpTypeId(),-4} | {pNode.ChildsNum,9} | {pNode.CnstrNum,-13} | {pNode.PruneFase,-9} | {pGrp.GetAccMoney(),-5} | {pGrp.GetAccMinutes(),-7} ]"); } pGrp = GetGroupParent(pGrp.GetGrpId()); } } catch (Exception error) { trace.Write(TraceLevel.Error, error.ToLogString()); } }
public void Init() { m_nNodeNum = 0; m_nGroupNum = 0; for (int i = 0; i < TREE_MAX_NODES; i++) { m_Nodes[i] = new CM1Node(); } for (int i = 0; i < TREE_MAX_GROUPS; i++) { m_Groups[i] = new CM1Group(); } }
public CM1Node GetFirstNodeFromIds(long lGrpId, long lGrpChId = GlobalDefs.DEF_UNDEFINED_VALUE) { trace?.Write(TraceLevel.Debug, "CM1GroupsTree::GetFirstNodeFromIds"); bool fnResult = true; CM1Node nRdo = null; try { if (lGrpId == GlobalDefs.DEF_UNDEFINED_VALUE) { throw new ArgumentNullException(nameof(lGrpId), "lGrpId == DEF_UNDEFINED_VALUE"); } for (int i = 0; i < m_nNodeNum; i++) { if (m_Nodes[i].GrpId == lGrpId && // GrpId ((lGrpChId != GlobalDefs.DEF_UNDEFINED_VALUE && // GrpChildId is defined m_Nodes[i].GrpChild != null && m_Nodes[i].GrpChild.GetGrpId() == lGrpChId) || (lGrpChId == GlobalDefs.DEF_UNDEFINED_VALUE && // GrpChildId is not defined m_Nodes[i].GrpChild == null) ) ) { nRdo = m_Nodes[i]; break; } } } catch (Exception error) { trace?.Write(TraceLevel.Error, error.ToLogString()); fnResult = false; } if (!fnResult) { nRdo = null; } return(nRdo); }
// Constraints public bool MergeOrAddConstraint(CM1Group pGrp, long lCnstrDef, float fValue) { trace?.Write(TraceLevel.Debug, "CM1GroupsTree::MergeOrAddConstraint"); bool fnResult = true; try { if (pGrp == null) { throw new ArgumentNullException(nameof(pGrp), "pGrp is NULL"); } // TODO: Best control // If MergeConstraint fails I suppose that previosly this type of constraint // was not set ... so I add it. float?result = null; if (!pGrp.MergeConstraint(lCnstrDef, fValue, ref result)) { if (pGrp.AddConstraint(lCnstrDef, fValue)) { CM1Node pNode = GetFirstNodeFromIds(pGrp.GetGrpId()); if (pNode != null) { pNode.CnstrNum++; } } else { fnResult = false; } } } catch (Exception error) { trace?.Write(TraceLevel.Error, error.ToLogString()); fnResult = false; } return(fnResult); }
// Trace public void TraceFullTree() { trace.Write(TraceLevel.Debug, "CM1GroupsTree::TraceFullTree"); try { trace?.Write(TraceLevel.Debug, $"#Groups: {GetGroupNum()} , #Nodes:{GetNodeNum()}"); trace?.Write(TraceLevel.Debug, "Groups [ Group | Type | NumChilds | NumConstraits | PruneFase ] Childs { Group | ChildGroup }:"); trace?.Write(TraceLevel.Debug, "Constraints ( Type | Value ):"); for (int i = 0; i < GetGroupNum(); i++) { CM1Group pGrp = m_Groups[i]; if (pGrp == null) { continue; } // For each group have to be a node CM1Node pNode = GetFirstNodeFromIds(pGrp.GetGrpId()); if (pNode != null) { trace?.Write(TraceLevel.Debug, $" [ {pGrp.GetGrpId(),7} | {pGrp.GetGrpTypeId(),4} | {pNode.ChildsNum,9} | {pNode.CnstrNum,13} | {pNode.PruneFase} ]\t"); // A node can have constraints CM1Constraint[] pCnstr = pGrp.GetConstraints(); for (int k = 0; k < CM1Constraint.CNSTR_NUM; k++) { if (!pCnstr[k].IsValid()) { continue; } trace?.Write(TraceLevel.Debug, $"( {pCnstr[k].TypeId, 4} | %{pCnstr[k].Value},4)"); } // A node can have childs for (int j = 0; j < GetNodeNum(); j++) { pNode = m_Nodes[j]; if (pNode == null || pNode.GrpChild == null || pNode.GrpId != pGrp.GetGrpId()) { continue; } trace?.Write(TraceLevel.Debug, $" ( {pNode.GrpId,7} | {pNode.GrpChild.GetGrpId(),10} )\t"); } ////sRdo += _T("\n"); //trace?.Write(TraceLevel.Info, (LPCTSTR)strRdo); //if (!strCnstr.IsEmpty()) //{ // /* // sRdo += _T("\t"); // sRdo += sCnstr; // sRdo += _T("\n"); // */ // trace.Write(TRACE_M1_LEVEL, _T("\t%s"), (LPCTSTR)strCnstr); //} } } } catch (Exception error) { trace.Write(TraceLevel.Error, error.ToLogString()); } }
// Fase 3: Compact Tree public bool PruneFase3() { trace?.Write(TraceLevel.Debug, "CM1GroupsTree::PruneFase3"); bool fnResult = true; try { CM1Node[] dummyNodes = new CM1Node[CM1GroupsTree.TREE_MAX_NODES]; int nNewNodeNum = 0; // Add node-base int j; for (j = 0; j < GetNodeNum(); j++) { CM1Node pNode = m_Nodes[j]; if (pNode == null) { continue; } // Node is valid? if (pNode.GrpChild == null && pNode.PruneFase == PruneFase.SECOND) { // Yes, copy the node CM1Node pNdDest = dummyNodes[nNewNodeNum++]; if (pNdDest != null) { pNdDest.Copy(pNode); } } if (pNode.GrpChild == null) { pNode.Init(); } } // Add the childs (if parent and child are in the new node-base set) for (j = 0; j < GetNodeNum(); j++) { CM1Node pNode = m_Nodes[j]; if (pNode == null) { continue; } // Not node-base, only child relationship if (pNode.GrpChild != null) { // ... if parent and child are in the new node-base set ... bool bFindParent = false; bool bFindChild = false; for (int i = 0; i < nNewNodeNum; i++) { CM1Node pNdDest = dummyNodes[i]; if (pNdDest != null && pNdDest.GrpChild == null && pNdDest.GrpId == pNode.GrpId) { bFindParent = true; } if (pNdDest != null && pNdDest.GrpChild == null && pNdDest.GrpId == pNode.GrpChild.GetGrpId()) { bFindChild = true; } } if (bFindParent && bFindChild) // Yes, copy the node { CM1Node pNdDest = dummyNodes[nNewNodeNum++]; if (pNdDest != null) { pNdDest.Copy(pNode); } } } pNode.Init(); } m_nNodeNum = 0; // First we add base nodes for (j = 0; j < nNewNodeNum; j++) { CM1Node pNdSrc = dummyNodes[j]; if (pNdSrc == null) { continue; } if (pNdSrc.GrpChild == null) { AddNode(pNdSrc.GrpId, GlobalDefs.DEF_UNDEFINED_VALUE, pNdSrc.CnstrNum); } } // Second we add child nodes for (j = 0; j < nNewNodeNum; j++) { CM1Node pNdSrc = dummyNodes[j]; if (pNdSrc == null) { continue; } if (pNdSrc.GrpChild != null) { AddNode(pNdSrc.GrpId, pNdSrc.GrpChild.GetGrpId()); } } } catch (Exception error) { trace?.Write(TraceLevel.Error, error.ToLogString()); fnResult = false; } return(fnResult); }
// Fase 2: Save childs/parents of operation group public bool PruneFase2(long lGrpId) { trace?.Write(TraceLevel.Debug, "CM1GroupsTree::PruneFase2"); bool fnResult = true; try { if (lGrpId == GlobalDefs.DEF_UNDEFINED_VALUE) { throw new ArgumentNullException(nameof(lGrpId), "lGrpId == DEF_UNDEFINED_VALUE"); } // Look for the group CM1Node pNode = GetFirstNodeFromIds(lGrpId); if (pNode == null) { throw new InvalidOperationException("Can't find the group"); } if (pNode.PruneFase == PruneFase.FIRST) { pNode.PruneFase = PruneFase.SECOND; // Look for parents and childs for (int j = 0; j < GetNodeNum(); j++) { CM1Node pLoopNode = m_Nodes[j]; if (pLoopNode == null || // No node or pLoopNode == pNode) // node-group { continue; } if (pLoopNode.GrpId == lGrpId && pLoopNode.GrpChild != null) // Child { if (!PruneFase2(pLoopNode.GrpChild.GetGrpId())) { throw new InvalidOperationException("Error in PruneFase2(pLoopNode->m_pGrpChild->GetGrpId()"); } } if (pLoopNode.GrpChild != null && pLoopNode.GrpChild.GetGrpId() == lGrpId) // Parent { if (!PruneFase2(pLoopNode.GrpId)) { throw new InvalidOperationException("Error in PruneFase2(pLoopNode->m_lGrpId)"); } } } } } catch (Exception error) { trace?.Write(TraceLevel.Error, error.ToLogString()); fnResult = false; } return(fnResult); }
// Prune // Fase 1: Save childs when parent has constraints public bool PruneFase1(long lGrpId = GlobalDefs.DEF_UNDEFINED_VALUE) { trace?.Write(TraceLevel.Debug, "CM1GroupsTree::PruneFase1"); bool fnResult = true; try { for (int j = 0; j < GetNodeNum(); j++) { CM1Node pNode = m_Nodes[j]; if (pNode == null) { continue; } if (lGrpId == GlobalDefs.DEF_UNDEFINED_VALUE && // first time pNode.GrpChild == null && // all leaves pNode.CnstrNum != 0 && // with constraints pNode.PruneFase != PruneFase.FIRST) // not pruned before { pNode.PruneFase = PruneFase.FIRST; // set the prune level if (pNode.GrpId == GlobalDefs.DEF_UNDEFINED_VALUE) { throw new InvalidOperationException("Error pNode->m_lGrpId == DEF_UNDEFINED_VALUE"); } if (!PruneFase1(pNode.GrpId)) // look for childs { throw new InvalidOperationException("Error in inner call"); } } else // I look for a group (and it's childs) { if (pNode.GrpId == lGrpId && // It is the group pNode.PruneFase != PruneFase.FIRST) // not pruned before { if (pNode.GrpChild == null) // It is a leave, set and continue; { pNode.PruneFase = PruneFase.FIRST; } else // Has childs ... look for them { if (pNode.GrpChild.GetGrpId() == GlobalDefs.DEF_UNDEFINED_VALUE) { throw new InvalidOperationException("Error pNode->m_pGrpChild->GetGrpId() == DEF_UNDEFINED_VALUE"); } if (!PruneFase1(pNode.GrpChild.GetGrpId())) { throw new InvalidOperationException("Error in inner call"); } } } } } } catch (Exception error) { trace?.Write(TraceLevel.Error, error.ToLogString()); fnResult = false; } return(fnResult); }
public int AddNode(long lGrpId, long lGrpChildId = GlobalDefs.DEF_UNDEFINED_VALUE, int nNumCnstr = 0) { trace?.Write(TraceLevel.Debug, "CM1GroupsTree::AddNode"); bool fnResult = true; int nRdo = ADD_TREE_OK; try { if (GetFirstNodeFromIds(lGrpId, lGrpChildId) != null) { nRdo = ADD_TREE_WAS; } else { m_Nodes[m_nNodeNum].Init(); m_Nodes[m_nNodeNum].GrpId = lGrpId; m_Nodes[m_nNodeNum].Grp = GetGroupFromGrpId(lGrpId); m_nGroupNum++; // Fill Group child info if (lGrpChildId != GlobalDefs.DEF_UNDEFINED_VALUE) // It's a child! { // Verify parent existence CM1Node pParentNode = GetFirstNodeFromIds(lGrpId); if (pParentNode == null) { throw new InvalidOperationException("Trying to add child node without parent node"); } m_Nodes[m_nNodeNum].GrpChild = GetGroupFromGrpId(lGrpChildId); m_Nodes[m_nNodeNum].ChildsNum = 0; m_Nodes[m_nNodeNum].CnstrNum = 0; // Number of childs++ pParentNode.ChildsNum++; } else // Not Child { m_Nodes[m_nNodeNum].GrpChild = null; m_Nodes[m_nNodeNum].ChildsNum = 0; m_Nodes[m_nNodeNum].CnstrNum = nNumCnstr; } m_nNodeNum++; // Inc node counter nRdo = ADD_TREE_OK; } } catch (Exception error) { trace?.Write(TraceLevel.Error, error.ToLogString()); fnResult = false; } if (!fnResult) { nRdo = ADD_TREE_ERR; } return(nRdo); }