|
From: <ma...@us...> - 2011-10-09 16:43:09
|
Revision: 1205
http://scstudio.svn.sourceforge.net/scstudio/?rev=1205&view=rev
Author: madzin
Date: 2011-10-09 16:43:02 +0000 (Sun, 09 Oct 2011)
Log Message:
-----------
Modify difference processing in diff algorithm. In this version the algorithm returns in some cases better result. It is hard to say whether it returns minimal diff in any case.
Modified Paths:
--------------
trunk/src/data/msc.h
trunk/src/membership/diff_impl.cpp
trunk/src/membership/membership_base.h
Added Paths:
-----------
trunk/tests/diff/flow07_1.mpr.result2
trunk/tests/diff/flow12_1.mpr.result
trunk/tests/diff/flow12_2.mpr.result
Modified: trunk/src/data/msc.h
===================================================================
--- trunk/src/data/msc.h 2011-10-03 23:00:43 UTC (rev 1204)
+++ trunk/src/data/msc.h 2011-10-09 16:43:02 UTC (rev 1205)
@@ -2011,6 +2011,17 @@
m_successor = successor;
}
+ void remove_successor()
+ {
+ if(m_successor->is_last())
+ m_successor = NULL;
+ else
+ {
+ m_successor = m_successor->m_successor;
+ m_successor->m_predecessor = this;
+ }
+ }
+
void set_predecessor(const StrictEventPtr& predecessor)
{
if(!is_first())
@@ -2022,6 +2033,17 @@
m_predecessor = predecessor.get();
}
+ void remove_predecessor()
+ {
+ if(m_predecessor->is_first())
+ m_predecessor = NULL;
+ else
+ {
+ m_predecessor = m_predecessor->m_predecessor;
+ m_predecessor->m_successor = this;
+ }
+ }
+
int is_first() const
{
return m_predecessor==NULL;
Modified: trunk/src/membership/diff_impl.cpp
===================================================================
--- trunk/src/membership/diff_impl.cpp 2011-10-03 23:00:43 UTC (rev 1204)
+++ trunk/src/membership/diff_impl.cpp 2011-10-09 16:43:02 UTC (rev 1205)
@@ -19,11 +19,11 @@
void process_diffrences(MembershipContext* c, BMscPtr dup_flow, const std::map<std::wstring, Difference*>& diff_map,
std::set<MscMessagePtr>& added_messages, std::set<MscMessagePtr>& removed_messages);
-bool check_attributes(MembershipContext* c, BMscPtr specification, BMscPtr dup_flow);
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);
+void diff_identification_settings2(MembershipContext* c, const std::map<std::wstring, Difference*>& diff_map, std::set<Difference*> unmatched_diff);
InstancePtr find_instance(BMscPtr bmsc, std::wstring name);
void separate_diffrences(MembershipContext* c,
const std::map<std::wstring, Difference*>& diff_map,
@@ -47,7 +47,7 @@
while(st != NULL)
{
- std::wcerr << st->get_message()->get_label() << L" id: " << st->get_attribute("identification", -3, setting) << L" ";
+ std::wcerr << st->get_message()->get_label() << " " << st << L" id: " << st->get_attribute("identification", -3, setting) << L" ";
std::wcerr << L" removed: " << (st->get_marked()==REMOVED) << std::endl;
st = st->get_successor();
}
@@ -143,17 +143,8 @@
row++;
-// 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();
-
- //the algorithm skips REMOVED events in attributes checking part
- while(event_a != NULL && event_a->get_marked() == REMOVED)
- {
- event_a = event_a->get_successor();
- }
}
int lower, upper;
@@ -267,10 +258,6 @@
for (int i = 0; i < row-1; i++)
{
location = location->get_successor();
-
-//TODO check this
- if(location->get_marked() == REMOVED)
- i--;
}
if(row <= 0)
location = NULL;
@@ -323,9 +310,6 @@
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());
-
event_a = event_a->get_successor();
event_b = event_b->get_successor();
row++;
@@ -387,12 +371,11 @@
if(compare_events(original_event, (*discover)->getLocation().get(), false))
{
- //function returns bool value: true in case the proper event has been found
- // false in case the proper event has not been found
StrictEventPtr new_location = search_predecessors_successors(*discover, original_event);
if(new_location != NULL)
{
+ //modify difference to matching event
(*discover)->setLocation(new_location);
matched_differences.insert(*un_it);
matched_differences.insert(*discover);
@@ -400,6 +383,14 @@
}
}
}
+
+ //remove matched differences from unmatched_differences
+ std::set<Difference*>::iterator matched_it;
+ for(matched_it = matched_differences.begin(); matched_it != matched_differences.end(); matched_it++)
+ {
+(*matched_it)->getLocation()->set_marked(REMOVED);
+ unmatched_differences.erase(*matched_it);
+ }
}
/**
@@ -418,7 +409,7 @@
* 2. wrong ordering: one event of the message is in proper place but the other is in wrong ordering
* on instance. Remove diffrence is supposed to be paired with add diffrence.
*/
-void diff_identification_preprocessing(MembershipContext* c,
+std::set<Difference*> diff_identification_preprocessing(MembershipContext* c,
std::map<std::wstring, Difference*>& diff_map)
{
//diffrences which operation is add, separated by instances
@@ -444,8 +435,11 @@
CompleteMessagePtr msg = boost::dynamic_pointer_cast<CompleteMessage> ((*list_it)->getMessage());
if(msg == NULL)
+{
//in case the message is incomplete, there is no pair
+(*list_it)->getLocation()->set_marked(REMOVED);
continue;
+}
else
{
//in case the message is complete
@@ -462,7 +456,10 @@
//for advanced remove diffrences matching is it irelevant, because when there is not matching difference it means that one event was on right place (remove_insert exmaple).
if(matching_it == remove_map.end())
+ {
+ unmatched_differences.insert(*list_it);
continue;
+ }
std::list<Difference*>::reverse_iterator matching_list_it;
@@ -474,7 +471,11 @@
}
if(matching_list_it != matching_it->second.rend())
+ {
+(*matching_list_it)->getLocation()->set_marked(REMOVED);
+(*list_it)->getLocation()->set_marked(REMOVED);
continue;
+ }
else
unmatched_differences.insert(*list_it);
}
@@ -483,13 +484,19 @@
//at this moment all candidates for advanced matching are in unmatched_differences
preprocessing_advanced_matching(unmatched_differences);
+ //TODO in identification settings I need to solve unmatched_differences
+ //at this moment I have got all unmatched remove deiffrences in unmatched_differences
+ //think about if I can marked messages as removed when the matching difference of the remove difference is insert/add
+ //NIE pretoze by sa mi rozhodili identifikatory ak by som pridaval identifikatory ako v metode identification_settings2
+
+ return unmatched_differences;
}
/**
* Because of previous computation does not return the minimal diagrams diff, some
* added messages is now supposed to be deleted.
*/
-void remove_added_message(MscMessagePtr msg)
+void remove_added_message(MembershipContext* c, MscMessagePtr msg)
{
CompleteMessagePtr com_msg = boost::dynamic_pointer_cast<CompleteMessage> (msg);
StrictEventPtr s_e, r_e;
@@ -507,30 +514,36 @@
else
//sets NULL as a predecessor of the successor
s_e->get_successor()->set_predecessor(NULL);
+
+ c->remove_attributed_event(s_e.get());
}
else
{
s_e = dynamic_cast<StrictEvent*>(com_msg->get_send_event());
r_e = dynamic_cast<StrictEvent*>(com_msg->get_receive_event());
- if(s_e || r_e)
+ if(s_e == NULL || r_e == NULL)
throw std::runtime_error("Error: unexpected behaviour");
+ //IT can not occure NULL pointer exception because some other message has to be present in the area
//remove send event
if(s_e->get_predecessor() != NULL)
- //remove event (to predecessor sets event's successor as successor)
- s_e->get_predecessor()->set_successor(s_e->get_successor());
+ //remove event (call remove_successor from the predecessor)
+ s_e->get_predecessor()->remove_successor();
else
//sets NULL as a predecessor of the successor
- s_e->get_successor()->set_predecessor(NULL);
+ s_e->get_successor()->remove_predecessor();
//remove receive event
if(r_e->get_predecessor() != NULL)
//remove event (to predecessor sets event's successor as successor)
- r_e->get_predecessor()->set_successor(r_e->get_successor());
+ r_e->get_predecessor()->remove_successor();
else
//sets NULL as a predecessor of the successor
- r_e->get_successor()->set_predecessor(NULL);
+ r_e->get_successor()->remove_predecessor();
+
+ c->remove_attributed_event(s_e.get());
+ c->remove_attributed_event(r_e.get());
}
}
@@ -542,7 +555,7 @@
{
CompleteMessagePtr com_msg = boost::dynamic_pointer_cast<CompleteMessage> (msg);
- if(com_msg == NULL)
+ if(com_msg != NULL)
{
com_msg->get_send_event()->set_marked(NONE);
com_msg->get_receive_event()->set_marked(NONE);
@@ -561,7 +574,8 @@
* Function process incomplete messages. In case the same incomplete message is added and removed in the same
* place, the function removes added message and unmarked removed message.
*/
-void post_processing_incomplete_msg(IncompleteMessagePtr in_msg, std::set<MscMessagePtr>& removed_messages)
+void post_processing_incomplete_msg(MembershipContext* c, IncompleteMessagePtr in_msg,
+ std::set<MscMessagePtr>& removed_messages)
{
std::set<MscMessagePtr>::iterator removed_it;
StrictEventPtr neighbor, event;
@@ -574,43 +588,117 @@
//get successor of the event
neighbor = event->get_successor();
- //neighbor and event has to be same because of the function precess only same messages
- if(neighbor != NULL && compare_events(event.get(), neighbor.get(), false))
+ //searched event is not neccessary the first successor
+ while(neighbor != NULL)
{
removed_it = removed_messages.find(neighbor->get_message());
if(removed_it != removed_messages.end())
{
- //the messages of the parameters was taken from added_messages
- remove_added_message(in_msg);
- reconstruct_removed_message(*removed_it);
+ //neighbor and event has to be same because of the function precess only same messages
+ if(compare_events(event.get(), neighbor.get(), false))
+ {
+ //the messages of the parameters was taken from added_messages
+ remove_added_message(c, in_msg);
+ reconstruct_removed_message(*removed_it);
- //one message can be removed only once
- return ;
+ //one message can be removed only once
+ return ;
+ }
}
+ else
+ //in case the successor is not removed no other event could be matching event
+ break;
+
+ //look at a next successor
+ neighbor = neighbor->get_successor();
}
+//TODO code for predecessor and successor was copied with small diffrences
//get predecessor of the event
neighbor = event->get_predecessor();
- if(neighbor != NULL && compare_events(event.get(), neighbor.get(), false))
+ //searched event is not neccessary the first predecessor
+ while(neighbor != NULL)
{
removed_it = removed_messages.find(neighbor->get_message());
-
+
if(removed_it != removed_messages.end())
{
- //the messages of the parameters was taken from added_messages
- remove_added_message(in_msg);
- reconstruct_removed_message(*removed_it);
+ //neighbor and event has to be same because of the function precess only same messages
+ if(compare_events(event.get(), neighbor.get(), false))
+ {
+ //the messages of the parameters was taken from added_messages
+ remove_added_message(c, in_msg);
+ reconstruct_removed_message(*removed_it);
+
+ //one message can be removed only once
+ return ;
+ }
}
+ else
+ //in case the successor is not removed no other event could be matching event
+ break;
+
+ //look at a next successor
+ neighbor = neighbor->get_predecessor();
}
}
+//musim skontrolovat ci medzi removed receive a added receive su vsetky eventy removed
+bool can_reconstruct_message(StrictEventPtr added_send, MscMessagePtr removed_msg)
+{
+ CompleteMessagePtr msg = boost::dynamic_pointer_cast<CompleteMessage> (added_send->get_message());
+ StrictEventPtr added_receive = dynamic_cast<StrictEvent*> (msg->get_receive_event());
+
+ msg = boost::dynamic_pointer_cast<CompleteMessage> (removed_msg);
+ StrictEventPtr removed_receive = dynamic_cast<StrictEvent*> (msg->get_receive_event());
+
+ if(added_receive == NULL || removed_receive == NULL)
+ throw std::runtime_error("Error: unexpected behaviour");
+
+ //look at successors
+ StrictEventPtr neighbor = removed_receive->get_successor();
+
+ while(neighbor != NULL)
+ {
+ if(added_receive == neighbor)
+ return true;
+ else
+ {
+ if(neighbor->get_marked() != REMOVED)
+ break;
+ }
+
+ neighbor = neighbor->get_successor();
+ }
+
+ //TODO znovu skopceny kod pre predchodcu
+ //look at predecessors
+ neighbor = removed_receive->get_predecessor();
+
+ while(neighbor != NULL)
+ {
+ if(added_receive == neighbor)
+ return true;
+ else
+ {
+ if(neighbor->get_marked() != REMOVED)
+ break;
+ }
+
+ neighbor = neighbor->get_predecessor();
+ }
+
+ return false;
+}
+
/**
* Function process complete messages. In case the same complete message is added and removed in the same
* place, the function removes added message and unmarked removed message.
*/
-void post_processing_complete_msg(CompleteMessagePtr com_msg, std::set<MscMessagePtr>& removed_messages)
+void post_processing_complete_msg(MembershipContext* c, CompleteMessagePtr com_msg,
+ std::set<MscMessagePtr>& removed_messages)
{
std::set<MscMessagePtr>::iterator removed_it;
StrictEventPtr s_neighbor, r_neighbor, s_e, r_e;
@@ -621,40 +709,70 @@
if(s_e == NULL || r_e == NULL)
throw std::runtime_error("Error: unexpected behaviour");
+//musim urobit take kolecko, od sendu sa pozriem po succesoroch a potom od mozneho receivu musim prehladat jak successorov tak predecesorov a najst dany event.
+//take iste kolecko musim urobit pri prehladavami predecesorov
+
//check successor
s_neighbor = s_e->get_successor();
- r_neighbor = r_e->get_successor();
- //not neccessary to compare receive events because of the same messages
- if(s_neighbor != NULL && r_neighbor != NULL && s_neighbor->get_message() == r_neighbor->get_message()
- && compare_events(s_e.get(), s_neighbor.get(), false))
+ while(s_neighbor != NULL)
{
+ //look among removed
removed_it = removed_messages.find(s_neighbor->get_message());
-
+
if(removed_it != removed_messages.end())
{
- //the messages of the parameters was taken from added_messages
- remove_added_message(com_msg);
- reconstruct_removed_message(*removed_it);
+ //in case we think about the reconstruction, events have to be same,
+ //otherwise look at a next successor
+ if(compare_events(s_e.get(), s_neighbor.get(), false))
+ {
+ //must look at the receive event
+ //in case the message could not be reconstructed, look at a next successor
+ if(can_reconstruct_message(s_e, *removed_it))
+ {
+ //the messages of the parameters was taken from added_messages
+ remove_added_message(c, com_msg);
+ reconstruct_removed_message(*removed_it);
+
+ //each message could be reconstructed only once
+ return ;
+ }
+ }
}
+ else
+ break;
+
+ s_neighbor = s_neighbor->get_successor();
}
//check predecessor
s_neighbor = s_e->get_predecessor();
- r_neighbor = r_e->get_predecessor();
- //not neccessary to compare receive events because of the same messages
- if(s_neighbor != NULL && r_neighbor != NULL && s_neighbor->get_message() == r_neighbor->get_message()
- && compare_events(s_e.get(), s_neighbor.get(), false))
+ while(s_neighbor != NULL)
{
+ //look among removed
removed_it = removed_messages.find(s_neighbor->get_message());
if(removed_it != removed_messages.end())
{
- //the messages of the parameters was taken from added_messages
- remove_added_message(com_msg);
- reconstruct_removed_message(*removed_it);
+ //in case we think about the reconstruction, events have to be same,
+ //otherwise look at a next successor
+ if(compare_events(s_e.get(), s_neighbor.get(), false))
+ {
+ //must look at the receive event
+ //in case the message could not be reconstructed, look at a next successor
+ if(can_reconstruct_message(s_e, *removed_it))
+ {
+ //the messages of the parameters was taken from added_messages
+ remove_added_message(c, com_msg);
+ reconstruct_removed_message(*removed_it);
+ }
+ }
}
+ else
+ break;
+
+ s_neighbor = s_neighbor->get_predecessor();
}
}
@@ -664,7 +782,8 @@
* into the same place. If it found message which was removed and added it deletes the add message and
* deletes the marking of the removed message.
*/
-void post_processing(std::set<MscMessagePtr>& added_messages, std::set<MscMessagePtr>& removed_messages)
+void post_processing(MembershipContext* c, std::set<MscMessagePtr>& added_messages,
+ std::set<MscMessagePtr>& removed_messages)
{
std::set<MscMessagePtr>::iterator added_it, removed_it;
StrictEventPtr neighbor;
@@ -678,11 +797,11 @@
{
//process incomplete message
IncompleteMessagePtr in_msg = boost::dynamic_pointer_cast<IncompleteMessage> (*added_it);
- post_processing_incomplete_msg(in_msg, removed_messages);
+ post_processing_incomplete_msg(c, in_msg, removed_messages);
}
else
//process complete message
- post_processing_complete_msg(com_msg, removed_messages);
+ post_processing_complete_msg(c, com_msg, removed_messages);
}
}
@@ -828,8 +947,10 @@
if(i == 0)
{
- diff_identification_preprocessing(c, diff_map);
- diff_identification_settings(c, diff_map);
+ std::set<Difference*> unmatched_diff = diff_identification_preprocessing(c, diff_map);
+ diff_identification_settings2(c, diff_map, unmatched_diff);
+
+
}
}
@@ -839,7 +960,7 @@
std::set<MscMessagePtr> removed_messages;
process_diffrences(c, dup_flow, diff_map, added_messages, removed_messages);
- post_processing(added_messages, removed_messages);
+ post_processing(c, added_messages, removed_messages);
c->clear_attributed_events();
return dup_flow;
@@ -1073,74 +1194,7 @@
return new_msg;
}
-/**
- * Add new (missing) message to the diagram and remove diffrences from the insert map
- */
-//TODO zabezpecit aby sa diffrence odoberalo aj v metode add_incomplete_message
-Difference* add_complete_message(MembershipContext* c, BMscPtr dup_flow, StrictEventPtr event,
- Difference* matching_diff)
-{
/*
- std::map<std::wstring, std::list<Difference*> >::iterator insert_it;
- InstancePtr matching_inst; // matching instance
-
- //original message which is supposed to be created
- CompleteMessagePtr msg = boost::dynamic_pointer_cast<CompleteMessage> (diff->getMessage());
-
- if(diff->getDirection() == SEND)
- matching_inst = msg->get_receiver();
- else
- matching_inst = msg->get_sender();
-
- insert_it = insert_map.find(matching_inst->get_label());
-
- if(insert_it == insert_map.end())
- return diff;
-
- std::list<Difference*>::reverse_iterator list_it;
-
- for(list_it = insert_it->second.rbegin(); list_it != insert_it->second.rend(); list_it++)
- {
- if(*list_it == NULL)
- {
- throw std::runtime_error("Something wrong ");
- continue;
- }
-
- if((*list_it)->getMessage() == msg)
- break;
- }
-
- if(list_it == insert_it->second.rend())
- return diff;
-
- CompleteMessagePtr new_msg = create_complete_message(dup_flow, diff, *list_it);
-
- set_identification(c, new_msg->get_send_event(), msg->get_send_event());
- set_identification(c, new_msg->get_receive_event(), msg->get_receive_event());
-
- //remove matching diffrence from the insert map
- insert_it->second.remove(*list_it);
-
- //remove diffrence from the insert map
- std::wstring diff_instance;
-
- if(diff->getDirection() == SEND)
- diff_instance = msg->get_sender()->get_label();
- else
- diff_instance = msg->get_receiver()->get_label();
-
- insert_it = insert_map.find(diff_instance);
-
- if(insert_it == insert_map.end())
- throw std::runtime_error("Error: unexpected behaviour");
-
- insert_it->second.remove(diff);
-*/
- return NULL;
-}
-
-/*
* process diffrences which operation is ADD
*
* the function travers insert map and creates events for all diffrences. It is
@@ -1403,9 +1457,8 @@
if(compare_events(original_event, (*discover)->getLocation().get(), false))
{
- //function returns bool value: true in case the proper event has been found
- // false in case the proper event has not been found
- if(search_predecessors_successors(*discover, original_event))
+
+ if(search_predecessors_successors(*discover, original_event) != NULL)
{
matched_differences.insert(*removes_it);
matched_differences.insert(*discover);
@@ -1569,7 +1622,7 @@
//process advanced matching of "remove" differences
if(!unmatched_remove.empty())
advanced_remove_matching(unmatched_remove, removed_messages);
-
+
if(!unmatched_remove.empty() || !unmatched_insert.empty())
{
//in case the ordering is wrong, this situation creates one remove difference and
@@ -1578,112 +1631,6 @@
}
}
-bool check_attributes(MembershipContext* c, BMscPtr specification, BMscPtr dup_flow)
-{
- std::map<std::wstring, Difference*> diff_map;
-
- InstancePtrList spec_insts = specification->get_instances();
- InstancePtrList flow_insts = dup_flow->get_instances();
- InstancePtrList::iterator flow_it;
- InstancePtrList::iterator spec_it;
- bool found = false;
-
- c->set_diff_type(ATTRIBUTE);
-
- //TODO prerobit ako pri prvej kontrole all_instances
- for(spec_it = spec_insts.begin(); spec_it != spec_insts.end(); spec_it++)
- {
- for(flow_it = flow_insts.begin(); flow_it != flow_insts.end(); flow_it++)
- {
- if((*flow_it)->get_label() == (*spec_it)->get_label())
- {
- Difference* diff = instance_diff(c, *flow_it, *spec_it);
-
- if(diff != NULL)
- diff_map.insert(std::make_pair((*flow_it)->get_label(), diff));
-
- found = true;
- break;
- }
- }
-
- if(!found)
- throw std::runtime_error("Unexpected behaviour.");
- }
-
- //process_diffrences
-// if(!diff_map.empty())
-// process_diffrences(c, dup_flow, diff_map);
-/*
- {
-//TODO much of the following code was copied from proccess diffrences
- std::map<std::wstring, std::list<Difference*> > insert_map;
- std::map<std::wstring, std::list<Difference*> > remove_map;
-
- separate_diffrences(c, diff_map, insert_map, remove_map);
-
- std::map<std::wstring, std::list<Difference*> >::iterator ins_map_it;
-
- for (ins_map_it = insert_map.begin(); ins_map_it != insert_map.end(); ins_map_it++)
- {
- std::list<Difference*> insert_list = ins_map_it->second;
- std::list<Difference*>::iterator ins_list_it;
-
- for (ins_list_it = insert_list.begin(); ins_list_it != insert_list.end(); ins_list_it++)
- {
- MscMessagePtr message = (*ins_list_it)->getMessage();
- CompleteMessagePtr com_msg = boost::dynamic_pointer_cast<CompleteMessage> (message);
-
- if (com_msg == NULL)
- throw std::runtime_error("Unexpected behaviour.");
-
- std::wstring match_inst;
- std::wstring inst;
-
- if((*ins_list_it)->getDirection() == SEND)
- {
- inst = com_msg->get_sender()->get_label();
- match_inst = com_msg->get_receiver()->get_label();
- }
- else
- {
- match_inst = com_msg->get_sender()->get_label();
- inst = com_msg->get_receiver()->get_label();
- }
-
- MscMessagePtr m = (*ins_list_it)->getMessage();
- CompleteMessagePtr commplete = boost::dynamic_pointer_cast<CompleteMessage>(m);
- EventPtr e = commplete->get_send_event();
- Event* match_e = find_event_on_instance_by_id(c, match_inst, (*ins_list_it)->getAttribute());
-
- StrictEvent* match_se = dynamic_cast<StrictEvent*>(match_e);
-
- if(match_se == NULL)
- throw std::runtime_error("Unexpected behaviour.");
-
- StrictEventPtr new_match_e = new StrictEvent();
- set_event_position(new_match_e, match_se, match_inst, dup_flow);
-
- new_match_e->set_area(match_se->get_area());
- new_match_e->set_marked(ADDED);
-
- match_se->set_successor(new_match_e);
-
- StrictEventPtr new_e = create_event(dup_flow, *ins_list_it, inst);
-
- CompleteMessagePtr new_msg = new CompleteMessage((*ins_list_it)->getMessage()->get_label());
- new_msg->set_marked(ADDED);
-
- new_msg->glue_events(new_match_e, new_e);
- }
- }
-//-------------------------------------------------------------------
- return true;
- }
-*/
- return false;
-}
-
bool event_comparison(MembershipContext* c, StrictEventPtr& event_a, StrictEventPtr event_b)
{
if(c->get_diff_type() == MESSAGE)
@@ -1776,6 +1723,106 @@
}
}
+std::map<EventPtr, Difference*> get_removed_diff(const std::set<Difference*>& unmatched_diff)
+{
+ std::set<Difference*>::const_iterator un_it;
+ std::map<EventPtr, Difference*> un_remove;
+
+ for(un_it = unmatched_diff.begin(); un_it != unmatched_diff.end(); un_it++)
+ {
+ if((*un_it)->getOperation() == REMOVE)
+ un_remove.insert(std::make_pair((*un_it)->getLocation(), *un_it));
+ }
+
+ return un_remove;
+}
+
+//this implementation is only a test
+void diff_identification_settings2(MembershipContext* c, const std::map<std::wstring, Difference*>& diff_map,
+ std::set<Difference*> unmatched_diff)
+{
+ InstancePtr spec_inst, flow_inst;
+ StrictEventPtr spec_e, flow_e;
+ std::list<Difference*> insert_list;
+
+ //diffrences which operation is add, separated by instances
+ std::map<std::wstring, std::list<Difference*> > insert_map;
+ //diffrences which operation is remove, separated by instances
+ std::map<std::wstring, std::list<Difference*> > remove_map;
+
+ std::map<std::wstring, std::list<Difference*> >::iterator insert_map_it;
+
+ //TODO in case this way will works fine the separation can be done in the method which call this method
+ separate_diffrences(c, diff_map, insert_map, remove_map);
+
+ //get unmatched diff which are supposed to be removed
+ std::map<EventPtr, Difference*> r_unmatched_diff = get_removed_diff(unmatched_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++)
+ {
+ insert_map_it = insert_map.find((*instances_it)->get_label());
+
+ if(insert_map_it != insert_map.end())
+ insert_list = insert_map_it->second;
+
+ 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::list<Difference*>::reverse_iterator list_it = insert_list.rbegin();
+
+ std::vector<Difference*> insert_diff;
+ insert_diff.insert(insert_diff.begin(), insert_list.begin(), insert_list.end());
+ std::vector<Difference*>::reverse_iterator vec_it = insert_diff.rbegin();
+
+ while(spec_e != NULL && flow_e != NULL)
+ {
+ if(flow_e->get_marked() == REMOVED || r_unmatched_diff.find(flow_e) != r_unmatched_diff.end())
+ {
+ flow_e->set_marked(NONE);
+ flow_e = flow_e->get_successor();
+ continue;
+ }
+ else
+ {
+ //NULL moze byt ked je insert event ako prvy na instancii
+ if(vec_it != insert_diff.rend() &&
+ ((*vec_it)->getLocation() == NULL || (*vec_it)->getLocation() == flow_e->get_predecessor()))
+ {
+ spec_e = spec_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();
+ }
+ }
+}
+
+
void diff_identification_settings(MembershipContext* c, const std::map<std::wstring, Difference*>& diff_map)
{
std::map<std::wstring, Difference*>::const_iterator map_it;
@@ -1835,8 +1882,7 @@
{
//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()))
+ if(vec_it + 1 == inst_diff.rend() || (*(vec_it+1))->getLocation() != (*vec_it)->getLocation())
{
flow_e = flow_e->get_successor();
vec_it++;
Modified: trunk/src/membership/membership_base.h
===================================================================
--- trunk/src/membership/membership_base.h 2011-10-03 23:00:43 UTC (rev 1204)
+++ trunk/src/membership/membership_base.h 2011-10-09 16:43:02 UTC (rev 1205)
@@ -264,7 +264,7 @@
ReferenceNodePtr processed_ref_node; //! currently processed reference node
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
+ std::set<Event*> attributed_events; //! events with attribute
std::map<ReferenceNodePtr, std::set<ConfigurationPtr> > checked_conf; //! map of reference nodes and configurations which were checked
std::map<TimeRelationRefNodePtr, ConfigurationPtr> top_time_references; //! the start of time interval is connected on top
std::map<TimeRelationRefNodePtr, ConfigurationPtr> bottom_time_references; //! the start of time interval is connected on bottom
@@ -400,7 +400,7 @@
snapshots[cor] = snap;
}
- const std::vector<Event*> get_attributed_events() const
+ const std::set<Event*> get_attributed_events() const
{
return attributed_events;
}
@@ -408,14 +408,21 @@
//! add event to #attributed_events
void add_attributed_event(Event* e)
{
- attributed_events.push_back(e);
+ attributed_events.insert(e);
}
+ void remove_attributed_event(Event* e)
+ {
+ if(attributed_events.erase(e))
+ e->remove_attribute<int>("identification");
+ }
+
//! removes event attribute "indentification" and clear #attributed_events
void clear_attributed_events()
{
- for(unsigned int i = 0; i < attributed_events.size(); i++)
- attributed_events[i]->remove_attribute<int>("identification");
+ std::set<Event*>::iterator it;
+ for(it = attributed_events.begin(); it != attributed_events.end(); it++)
+ (*it)->remove_attribute<int>("identification");
attributed_events.clear();
}
Added: trunk/tests/diff/flow07_1.mpr.result2
===================================================================
--- trunk/tests/diff/flow07_1.mpr.result2 (rev 0)
+++ trunk/tests/diff/flow07_1.mpr.result2 2011-10-09 16:43:02 UTC (rev 1205)
@@ -0,0 +1,19 @@
+OK: HMSC contains bMSC
+
+mscdocument msc_diff;
+msc Page_1;
+inst A;
+inst B;
+A: instance;
+/* REMOVED */
+/* REMOVED */
+out a,0 to B;
+out a,1 to B;
+endinstance;
+B: instance;
+in a,1 from A;
+/* REMOVED */
+/* REMOVED */
+in a,0 from A;
+endinstance;
+endmsc;
Added: trunk/tests/diff/flow12_1.mpr.result
===================================================================
--- trunk/tests/diff/flow12_1.mpr.result (rev 0)
+++ trunk/tests/diff/flow12_1.mpr.result 2011-10-09 16:43:02 UTC (rev 1205)
@@ -0,0 +1,21 @@
+OK: HMSC contains bMSC
+
+mscdocument msc_diff;
+msc Page_1;
+inst A;
+inst B;
+A: instance;
+out a,0 to B;
+out a,1 to B;
+/* REMOVED */
+/* REMOVED */
+out a,2 to B;
+endinstance;
+B: instance;
+/* REMOVED */
+/* REMOVED */
+in a,2 from A;
+in a,0 from A;
+in a,1 from A;
+endinstance;
+endmsc;
Added: trunk/tests/diff/flow12_2.mpr.result
===================================================================
--- trunk/tests/diff/flow12_2.mpr.result (rev 0)
+++ trunk/tests/diff/flow12_2.mpr.result 2011-10-09 16:43:02 UTC (rev 1205)
@@ -0,0 +1,21 @@
+OK: HMSC contains bMSC
+
+mscdocument msc_diff;
+msc Page_1;
+inst A;
+inst B;
+A: instance;
+/* REMOVED */
+/* REMOVED */
+out a,0 to B;
+out a,1 to B;
+out a,2 to B;
+endinstance;
+B: instance;
+in a,1 from A;
+in a,2 from A;
+/* REMOVED */
+/* REMOVED */
+in a,0 from A;
+endinstance;
+endmsc;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|