MATSIM
EventsFileComparator.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * *
4  * *********************************************************************** *
5  * *
6  * copyright : (C) 2010 by the members listed in the COPYING, *
7  * LICENSE and WARRANTY file. *
8  * email : info at matsim dot org *
9  * *
10  * *********************************************************************** *
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * See also COPYING, LICENSE and WARRANTY file *
17  * *
18  * *********************************************************************** */
19 
20 package org.matsim.utils.eventsfilecomparison;
21 
22 import org.apache.logging.log4j.LogManager;
23 import org.apache.logging.log4j.Logger;
24 import org.matsim.core.gbl.Gbl;
25 
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.concurrent.CyclicBarrier;
29 
37 public final class EventsFileComparator {
38  private static final Logger log = LogManager.getLogger(EventsFileComparator.class);
39 
40  private boolean ignoringCoordinates = false;
41  public EventsFileComparator setIgnoringCoordinates( boolean ignoringCoordinates ){
42  this.ignoringCoordinates = ignoringCoordinates;
43  return this;
44  }
45 
46  public static void main(String[] args) {
47  if (args.length != 2) {
48  System.out.println("Error: expected 2 events files as input arguments but found " + args.length);
49  System.out.println("Syntax: EventsFileComparator eventsFile1 eventsFile2");
50  } else {
51  String filename1 = args[0];
52  String filename2 = args[1];
53 
54  EventsFileComparator.compare(filename1, filename2);
55  }
56  }
57 
65  public static ComparisonResult compare(final String filename1, final String filename2) {
66  return new EventsFileComparator().runComparison( filename1, filename2 );
67  }
68 
69  public ComparisonResult runComparison(final String filename1, final String filename2 ) {
70  // (need method name different from pre-existing static method. kai, feb'20)
71 
72  EventsComparator comparator = new EventsComparator( );
73  CyclicBarrier doComparison = new CyclicBarrier(2, comparator);
74  Worker w1 = new Worker(filename1, doComparison, ignoringCoordinates );
75  Worker w2 = new Worker(filename2, doComparison, ignoringCoordinates );
76  comparator.setWorkers(w1, w2);
77  w1.start();
78  w2.start();
79 
80  try {
81  w1.join();
82  } catch (InterruptedException e) {
83  e.printStackTrace();
84  }
85  try {
86  w2.join();
87  } catch (InterruptedException e) {
88  e.printStackTrace();
89  }
90 
91  ComparisonResult retCode = comparator.retCode;
92  if (retCode == ComparisonResult.FILES_ARE_EQUAL) {
93  log.info("Event files are semantically equivalent.");
94  } else {
95  log.warn("Event files differ.");
96  }
97  return retCode;
98  }
99 
100  private static class EventsComparator implements Runnable {
101 
102  private Worker worker1 = null;
103  private Worker worker2 = null;
104  private volatile ComparisonResult retCode = null ;
105 
106  /*package*/ void setWorkers(final Worker w1, final Worker w2) {
107  this.worker1 = w1;
108  this.worker2 = w2;
109  }
110 
111  @Override
112  public void run() {
113  if (this.worker1.getCurrentTime() != this.worker2.getCurrentTime()) {
114  log.warn("Differnt time steps in event files!");
116  return;
117  }
118 
119  if (this.worker1.isFinished() != this.worker2.isFinished()) {
120  log.warn("Events files have different number of time steps!");
122  return;
123  }
124 
125  Map<String, Counter> map1 = this.worker1.getEventsMap();
126  Map<String, Counter> map2 = this.worker2.getEventsMap();
127 
128  boolean problem = false ;
129 
130  int logCounter = 0;
131 
132  // check that map2 contains all keys of map1, with the same values
133  for (Entry<String, Counter> entry : map1.entrySet()) {
134 
135  Counter counter = map2.get(entry.getKey());
136  if (counter == null) {
137  if (logCounter < 50) {
138  logCounter++;
139  log.warn("The event:");
140  log.warn(entry.getKey());
141  log.warn("is missing in events file:" + worker2.getEventsFile());
143  problem = true;
144  if (logCounter == 50) {
145  log.warn(Gbl.FUTURE_SUPPRESSED);
146  }
147  }
148  } else{
149  if( counter.getCount() != entry.getValue().getCount() ){
150  log.warn(
151  "Wrong event count for: " + entry.getKey() + "\n" + entry.getValue().getCount() + " times in file:" + worker1.getEventsFile()
152  + "\n" + counter.getCount() + " times in file:" + worker2.getEventsFile() );
154  problem = true;
155  }
156  }
157  }
158 
159  logCounter = 0;
160  // also check that map1 contains all keys of map2
161  for (Entry<String, Counter> e : map2.entrySet()) {
162  Counter counter = map1.get(e.getKey());
163  if (counter == null) {
164  if (logCounter < 50) {
165  logCounter++;
166  log.warn("The event:");
167  log.warn(e.getKey());
168  log.warn("is missing in events file:" + worker1.getEventsFile());
170  problem = true;
171  if (logCounter == 50) {
172  log.warn(Gbl.FUTURE_SUPPRESSED);
173  }
174  }
175  }
176  }
177 
178  if ( problem ) {
179  return ;
180  }
181 
182  if (this.worker1.isFinished()) {
184  }
185  }
186 
187  private void setExitCode(final ComparisonResult errCode) {
188  this.retCode= errCode;
189  if (errCode != ComparisonResult.FILES_ARE_EQUAL) {
190  this.worker1.interrupt();
191  this.worker2.interrupt();
192  }
193  }
194  }
195 
200  @Deprecated
201  public enum Result {
202  }
203 
204 }
static final String FUTURE_SUPPRESSED
Definition: Gbl.java:44
static ComparisonResult compare(final String filename1, final String filename2)
EventsFileComparator setIgnoringCoordinates(boolean ignoringCoordinates)
ComparisonResult runComparison(final String filename1, final String filename2)