From: <ma...@us...> - 2011-03-13 20:07:36
|
Revision: 1061 http://scstudio.svn.sourceforge.net/scstudio/?rev=1061&view=rev Author: madzin Date: 2011-03-13 20:07:29 +0000 (Sun, 13 Mar 2011) Log Message: ----------- Fix bug in MSC diff algorithm. The algorithm was set the identification during the matrix creation, which brings identification inconsistency when some event was multiple times compared with different events with the same properties. Now the algorithm set identification after first run of diff part of the algorithm. Modified Paths: -------------- trunk/src/membership/diff_impl.cpp trunk/src/membership/membership_base.h trunk/tests/diff/CMakeLists.txt Added Paths: ----------- trunk/tests/diff/flow05_3.mpr.result2 trunk/tests/diff/flow06_3.mpr.result2 trunk/tests/diff/flow08_1.mpr.result2 trunk/tests/diff/flow09_1.mpr trunk/tests/diff/flow09_1.mpr.result trunk/tests/diff/spec09.mpr Modified: trunk/src/membership/diff_impl.cpp =================================================================== --- trunk/src/membership/diff_impl.cpp 2011-03-09 09:41:13 UTC (rev 1060) +++ trunk/src/membership/diff_impl.cpp 2011-03-13 20:07:29 UTC (rev 1061) @@ -22,6 +22,8 @@ bool check_matching_event_creation(std::map<std::wstring, std::list<Difference*> > insert_map, Difference* diff); std::map<std::wstring, std::list<Difference*> > create_insert_map(MembershipContext* c, const std::map<std::wstring, Difference*>& diff_map); +void diff_identification_settings(MembershipContext* c, const std::map<std::wstring, Difference*>& diff_map); +InstancePtr find_instance(BMscPtr bmsc, std::wstring name); void print_result(BMscPtr msc) { @@ -85,7 +87,6 @@ BMscPtr bmsc = boost::dynamic_pointer_cast<BMsc> (specification); - //TODO refactoring flow BMSC get to MembershipContext and start to use it (not as the parameter) MembershipContext* c = new MembershipContext(); c->set_mem(this); c->set_diff_type(MESSAGE); @@ -132,8 +133,8 @@ row++; - if(c->get_diff_type() == MESSAGE) - set_identification(c, event_a.get(), event_b.get()); +// if(c->get_diff_type() == MESSAGE) +// set_identification(c, event_a.get(), event_b.get()); event_a = event_a->get_successor(); event_b = event_b->get_successor(); @@ -312,8 +313,8 @@ while (event_a != NULL && event_b != NULL && event_comparison(c, event_a, event_b)) { - if(c->get_diff_type() == MESSAGE) - set_identification(c, event_a.get(), event_b.get()); +// if(c->get_diff_type() == MESSAGE) +// set_identification(c, event_a.get(), event_b.get()); event_a = event_a->get_successor(); event_b = event_b->get_successor(); @@ -351,6 +352,7 @@ dup_flow = duplicator.duplicate(flow); c->set_bmsc(dup_flow); + c->set_specification(specification); InstancePtrList spec_inst = specification->get_instances(); InstancePtrList flow_inst = dup_flow->get_instances(); @@ -384,6 +386,8 @@ for(int i = 0; i < 2; i++) { + diff_map.clear(); + for(all_inst_it = all_instances.begin(); all_inst_it != all_instances.end(); all_inst_it++) { spec_found = false; @@ -477,9 +481,12 @@ //when the instance of proper name was found in both MSCs (specification, flow) Difference* diff = instance_diff(c, *flow_it, *spec_it); - if(i == 1 && diff != NULL) + if(diff != NULL) diff_map.insert(std::make_pair((*flow_it)->get_label(), diff)); } + + if(i == 0) + diff_identification_settings(c, diff_map); } @@ -1029,3 +1036,118 @@ return insert_map; } + +void diff_identification_settings(MembershipContext* c, const std::map<std::wstring, Difference*>& diff_map) +{ + std::map<std::wstring, Difference*>::const_iterator map_it; + std::vector<Difference*> inst_diff; + InstancePtr spec_inst, flow_inst; + StrictEventPtr spec_e, flow_e; + Difference* diff; + + BMscPtr specification = boost::dynamic_pointer_cast<BMsc> (c->get_specification()); + + if(specification == NULL) + return ; + + InstancePtrList instances = specification->get_instances(); + InstancePtrList::iterator instances_it; + + for(instances_it = instances.begin(); instances_it != instances.end(); instances_it++) + { + inst_diff.clear(); + diff = NULL; + + map_it = diff_map.find((*instances_it)->get_label()); + + if(map_it != diff_map.end()) + diff = map_it->second; + + while(diff != NULL) + { + inst_diff.push_back(diff); + diff = diff->getPrevious(); + } + + spec_inst = find_instance(boost::dynamic_pointer_cast<BMsc> (c->get_specification()), (*instances_it)->get_label()); + flow_inst = find_instance(c->get_bmsc(), (*instances_it)->get_label()); + + if(spec_inst == NULL || flow_inst == NULL) + continue; + + StrictOrderAreaPtr spec_ea = boost::dynamic_pointer_cast<StrictOrderArea>(spec_inst->get_first()); + StrictOrderAreaPtr flow_ea = boost::dynamic_pointer_cast<StrictOrderArea>(flow_inst->get_first()); + + if(spec_ea == NULL || flow_ea == NULL) + continue; + + spec_e = spec_ea->get_first(); + flow_e = flow_ea->get_first(); + + //set identification to proper events + std::vector<Difference*>::reverse_iterator vec_it = inst_diff.rbegin(); + while(spec_e != NULL && flow_e != NULL) + { + if(vec_it != inst_diff.rend()) + { + if((*vec_it)->getOperation() == REMOVE) + { + if((*vec_it)->getLocation() == flow_e) + { + //due to some differences (REMOVE and ADD) can have same location + //in case the following diffrence has the same location flow_e is not changing + if(vec_it + 1 == inst_diff.rend() || + (vec_it + 1 != inst_diff.rend() && (*(vec_it+1))->getLocation() != (*vec_it)->getLocation())) + { + flow_e = flow_e->get_successor(); + vec_it++; + continue; + } + } + } + else + { + if((*vec_it)->getLocation() == NULL || (*vec_it)->getLocation() == flow_e->get_predecessor()) + { + spec_e = spec_e->get_successor(); + + //due to in some cases the flow_e was not changed + //in case that flow_e was not changed and the location of the following diffrence is not same + //it is neccessary to change the flow_e too + if(vec_it != inst_diff.rbegin() && + (*(vec_it-1))->getLocation() == (*vec_it)->getLocation() && + (*vec_it)->getLocation() != NULL && + (vec_it+1 == inst_diff.rend() || (*vec_it)->getLocation() != (*(vec_it+1))->getLocation())) + { + flow_e = flow_e->get_successor(); + } + vec_it++; + continue; + } + } + } + + + set_identification(c, spec_e.get(), flow_e.get()); + spec_e = spec_e->get_successor(); + flow_e = flow_e->get_successor(); + } + } +} + +InstancePtr find_instance(BMscPtr bmsc, std::wstring name) +{ + if(bmsc == NULL) + return NULL; + + InstancePtrList insts = bmsc->get_instances(); + InstancePtrList::iterator it; + + for(it = insts.begin(); it != insts.end(); it++) + { + if((*it)->get_label() == name) + return *it; + } + + return NULL; +} Modified: trunk/src/membership/membership_base.h =================================================================== --- trunk/src/membership/membership_base.h 2011-03-09 09:41:13 UTC (rev 1060) +++ trunk/src/membership/membership_base.h 2011-03-13 20:07:29 UTC (rev 1061) @@ -50,6 +50,7 @@ MembershipAlg* mem; //! enable print_report int max_id; //! identification for receive events BMscPtr bmsc; //! bmsc which represents the flow + MscPtr msc; //! msc which represents the specification std::vector<std::wstring> focused_instances; //! name of instances on which a user is focused on std::map<CoregionAreaPtr, SnapshotContextPtr> snapshots; //! snapshots of context for each coregion std::vector<Event*> attributed_events; //! events with attribute @@ -106,7 +107,17 @@ { return bmsc; } + + void set_specification(MscPtr m) + { + msc = m; + } + const MscPtr get_specification() const + { + return msc; + } + void set_focused_instances(std::vector<std::wstring> instances) { focused_instances.insert(focused_instances.begin(), instances.begin(), instances.end()); Modified: trunk/tests/diff/CMakeLists.txt =================================================================== --- trunk/tests/diff/CMakeLists.txt 2011-03-09 09:41:13 UTC (rev 1060) +++ trunk/tests/diff/CMakeLists.txt 2011-03-13 20:07:29 UTC (rev 1061) @@ -38,4 +38,5 @@ ADD_DIFF_TEST(spec07.mpr flow07_1.mpr 1) ADD_DIFF_TEST(spec07.mpr flow07_2.mpr 1) ADD_DIFF_TEST(spec08.mpr flow08_1.mpr 1) +ADD_DIFF_TEST(spec09.mpr flow09_1.mpr 1) Added: trunk/tests/diff/flow05_3.mpr.result2 =================================================================== --- trunk/tests/diff/flow05_3.mpr.result2 (rev 0) +++ trunk/tests/diff/flow05_3.mpr.result2 2011-03-13 20:07:29 UTC (rev 1061) @@ -0,0 +1,19 @@ +OK: HMSC contains bMSC + +mscdocument msc_diff; +msc Page_1; +inst A; +inst B; +A: instance; +/* ADDED */ +/* ADDED */ +out a,0 to B; +out a,1 to B; +endinstance; +B: instance; +/* ADDED */ +/* ADDED */ +in a,0 from A; +in a,1 from A; +endinstance; +endmsc; Added: trunk/tests/diff/flow06_3.mpr.result2 =================================================================== --- trunk/tests/diff/flow06_3.mpr.result2 (rev 0) +++ trunk/tests/diff/flow06_3.mpr.result2 2011-03-13 20:07:29 UTC (rev 1061) @@ -0,0 +1,19 @@ +OK: HMSC contains bMSC + +mscdocument msc_diff; +msc Page_1; +inst A; +inst B; +A: instance; +/* ADDED */ +/* ADDED */ +out a,0 to B; +out a,1 to B; +endinstance; +B: instance; +in a,1 from A; +/* ADDED */ +/* ADDED */ +in a,0 from A; +endinstance; +endmsc; Added: trunk/tests/diff/flow08_1.mpr.result2 =================================================================== --- trunk/tests/diff/flow08_1.mpr.result2 (rev 0) +++ trunk/tests/diff/flow08_1.mpr.result2 2011-03-13 20:07:29 UTC (rev 1061) @@ -0,0 +1,19 @@ +OK: HMSC contains bMSC + +mscdocument msc_diff; +msc Page_1; +inst A; +inst B; +A: instance; +in a,0 from B; +/* ADDED */ +/* ADDED */ +in a,1 from B; +endinstance; +B: instance; +/* ADDED */ +/* ADDED */ +out a,1 to A; +out a,0 to A; +endinstance; +endmsc; Added: trunk/tests/diff/flow09_1.mpr =================================================================== --- trunk/tests/diff/flow09_1.mpr (rev 0) +++ trunk/tests/diff/flow09_1.mpr 2011-03-13 20:07:29 UTC (rev 1061) @@ -0,0 +1,18 @@ +msc Spec; +inst A; +inst B; +text 'Diff algorithm bug: Flow Spec and specification Flow2'; +text 'Diff algorithm TODO: Set position to a new instance (Flow 3 and Spec)'; +A: instance; +in n,0 from B; +in n,1 from B; +out m,2 to B; +in n,3 from B; +endinstance; +B: instance; +out n,0 to A; +out n,1 to A; +in m,2 from A; +out n,3 to A; +endinstance; +endmsc; Added: trunk/tests/diff/flow09_1.mpr.result =================================================================== --- trunk/tests/diff/flow09_1.mpr.result (rev 0) +++ trunk/tests/diff/flow09_1.mpr.result 2011-03-13 20:07:29 UTC (rev 1061) @@ -0,0 +1,35 @@ +OK: HMSC contains bMSC + +mscdocument msc_diff; +msc Spec; +inst A; +inst B; +A: instance; +/* ADDED */ +/* ADDED */ +out m,0 to B; +/* ADDED */ +/* ADDED */ +out m,1 to B; +in n,2 from B; +in n,3 from B; +out m,4 to B; +/* REMOVED */ +/* REMOVED */ +in n,5 from B; +endinstance; +B: instance; +/* ADDED */ +/* ADDED */ +in m,0 from A; +/* ADDED */ +/* ADDED */ +in m,1 from A; +out n,2 to A; +out n,3 to A; +in m,4 from A; +/* REMOVED */ +/* REMOVED */ +out n,5 to A; +endinstance; +endmsc; Added: trunk/tests/diff/spec09.mpr =================================================================== --- trunk/tests/diff/spec09.mpr (rev 0) +++ trunk/tests/diff/spec09.mpr 2011-03-13 20:07:29 UTC (rev 1061) @@ -0,0 +1,18 @@ +msc Flow2; +inst A; +inst B; +A: instance; +out m,0 to B; +out m,1 to B; +in n,2 from B; +in n,3 from B; +out m,4 to B; +endinstance; +B: instance; +in m,0 from A; +in m,1 from A; +out n,2 to A; +out n,3 to A; +in m,4 from A; +endinstance; +endmsc; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |