mp2.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. /*
  2. * mp2.h
  3. *
  4. * Created by Mike Auguston on 2/2/15.
  5. * recursive descent trace generation
  6. * common declarations and globals
  7. *
  8. * last modified: 03/26/15
  9. */
  10. #include <iostream>
  11. #include <fstream>
  12. #include <cstdlib>
  13. #include <ctime>
  14. #include <vector>
  15. #include <map>
  16. #include <set>
  17. //#include <algorithm>
  18. using namespace std;
  19. //************************
  20. //***** Statistics
  21. //************************
  22. double storage = 0; // memory for composite segments
  23. int total_events = 0; // total events stored
  24. clock_t gen_start,gen_end; // for time measurement
  25. double dif; // for time interval
  26. //************************
  27. //***** Globals
  28. //************************
  29. ofstream JSON; // text file for trace visualization
  30. class Event_producer;
  31. class Composite_producer;
  32. typedef Event_producer * Event_producer_ref;
  33. typedef Composite_producer * Composite_producer_ref;
  34. typedef vector <Event_producer_ref> trace_segment;
  35. //***************************************
  36. //*** these are used for traverse() work
  37. //***************************************
  38. trace_segment Stack;
  39. // Stack used by producers for trace segment construction via traverse()
  40. // to maintain relations lists
  41. typedef multimap <int, int> pair_list;
  42. // for storing basic relations IN, FOLLOWS, EQUAL for the segment,
  43. // matricies for segments are build from these when needed
  44. pair_list Follows; // to store FOLLOWS
  45. pair_list Inside; // to store IN
  46. pair_list Equals; // to store Equals (result of MAP or SHARE ALL)
  47. // stack accompanying the Stack
  48. vector <int> predecessor; // to track PRECEDES relation during traverse()
  49. // push/pop performed in Composite_producer
  50. //===========================
  51. // for SET_node traverse()
  52. //--------------------------------------------------
  53. // initialized in Composite_producer, similar to predecessor.back()
  54. // used in SET_node_producer_container
  55. // replace predecessor when traversing Sets
  56. // heads and tails store for each Set a list
  57. // (branch_begin FOLLOWS node) for heads
  58. // (forthcoming_node FOLLOWS end-of-branch-event) for tails
  59. // each is a permanent list for Set traverse()
  60. vector<pair_list> heads;
  61. vector<pair_list> tails;
  62. void find_and_copy_heads(int branch_start, int my_index);
  63. void find_and_copy_tails(int first_branch_start, pair_list &destination);
  64. void copy_from_to(int anchor, pair_list &from_list, pair_list &to_list);
  65. void copy_and_adjust_from_to(int anchor, int adjusted_node,
  66. pair_list &from_list, pair_list &to_list);
  67. bool find_in_heads(int node);
  68. //===================================
  69. // composite producers infrastructure
  70. //===================================
  71. void add_relations_for_leader(); // the subroutine for adding relations for
  72. //the leading event in Atomic_producer or Composite_secondary_producer
  73. //********** main list of composite event, root, and schema producers ******
  74. //==========================================================================
  75. map <int, Composite_producer_ref> Composite_address_book;
  76. // for each composite event/root/schema name contains a plain pointer to the
  77. // producer object with the segment list
  78. void show_map(pair_list &x);// for debugging printouts
  79. //****************************
  80. // event producer types
  81. //****************************
  82. enum Event_type {Atom, Composite_producer_node, Composite_event_instance_node,
  83. Composite_secondary_producer_node,
  84. ROOT_node, Schema_node, OR_node, AND_node, SET_node, Empty_node,
  85. Coordinate_op, ShareAll_op };
  86. string event_type_string[] = { "Atom", "Composite_producer_node",
  87. "Composite_event_instance_node",
  88. "Composite_secondary_producer_node",
  89. "ROOT_node", "Schema_node",
  90. "OR_node", "AND_node", "SET_node",
  91. "Empty_node", "Coordinate_op", "ShareAll_op" };
  92. //======= traversal results
  93. enum Traversal_result {failed, success_and_completed, success_and_ready_for_next};
  94. string Traversal_result_string[] = {"failed", "success_and_completed",
  95. "success_and_ready_for_next"};
  96. //**************************************
  97. //========= generic classes ============
  98. //**************************************
  99. //********** Event producers ************
  100. //***************************************
  101. class Event_producer{
  102. public:
  103. int name; // event name
  104. Event_type type;
  105. // constructor
  106. Event_producer(int n){
  107. name = n;
  108. type = Atom; // default
  109. }
  110. virtual Traversal_result traverse()=0; // will be overloaded
  111. virtual void hold(){} // redefined for OR_nodes
  112. virtual void print_event();
  113. };
  114. //--------------------------------------
  115. class Atomic_producer: public Event_producer {
  116. public:
  117. // constructor
  118. Atomic_producer(int n): Event_producer(n){}
  119. Traversal_result traverse(){
  120. // add relations for new event
  121. add_relations_for_leader();
  122. Stack.push_back(this);
  123. return success_and_completed;
  124. }
  125. };// end class Atomic_producer
  126. //-----------------------------------------
  127. // for empty alternatives in Alt and Optional containers
  128. // does not leave anything on the trace
  129. class Empty_producer: public Event_producer {
  130. public:
  131. // constructor
  132. Empty_producer(int n): Event_producer(n){
  133. type = Empty_node;
  134. }
  135. Traversal_result traverse(){
  136. return success_and_completed;
  137. }
  138. };// end class Empty_producer
  139. //-----------------------------------------
  140. class OR_node_producer_container: public Event_producer{
  141. public:
  142. Event_producer_ref * element; // dynamic array of producer elements
  143. int element_count; // length of the element array
  144. int current_alternative; // the alternative to try, when there is one
  145. int previous_alternative; // to hold on the alternative waiting until successors complete
  146. // constructor
  147. OR_node_producer_container(int n): Event_producer(n){
  148. type = OR_node;
  149. current_alternative = 0;
  150. }
  151. Traversal_result traverse(){
  152. previous_alternative = current_alternative;
  153. Traversal_result result;
  154. bool done = false; // to interrupt the for loop when success is reached
  155. // try to find a valid alternative
  156. for(int i = current_alternative; (i< element_count) && !done; i++){
  157. switch(result = (element[i] -> traverse()) ){
  158. case failed: continue; // try next alternative
  159. case success_and_completed: current_alternative++;
  160. done = true;
  161. break;
  162. case success_and_ready_for_next: done = true;
  163. // retain the current_alternative
  164. };
  165. }
  166. if(result == failed) return failed;
  167. return (current_alternative >= element_count)?
  168. (current_alternative = 0, success_and_completed):
  169. success_and_ready_for_next;
  170. }
  171. void hold(){ //follower in an AND_node may hold advance to the next alternative
  172. // because the follower has not yet completed
  173. current_alternative = previous_alternative;
  174. // freez producers in the alternative that will be executed next
  175. element[current_alternative]->hold();
  176. }
  177. }; // end OR_node_producer_container class
  178. //-----------------------------------------------------------
  179. class AND_node_producer_container: public Event_producer{
  180. // serves sequence producers
  181. public:
  182. Event_producer_ref * element; // array of producer elements
  183. int element_count; // length of the element array
  184. Event_type target_event;// set in the generated subclass constructor
  185. int completeness_count; // for harvest() to detect when no more options remain
  186. // constructor
  187. AND_node_producer_container(int n): Event_producer(n){
  188. type = target_event = AND_node;
  189. }
  190. Traversal_result traverse(){
  191. completeness_count = 0;
  192. for(int i =0; i< element_count; i++){
  193. if(target_event == Schema_node) {
  194. // before element[i] -> traverse()
  195. predecessor.back() = -1; // block regular ordering
  196. }
  197. switch(element[i] -> traverse()){
  198. case failed: if(completeness_count == i)
  199. // there are no more options to try
  200. // let harvest() to stop calling this traverse() again
  201. completeness_count = element_count;
  202. return failed;
  203. case success_and_completed: completeness_count++;
  204. break;
  205. case success_and_ready_for_next:
  206. // hold all previous OR_nodes until element[i] completes
  207. for(int j = 0; j<i; j++)
  208. element[j]->hold();
  209. };
  210. }
  211. return (completeness_count == element_count)? success_and_completed:
  212. success_and_ready_for_next;
  213. }
  214. void hold(){
  215. // hold all nodes until next element completes
  216. for(int j = 0; j < element_count; j++){
  217. element[j]->hold();
  218. }
  219. }
  220. }; // end AND_node_producer_container class
  221. //----------------------------------------------------------------------
  222. class SET_node_producer_container: public Event_producer{
  223. // serves set producers
  224. public:
  225. Event_producer_ref * element; // array of producer elements
  226. // set branches
  227. int element_count; // length of the element array
  228. // constructor
  229. SET_node_producer_container(int n): Event_producer(n){
  230. type = SET_node;
  231. }
  232. Traversal_result traverse(){
  233. int completeness_count = 0;
  234. //========= begin Set traversal ================
  235. // prepare heads for set branch traversal
  236. //==============================================
  237. int last = predecessor.back(); // current predecessor, value stored on the top of stack
  238. int first_branch_start = Stack.size();
  239. pair_list temp_list; // needed to push empty map to heads,
  240. // and to store this Set's tails before moving them to global tails
  241. set<int> my_tails; // will use in this traverse() and store in tails at the very end
  242. int my_index = heads.size(); // position in heads vector
  243. heads.push_back(temp_list); // start heads[my_index] with empty, will update in situ
  244. // prepare heads for the first branch
  245. if(last >= 0){
  246. // this Set is not at any branch begin in a parent Set
  247. heads[my_index].insert(pair<int, int>(first_branch_start, last) );
  248. }
  249. // find the earliest parent and copy to heads[my_index] for this branch
  250. // this Set is at some branch beginning with a parent Set
  251. find_and_copy_heads(first_branch_start, my_index);
  252. // if first_branch_start is found in any previous Set tails, copy it to heads[my_index]
  253. find_and_copy_tails(first_branch_start, heads[my_index]);
  254. //============================
  255. // main loop starts here
  256. //============================
  257. for(int i =0; i< element_count; i++){
  258. //=================================
  259. // before element[i] -> traverse()
  260. //=================================
  261. predecessor.back() = -1; // block regular ordering
  262. int forthcoming_event = Stack.size();
  263. if(forthcoming_event > first_branch_start){
  264. // not the first branch beginning, copy and adjust
  265. copy_and_adjust_from_to(first_branch_start, forthcoming_event,
  266. heads[my_index], heads[my_index]);
  267. }
  268. // copy tails from children Set and delete them, to prevent siblings from using it
  269. for(int k = 0; k < tails.size(); k++){
  270. multimap<int, int>:: iterator p = tails[k].find(forthcoming_event);
  271. multimap<int, int>:: iterator q = tails[k].upper_bound(forthcoming_event);
  272. if(p != tails[k].end()){ // found a tail that should be added to my_tails
  273. while(p != q) {
  274. my_tails.insert(p->second);
  275. p++;
  276. }
  277. tails[k].clear();// done with this Set
  278. }
  279. }
  280. //===============
  281. // traverse()
  282. //===============
  283. switch(element[i] -> traverse()){
  284. case failed: return failed;
  285. case success_and_completed: completeness_count++;
  286. break;
  287. case success_and_ready_for_next:
  288. // hold all previous OR_nodes until element[i] completes
  289. for(int j = 0; j<i; j++)
  290. element[j]->hold();
  291. }
  292. //===============================
  293. // after element[i] -> traverse()
  294. //===============================
  295. int next_event = Stack.size();
  296. if( next_event > forthcoming_event ){
  297. // there was a non-empty contribution by traverse()
  298. // forthcoming_event exists, now can forward heads[my_index]
  299. // for forthcoming_event to Follows
  300. // and perform this delayed action
  301. copy_from_to(forthcoming_event, heads[my_index], Follows);
  302. if(predecessor.back() >= 0){
  303. my_tails.insert(predecessor.back());
  304. }
  305. if(i == element_count - 1){// if the last element, do it now
  306. // copy tails from children Set
  307. for(int k = 0; k < tails.size(); k++){
  308. multimap<int, int>:: iterator p = tails[k].find(next_event);
  309. multimap<int, int>:: iterator q = tails[k].upper_bound(next_event);
  310. if(p != tails[k].end()){ // found a tail that should be added to my_tails
  311. while(p != q) {
  312. my_tails.insert(p->second);
  313. p++;
  314. }
  315. tails[k].clear();// done with this Set
  316. }
  317. }
  318. }
  319. }
  320. // else continue element[i+1] -> traverse() with the same heads and tails
  321. } // end main loop
  322. //============================
  323. // end of Set generation
  324. //============================
  325. // store tails accumulated in my_tails
  326. int next = Stack.size();
  327. for(set<int>:: iterator tt = my_tails.begin(); tt != my_tails.end(); tt++){
  328. temp_list.insert(pair<int, int>(next, *tt) );
  329. }
  330. // finally add to the global tails
  331. tails.push_back(temp_list);
  332. predecessor.back() = -1; // block regular ordering
  333. return (completeness_count == element_count)? success_and_completed:
  334. success_and_ready_for_next;
  335. }
  336. void hold(){
  337. // hold all nodes until next element completes
  338. for(int j = 0; j < element_count; j++){
  339. element[j]->hold();
  340. }
  341. }
  342. }; // end SET_node_producer_container class
  343. //--------------------------------------------------
  344. // this element sits on the generated event trace, along with Atomic_producers
  345. // generated in the Composite_secondary_producer,
  346. // added at the beginning of each segment,
  347. // brought from the Composite_producer segments storage
  348. class Composite_event_instance: public Event_producer{
  349. public:
  350. int index; // fetched segment's index in the segment_storage (version of this composite event)
  351. // constructor
  352. Composite_event_instance(int n, int indx): Event_producer(n){
  353. type = Composite_event_instance_node;
  354. index = indx;
  355. }
  356. void print_event(); // defined in the generated part,
  357. // because it needs event type and name strings
  358. // to prevent this class from being abstract, as Event_producer
  359. Traversal_result traverse(){return success_and_completed;}
  360. }; // end Composite_event_instance class
  361. //---------------------------------------------------------------
  362. // is a subclass of generated Composite classes
  363. // this object creates and stores list of composite event instances
  364. // traverse() is called from its harvest() only
  365. class Composite_producer: public AND_node_producer_container {
  366. public:
  367. // storage for secondary producers
  368. //===================================
  369. vector <trace_segment> segments;// composite event trace instance list
  370. // to store relation lists for the segments
  371. vector <pair_list> follows_lists; // to store FOLLOWS
  372. vector <pair_list> inside_lists; // to store IN
  373. vector <pair_list> equals_lists; // to store Equals (results of MAP or SHARE ALL)
  374. // constructor
  375. Composite_producer(int n): AND_node_producer_container(n){
  376. type = Composite_producer_node;
  377. // posts a reference to itself on the Composite_address_book
  378. Composite_address_book.insert(pair<int, Composite_producer_ref>(name, this));
  379. }
  380. Traversal_result traverse(){
  381. // creates a single trace on the Stack
  382. return this -> AND_node_producer_container::traverse();
  383. }
  384. // calls traverse to fill the segments list
  385. void harvest(); // defined in mp2_print_etc.h
  386. void show_traces(); // defined in mp2_print_etc.h
  387. void output_JSON(); // defined in mp2_print_etc.h
  388. }; // end Composite_producer class
  389. //-------------------------------------------------------
  390. // sits in the recursive descent graph
  391. // used during the recursive descent to traverse composite storage
  392. // and to fetch the next composite segment
  393. // previous_index shows the position of segment added to the trace
  394. class Composite_secondary_producer: public Event_producer{
  395. public:
  396. Composite_producer_ref segment_storage;// ptr to segment info stored in Composite_producer
  397. int index; // segment info index in the segment_storage to fetch now
  398. int previous_index; // for hold() implementation
  399. // constructor
  400. Composite_secondary_producer(int n): Event_producer(n){
  401. type = Composite_secondary_producer_node;
  402. // find segment list storage
  403. map <int, Composite_producer_ref> :: iterator p;
  404. p = Composite_address_book.find(name);
  405. if(p == Composite_address_book.end()){
  406. cout<< "Composite_secondary_producer constructor cannot find segment storage for the\n";
  407. print_event();
  408. segment_storage = NULL;
  409. }
  410. else segment_storage = p-> second;
  411. index = 0;
  412. previous_index = 0;
  413. }
  414. Traversal_result traverse(){
  415. if(!segment_storage) {
  416. // add relations for new event and add it
  417. add_relations_for_leader();
  418. Stack.push_back(new Composite_event_instance(name, 0));
  419. return success_and_completed;
  420. }
  421. // we are going to fetch this segment from the storage
  422. trace_segment * my_segment_ptr = & ((segment_storage->segments)[index]);
  423. // prepare for added segement scanning for relation update
  424. int base = Stack.size(); //master Composite_event_instance event's position in the trace
  425. // base is the position of composite event inside which the segment belongs
  426. // fetch a valid alternative and adjust relation list
  427. add_relations_for_leader();// add IN/PRECEDES for the composite event at the beginning of segment
  428. Stack.insert(Stack.end(), my_segment_ptr->begin(), my_segment_ptr->end() );
  429. // get the relation lists from the storage, adjust them with base,
  430. // and add to Follows, Inside and Equals
  431. multimap <int, int>:: iterator p;
  432. pair_list * my_rel_list_ptr = & ((segment_storage->follows_lists)[index]);
  433. for(p = my_rel_list_ptr-> begin(); p != my_rel_list_ptr-> end(); p++){
  434. // scan the list of pairs and add them to Follows adjusted with base
  435. Follows.insert(pair<int, int>( (p->first) + base,
  436. (p->second) + base ) );
  437. }
  438. my_rel_list_ptr = & ((segment_storage->inside_lists)[index]);
  439. for(p = my_rel_list_ptr-> begin(); p != my_rel_list_ptr-> end(); p++){
  440. // scan the list of pairs and add them to Follows adjusted with base
  441. Inside.insert(pair<int, int>( (p->first) + base,
  442. (p->second) + base ) );
  443. }
  444. my_rel_list_ptr = & ((segment_storage->equals_lists)[index]);
  445. for(p = my_rel_list_ptr-> begin(); p != my_rel_list_ptr-> end(); p++){
  446. // scan the list of pairs and add them to Follows adjusted with base
  447. Equals.insert(pair<int, int>( (p->first) + base,
  448. (p->second) + base ) );
  449. }
  450. previous_index = index;
  451. index++;
  452. return (index >= (segment_storage->segments).size() )?
  453. (index = 0, success_and_completed):
  454. success_and_ready_for_next;
  455. }
  456. void hold(){
  457. //follower in an AND_node may hold advance to the next alternative
  458. // because the follower has not yet completed
  459. index = previous_index;
  460. }
  461. }; // end Composite_secondary_producer class
  462. //---------------------------------------------------------------------------
  463. class Coordinate: public Event_producer {
  464. public:
  465. // these arrays are 2-dimensional,
  466. // and are allocated/deleted in generated traverse()
  467. // by create_matrices() as Stack.size() * Stack.size()
  468. char * eq_matrix;
  469. char * in_matrix;
  470. char * follows_matrix;
  471. int len; // matrix dimension
  472. int matrix_len; // len * len
  473. // constructor
  474. Coordinate(int n): Event_producer(n){
  475. type = Coordinate_op;
  476. eq_matrix = in_matrix = follows_matrix = 0;
  477. len = matrix_len = 0;
  478. }
  479. // transitive closures are based on Floyd-Warshall algorithm
  480. // [Cormen et al. 3rd Edition, pp.699]
  481. //--------------------------------------------------------------
  482. void eq_transitive_closure(char * m){
  483. for(int k = 0; k < len; k++){
  484. for(int i = 0; i < len; i++){
  485. for(int j = 0; j < len; j++){
  486. m[i * len + j] =
  487. m[i * len + j] || (m[i * len + k] && m[k * len + j]);
  488. }
  489. }
  490. }
  491. } // end eq_transitive_closure(char * m)
  492. void in_transitive_closure(char * m){
  493. // merge equal event rows
  494. for(int i = 0; i < len; i++){
  495. for(int j = 0; j < len; j++){
  496. if(eq_matrix[i * len + j] && (i != j)){
  497. for(int k = 0; k < len; k++){
  498. m[i * len + k] =
  499. m[j * len + k] =
  500. m[i * len + k] || m[j * len + k];
  501. }
  502. }
  503. }
  504. }
  505. // do the closure
  506. for(int k = 0; k < len; k++){
  507. for(int i = 0; i < len; i++){
  508. for(int j = 0; j < len; j++){
  509. m[i * len + j] =
  510. m[i * len + j] || (m[i * len + k] && m[k * len + j]);
  511. }
  512. }
  513. }
  514. // check for loops: axioms 5-6
  515. for(int i = 0; i < len; i++){
  516. if(m[i * len + i]) throw failed;
  517. }
  518. } // end in_transitive_closure(char * m)
  519. void fw_transitive_closure(char * m){
  520. // merge equal event rows
  521. for(int i = 0; i < len; i++){
  522. for(int j = 0; j < len; j++){
  523. if(eq_matrix[i * len + j] && (i != j)){
  524. for(int k = 0; k < len; k++){
  525. m[i * len + k] =
  526. m[j * len + k] =
  527. m[i * len + k] || m[j * len + k];
  528. }
  529. }
  530. }
  531. }
  532. // propagate FOLLOWS to the inner events
  533. for(int i = 0; i < len; i++){
  534. for(int j = 0; j < len; j++){
  535. // distributivity axioms 9-10
  536. if(in_matrix[i * len + j]){
  537. for(int k = 0; k < len; k++){
  538. m[k * len + i] =
  539. m[k * len + i] || m[k * len + j];
  540. }
  541. for(int k = 0; k < len; k++){
  542. m[i * len + k] =
  543. m[i * len + k] || m[j * len + k];
  544. }
  545. }
  546. }
  547. }
  548. // do the closure
  549. for(int k = 0; k < len; k++){
  550. for(int i = 0; i < len; i++){
  551. for(int j = 0; j < len; j++){
  552. m[i * len + j] =
  553. m[i * len + j] || (m[i * len + k] && m[k * len + j]);
  554. }
  555. }
  556. }
  557. // check for loops: axioms 5-6
  558. for(int i = 0; i < len; i++){
  559. if(m[i * len + i]) throw failed;
  560. }
  561. // check for mutual exclusion: axioms 1-4
  562. for(int k = 0; k < len; k++){
  563. for(int i = 0; i < len; i++){
  564. if(in_matrix[k * len + i] &&
  565. follows_matrix[k * len + i]) throw failed;
  566. }
  567. }
  568. } // end fw_transitive_closure(char * m)
  569. void delete_matrices(){
  570. if(in_matrix){
  571. delete [] eq_matrix;
  572. delete [] in_matrix;
  573. delete [] follows_matrix;
  574. eq_matrix = in_matrix = follows_matrix = 0;
  575. }
  576. }
  577. void create_matrices(){
  578. len = Stack.size();
  579. matrix_len = len * len;
  580. // allocate and initialize with 0
  581. eq_matrix = new char [matrix_len];
  582. in_matrix = new char [matrix_len];
  583. follows_matrix = new char [matrix_len];
  584. for(int i = 0; i < matrix_len; i++){
  585. eq_matrix[i] =
  586. in_matrix[i] =
  587. follows_matrix[i] = 0;
  588. }
  589. multimap <int, int>:: iterator p;
  590. // fill eq matrix
  591. for(p = Equals.begin(); p != Equals.end(); p++){
  592. eq_matrix[p->first * len + p->second ] =
  593. eq_matrix[p->second * len + p->first ] = 1;
  594. }
  595. eq_transitive_closure(eq_matrix);
  596. // fill in matrix
  597. for(p = Inside.begin(); p != Inside.end(); p++){
  598. in_matrix[p->first * len + p->second ] = 1;
  599. }
  600. in_transitive_closure(in_matrix);
  601. // fill follows matrix
  602. for(p = Follows.begin(); p != Follows.end(); p++){
  603. follows_matrix[p->first * len + p->second ] = 1;
  604. }
  605. fw_transitive_closure(follows_matrix);
  606. } // end create_matrices()
  607. void sort_events(vector<int> &L){
  608. // sorts vector of events by FOLLOWS
  609. // Selection Sort, Levitin p.99 (OK for small lists)
  610. // since FOLLOWS is partial order, the sort is topological
  611. // although selection sort is not stable
  612. if(L.size() < 2) return;
  613. int min, temp;
  614. for(int i = 0; i < L.size() - 1; i++){
  615. min = i;
  616. for(int j = i + 1; j < L.size(); j++){
  617. if(follows_matrix[L[min] * len + L[j]]){
  618. min = j;
  619. }
  620. }
  621. temp = L[i];
  622. L[i] = L[min];
  623. L[min] = temp;
  624. }
  625. }
  626. void sort_and_check_coordinated_events(vector<int> &L){
  627. // for synchronous COORDINATE
  628. // sorts vector of events by FOLLOWS
  629. // then checks for total ordering
  630. if(L.size() < 2) return;
  631. sort_events(L);
  632. // check total ordering
  633. for(int i = 0; i < L.size() - 1; i++){
  634. if(!follows_matrix[L[i + 1] * len + L[i]]) throw failed;
  635. }
  636. }
  637. void make_equality_complete(int a, int b){
  638. // add to Equals, but earlier position in Stack is more equal :-)
  639. // copies all Follows and Inside from b to a
  640. // and do the same for all inner events
  641. if(a == b) return;
  642. if(Stack[a]->name != Stack[b]->name) throw failed;
  643. if(Stack[a]->type == Composite_event_instance_node &&
  644. Stack[b]->type == Composite_event_instance_node &&
  645. ( ((Composite_event_instance *)Stack[a])->index !=
  646. ((Composite_event_instance *)Stack[b])->index ) )throw failed;
  647. // earlier position in Stack is more equal :-)
  648. if(a > b) {int t = a; a = b; b = t;}
  649. Equals.insert(pair<int, int>(a, b));
  650. // copy all Follows and Inside from b to a
  651. multimap<int, int>:: iterator p;
  652. for(p = Follows.begin(); p != Follows.end(); p++) {
  653. if(p->second == b)
  654. Follows.insert(pair<int, int>(p->first, a));
  655. if(p->first == b)
  656. Follows.insert(pair<int, int>(a, p->second));
  657. }
  658. for(p = Inside.begin(); p != Inside.end(); p++) {
  659. if(p->first == b)
  660. Inside.insert(pair<int, int>(a, p->second));
  661. }
  662. if(Stack[a]->type == Atom) return;
  663. // if composite event, do the same for all inner events
  664. vector<int> a_list, b_list;
  665. p = Inside.begin();
  666. while(p != Inside.end()) {
  667. if(p->second == a) a_list.push_back(p->first);
  668. if(p->second == b) b_list.push_back(p->first);
  669. p++;
  670. }
  671. if(a_list.size() != b_list.size()) throw failed;
  672. sort_events(a_list);
  673. sort_events(b_list);
  674. for(int i = 0; i < a_list.size() && i < b_list.size(); i++){
  675. make_equality_complete(a_list[i], b_list[i]);
  676. }
  677. }// end make_equality_complete()
  678. void print_matrix(char * m){
  679. cout<<" size: "<<len<< " * "<<len<<endl;
  680. cout<< " \t";
  681. for(int k = 0; k < len; k++){
  682. cout<<k<<" \t";
  683. }
  684. for(int i= 0; i < len; i++){
  685. cout<<"\n"<<i<<": \t";
  686. for(int j = 0; j <len; j++){
  687. cout<<(int)m[i * len + j]<<" \t";
  688. }
  689. }
  690. }
  691. void print_matrices(){
  692. cout<<"\n\neq_matrix ";
  693. print_matrix(eq_matrix);
  694. cout<<"\n\nin_matrix ";
  695. print_matrix(in_matrix);
  696. cout<<"\n\nfollows_matrix ";
  697. print_matrix(follows_matrix);
  698. }
  699. // traverse() is defined in the generated subclasses
  700. }; // end Coordinate class
  701. //========== auxiliary subroutines and declarations =========================
  702. inline void add_relations_for_leader(){
  703. // add relations for the event which will be in a moment pushed on the top of Stack
  704. // called from Atomic_producer or Composite_secondary_producer
  705. // when they add to the trace
  706. int myindex = Stack.size(); // index of this event in the segment,
  707. // before the event is actually pushed on the stack
  708. // always inside the master composite of the segment
  709. // will be further adjusted in Composite_secondary_producer traverse()
  710. Inside.insert(pair<int, int>(myindex, 0));
  711. // add PRECEDES according to the position in AND_node_producer_container where it belongs
  712. int last = predecessor.back(); // value stored on the top of stack
  713. if(last >= 0) { // if predecessor is defined
  714. Follows.insert(pair<int, int>(myindex, last) );
  715. }
  716. else{// happens seldom, only inside Set, or at the beginning of Composite
  717. // if heads have this node, do nothing, it will be taken care in Set,
  718. // otherwise, if tails have this node, add it to Follows
  719. if( !find_in_heads(myindex)) find_and_copy_tails(myindex, Follows);
  720. }
  721. predecessor.back() = myindex; // place this event as a previous
  722. }
  723. //---------------------------------------------------------------------------
  724. inline void copy_from_to(int anchor, pair_list &from_list, pair_list &to_list){
  725. // called from SET_node_producer_container.traverse()
  726. multimap<int, int>:: iterator q = from_list.find(anchor);
  727. if(q != from_list.end()){
  728. do {
  729. to_list.insert(pair<int, int>(anchor, q->second) );
  730. q++;
  731. } while ( q != from_list.upper_bound(anchor));
  732. }
  733. }
  734. //----------------------------------------------------------------------------
  735. inline void copy_and_adjust_from_to(int anchor, int adjusted_node,
  736. pair_list &from_list, pair_list &to_list){
  737. // called from SET_node_producer_container.traverse()
  738. multimap<int, int>:: iterator p = from_list.find(anchor);
  739. multimap<int, int>:: iterator q = from_list.upper_bound(anchor);
  740. if(p != from_list.end()) {
  741. set<int> temp;
  742. // collect all predecessors of anchor in from_list
  743. do {
  744. temp.insert( p->second);
  745. p++;
  746. } while ( p != q );
  747. // put them into to_list for adjusted_node
  748. for(set<int>:: iterator tt = temp.begin(); tt != temp.end(); tt++){
  749. to_list.insert(pair<int, int>(adjusted_node, *tt) );
  750. }
  751. }
  752. }
  753. //-----------------------------------------------------------------------------
  754. void find_and_copy_heads(int branch_start, int my_index){
  755. // called from SET_node_producer_container.traverse()
  756. // find the first parent Set that contains branch_start
  757. // and copy all branch_start -> N to heads[my_index]
  758. for(int i = 0; i < my_index; i++){
  759. multimap<int, int>:: iterator p = heads[i].find(branch_start);
  760. multimap<int, int>:: iterator q = heads[i].upper_bound(branch_start);
  761. if(p != heads[i].end()){ // found a parent Set
  762. while(p != q) {
  763. heads[my_index].insert(pair<int, int>(branch_start, p->second) );
  764. p++;
  765. }
  766. return;
  767. }
  768. }
  769. }
  770. //-------------------------------------------------------------------------------
  771. void find_and_copy_tails(int node, pair_list &destination){
  772. // called from SET_node_producer_container.traverse() and add_relations_for_leader()
  773. // if node is found in any previous Set tails, copy it to destination
  774. for(int i = 0; i < tails.size(); i++){
  775. multimap<int, int>:: iterator p = tails[i].find(node);
  776. multimap<int, int>:: iterator q = tails[i].upper_bound(node);
  777. if(p != tails[i].end()){ // found a match
  778. while(p != q) {
  779. destination.insert(pair<int, int>(node, p->second) );
  780. p++;
  781. }
  782. // now can discard it
  783. tails[i].clear();
  784. }
  785. }
  786. return;
  787. }
  788. //--------------------------------------------------------------------------------
  789. bool find_in_heads(int node){
  790. // called from add_relations_for_leader()
  791. for(int i = 0; i < heads.size(); i++){
  792. multimap<int, int>:: iterator p = heads[i].find(node);
  793. if(p != heads[i].end()) return true;// found a match
  794. }
  795. return false;
  796. }
  797. //=======================================================================================
  798. void show_statistics(){
  799. /*
  800. cout<<"\n*** Statistics **************************************\n";
  801. cout<<"size of Event_producer = "<< sizeof(Event_producer)<<endl;
  802. cout<<"size of OR_node_producer_container = "<< sizeof(OR_node_producer_container)<<endl;
  803. cout<<"size of AND_node_producer_container = "<< sizeof(AND_node_producer_container)<<endl;
  804. cout<<"size of SET_node_producer_container = "<< sizeof(SET_node_producer_container)<<endl;
  805. cout<<"size of Composite_producer = "<< sizeof(Composite_producer)<<endl;
  806. cout<<"size of Composite_secondary_producer = "<< sizeof(Composite_secondary_producer)<<endl;
  807. cout<<"size of Coordinate = "<< sizeof(Coordinate)<<endl;
  808. cout<<" *** These are stored on the trace\n";
  809. cout<<"size of Atomic_producer = "<< sizeof(Atomic_producer)<<endl;
  810. cout<<"size of Composite_event_instance = "<< sizeof(Composite_event_instance)<<endl;
  811. */
  812. cout<<"\ntotal number of stored events= "<< total_events;
  813. cout<< "\nmemory of composite storage= "<< storage << " bytes/ "<<
  814. (double)storage /1024<< "KB/ "<< (double)storage /1024/1024<< "MB (JEDEC binary definition)"<<endl;
  815. //gen_end = clock();
  816. dif = double(gen_end - gen_start) / CLOCKS_PER_SEC;
  817. cout<<"Elapsed time "<< dif<<" sec, Speed: "<< total_events/dif <<" events/sec\n"<<endl;
  818. }