EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.reliability.solver.compare]

COVERAGE SUMMARY FOR SOURCE FILE [MarkovComparator.java]

nameclass, %method, %block, %line, %
MarkovComparator.java0%   (0/1)0%   (0/21)0%   (0/1335)0%   (0/246)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MarkovComparator0%   (0/1)0%   (0/21)0%   (0/1335)0%   (0/246)
<static initializer> 0%   (0/1)0%   (0/5)0%   (0/3)
MarkovComparator (): void 0%   (0/1)0%   (0/36)0%   (0/12)
compare (MarkovChain, MarkovChain): void 0%   (0/1)0%   (0/43)0%   (0/12)
compare (String, String): void 0%   (0/1)0%   (0/38)0%   (0/9)
compareProperties (MarkovChain, MarkovChain): void 0%   (0/1)0%   (0/24)0%   (0/4)
compareProperties (State, State): void 0%   (0/1)0%   (0/85)0%   (0/16)
compareProperties (Transition, Transition): void 0%   (0/1)0%   (0/71)0%   (0/13)
compareStates (EList, EList): void 0%   (0/1)0%   (0/107)0%   (0/24)
compareTransitions (EList, EList): void 0%   (0/1)0%   (0/107)0%   (0/24)
getDecimalFormat (ArrayList): DecimalFormat 0%   (0/1)0%   (0/45)0%   (0/9)
increaseDeletedStateCount (): void 0%   (0/1)0%   (0/19)0%   (0/4)
increaseDeletedTransitionCount (): void 0%   (0/1)0%   (0/19)0%   (0/4)
increaseNewStateCount (): void 0%   (0/1)0%   (0/19)0%   (0/4)
increaseNewTransitionCount (): void 0%   (0/1)0%   (0/19)0%   (0/4)
increaseStatePropertyChangeCount (): void 0%   (0/1)0%   (0/19)0%   (0/4)
increaseTransitionPropertyChangeCount (): void 0%   (0/1)0%   (0/19)0%   (0/4)
printCompareStatistics (MarkovChain, MarkovChain): void 0%   (0/1)0%   (0/530)0%   (0/72)
searchLabelsForKey (EList, String): Label 0%   (0/1)0%   (0/20)0%   (0/4)
testEquality (EList, EList): boolean 0%   (0/1)0%   (0/59)0%   (0/13)
testIdentity (State, State): boolean 0%   (0/1)0%   (0/33)0%   (0/6)
testIdentity (Transition, Transition): boolean 0%   (0/1)0%   (0/18)0%   (0/2)

1package de.uka.ipd.sdq.reliability.solver.compare;
2 
3import java.io.File;
4import java.text.DecimalFormat;
5import java.util.ArrayList;
6import java.util.List;
7 
8import org.apache.log4j.Logger;
9import org.eclipse.emf.common.util.EList;
10import org.eclipse.emf.ecore.EObject;
11 
12import de.uka.ipd.sdq.markov.Label;
13import de.uka.ipd.sdq.markov.MarkovChain;
14import de.uka.ipd.sdq.markov.State;
15import de.uka.ipd.sdq.markov.Transition;
16import de.uka.ipd.sdq.reliability.core.helper.EMFHelper;
17 
18/**
19 * Provides functionality to compare two Markov models.
20 * 
21 * The comparison is based on the tracing information which uniquely identifies
22 * each Markov state.
23 * 
24 * @author brosch
25 * 
26 */
27public class MarkovComparator {
28 
29        /**
30         * A logger for printing the comparison result.
31         */
32        private static Logger logger = Logger.getLogger(MarkovComparator.class
33                        .getName());
34 
35        /**
36         * Counts the overall number of changes in chains #1 and #2.
37         */
38        private long changeCount = 0;
39 
40        /**
41         * Counts the number of deleted states in chain #1.
42         */
43        private int deletedStateCount = 0;
44 
45        /**
46         * Counts the number of deleted transitions in chain #1.
47         */
48        private int deletedTransitionCount = 0;
49 
50        /**
51         * The name of the first Markov chain.
52         */
53        private String firstName = "";
54 
55        /**
56         * Counts the number of newly introduced states in chain #2.
57         */
58        private int newStateCount = 0;
59 
60        /**
61         * Counts the number of newly introduced transitions in chain #2.
62         */
63        private int newTransitionCount = 0;
64 
65        /**
66         * The name of the second Markov chain.
67         */
68        private String secondName = "";
69 
70        /**
71         * Counts the overall number of state changes in chains #1 and #2.
72         */
73        private long stateChangeCount = 0;
74 
75        /**
76         * Counts the number of states with changed properties in chains #1 and #2.
77         */
78        private int statePropertyChangeCount = 0;
79 
80        /**
81         * Counts the overall number of transition changes in chains #1 and #2.
82         */
83        private long transitionChangeCount = 0;
84 
85        /**
86         * Counts the number of transitions with changed properties in chains #1 and
87         * #2.
88         */
89        private int transitionPropertyChangeCount = 0;
90 
91        /**
92         * Compares two Markov chains.
93         * 
94         * @param firstChain
95         *            the first chain
96         * @param secondChain
97         *            the second chain
98         */
99        public void compare(final MarkovChain firstChain,
100                        final MarkovChain secondChain) {
101                logger.info("Start Markov compare");
102                if (firstName == "") {
103                        firstName = firstChain.getName();
104                }
105                if (secondName == "") {
106                        secondName = secondChain.getName();
107                }
108                compareProperties(firstChain, secondChain);
109                compareStates(firstChain.getStates(), secondChain.getStates());
110                compareTransitions(firstChain.getTransitions(), secondChain
111                                .getTransitions());
112                printCompareStatistics(firstChain, secondChain);
113                logger.info("End Markov compare");
114        }
115 
116        /**
117         * Loads and compares the Markov models identified by the two given file
118         * names.
119         * 
120         * The files must exist and contain valid Markov models.
121         * 
122         * @param firstMarkovFileName
123         *            the file name of the first Markov model
124         * @param secondMarkovFileName
125         *            the file name of the second Markov model
126         */
127        public void compare(final String firstMarkovFileName,
128                        final String secondMarkovFileName) {
129                firstName = new File(firstMarkovFileName).getName();
130                secondName = new File(secondMarkovFileName).getName();
131                EObject ch1 = EMFHelper.loadFromXMIFile(firstMarkovFileName);
132                EObject ch2 = EMFHelper.loadFromXMIFile(secondMarkovFileName);
133                if ((ch1 == null) || !(ch1 instanceof MarkovChain) || (ch2 == null)
134                                || !(ch2 instanceof MarkovChain)) {
135                        return;
136                }
137                compare((MarkovChain) ch1, (MarkovChain) ch2);
138        }
139 
140        /**
141         * Compares the general properties of two Markov chains.
142         * 
143         * @param ch1
144         *            the first chain
145         * @param ch2
146         *            the second chain
147         */
148        private void compareProperties(final MarkovChain ch1, final MarkovChain ch2) {
149                if (!ch1.getName().equals(ch2.getName())) {
150                        logger.debug("Chain name changed from \"" + ch1.getName()
151                                        + "\" to \"" + ch2.getName() + "\"");
152                }
153        }
154 
155        /**
156         * Compares the properties of two Markov states.
157         * 
158         * The states are assumed to have the same identity.
159         * 
160         * @param st1
161         *            the first state
162         * @param st2
163         *            the second state
164         */
165        private void compareProperties(final State st1, final State st2) {
166 
167                boolean typeEquals = st1.getType().equals(st2.getType());
168                boolean nameEquals = st1.getName().equals(st2.getName());
169                boolean labelsEqual = testEquality(st1.getLabels(), st2.getLabels());
170 
171                if (!typeEquals || !nameEquals || !labelsEqual) {
172                        logger.debug("State \"" + st1.getName() + "\" changed:");
173                        increaseStatePropertyChangeCount();
174                        if (!nameEquals) {
175                                logger.debug("- mame changed from \"" + st1.getName()
176                                                + "\" to \"" + st2.getName() + "\"");
177                        }
178                        if (!typeEquals) {
179                                logger.debug("- type changed from \""
180                                                + st1.getType().toString() + "\" to \""
181                                                + st2.getType().toString() + "\"");
182                        }
183                        if (!labelsEqual) {
184                                logger.debug("- labels changed");
185                        }
186                }
187        }
188 
189        /**
190         * Compares the transitions of two Markov chains.
191         * 
192         * @param tr1
193         *            the transitions of the first chain
194         * @param tr2
195         *            the transitions of the second chain
196         */
197        private void compareProperties(final Transition tr1, final Transition tr2) {
198 
199                boolean nameEquals = tr1.getName().equals(tr2.getName());
200                boolean probabilityEquals = (tr1.getProbability() == tr2
201                                .getProbability());
202 
203                if (!nameEquals || !probabilityEquals) {
204                        logger.debug("Transition \"" + tr1.getName() + "\" changed:");
205                        increaseTransitionPropertyChangeCount();
206                        if (!nameEquals) {
207                                logger.debug("- mame changed from \"" + tr1.getName()
208                                                + "\" to \"" + tr2.getName() + "\"");
209                        }
210                        if (!probabilityEquals) {
211                                logger.debug("- probability changed from "
212                                                + tr1.getProbability() + " to " + tr2.getProbability());
213                        }
214                }
215        }
216 
217        /**
218         * Compares the states of two Markov chains.
219         * 
220         * @param states1
221         *            the states of the first chain
222         * @param states2
223         *            the states of the second chain
224         */
225        private void compareStates(final EList<State> states1,
226                        final EList<State> states2) {
227 
228                // Create private copies of the lists:
229                List<State> statesCopy1 = new ArrayList<State>();
230                statesCopy1.addAll(states1);
231                List<State> statesCopy2 = new ArrayList<State>();
232                statesCopy2.addAll(states2);
233 
234                // Iterate over the states of the first chain:
235                while (statesCopy1.size() > 0) {
236 
237                        // Retrieve the first state:
238                        State st1 = statesCopy1.get(0);
239 
240                        // Search for an identical state in the second chain:
241                        State st2 = null;
242                        for (State st2_candidate : statesCopy2) {
243                                if (testIdentity(st1, st2_candidate)) {
244                                        st2 = st2_candidate;
245                                        break;
246                                }
247                        }
248 
249                        // Check if an identical state exists:
250                        if (st2 != null) {
251 
252                                // check for changed state properties:
253                                compareProperties(st1, st2);
254 
255                                // delete the states:
256                                statesCopy1.remove(st1);
257                                statesCopy2.remove(st2);
258 
259                        } else {
260 
261                                // st1 does not longer exist:
262                                logger.debug("State \"" + st1.getName() + "\" deleted");
263                                increaseDeletedStateCount();
264 
265                                // delete the state:
266                                statesCopy1.remove(st1);
267                        }
268                }
269 
270                // Iterate over the states of the second chain:
271                while (statesCopy2.size() > 0) {
272 
273                        // Retrieve the first state:
274                        State st2 = statesCopy2.get(0);
275 
276                        // st2 is a new state:
277                        logger.debug("State \"" + st2.getName() + "\" added");
278                        increaseNewStateCount();
279 
280                        // delete the state:
281                        statesCopy2.remove(st2);
282                }
283        }
284 
285        /**
286         * Compares the transitions of two Markov chains.
287         * 
288         * @param transitions1
289         *            the transitions of the first chain
290         * @param transitions2
291         *            the transitions of the second chain
292         */
293        private void compareTransitions(final EList<Transition> transitions1,
294                        final EList<Transition> transitions2) {
295 
296                // Create private copies of the lists:
297                List<Transition> transitionsCopy1 = new ArrayList<Transition>();
298                transitionsCopy1.addAll(transitions1);
299                List<Transition> transitionsCopy2 = new ArrayList<Transition>();
300                transitionsCopy2.addAll(transitions2);
301 
302                // Iterate over the transitions of the first chain:
303                while (transitionsCopy1.size() > 0) {
304 
305                        // Retrieve the first transition:
306                        Transition tr1 = transitionsCopy1.get(0);
307 
308                        // Search for an identical transition in the second chain:
309                        Transition tr2 = null;
310                        for (Transition tr2_candidate : transitionsCopy2) {
311                                if (testIdentity(tr1, tr2_candidate)) {
312                                        tr2 = tr2_candidate;
313                                        break;
314                                }
315                        }
316 
317                        // Check if an identical transition exists:
318                        if (tr2 != null) {
319 
320                                // check for changed state properties:
321                                compareProperties(tr1, tr2);
322 
323                                // delete the states:
324                                transitionsCopy1.remove(tr1);
325                                transitionsCopy2.remove(tr2);
326 
327                        } else {
328 
329                                // tr1 does not longer exist:
330                                logger.debug("Transition \"" + tr1.getName() + "\" deleted");
331                                increaseDeletedTransitionCount();
332 
333                                // delete the state:
334                                transitionsCopy1.remove(tr1);
335                        }
336                }
337 
338                // Iterate over the transitions of the second chain:
339                while (transitionsCopy2.size() > 0) {
340 
341                        // Retrieve the first transition:
342                        Transition tr2 = transitionsCopy2.get(0);
343 
344                        // tr2 is a new transition:
345                        logger.debug("Transition \"" + tr2.getName() + "\" added");
346                        increaseNewTransitionCount();
347 
348                        // delete the state:
349                        transitionsCopy2.remove(tr2);
350                }
351        }
352 
353        /**
354         * Creates a decimal format based on the given numbers.
355         * 
356         * @param numbers
357         *            the list of numbers
358         * @return the resulting decimal format
359         */
360        private DecimalFormat getDecimalFormat(final ArrayList<Integer> numbers) {
361 
362                // Search for the maximal number of decimal places:
363                int maxPlaces = 0;
364                for (Integer number : numbers) {
365                        int places = number.toString().length();
366                        if (places > maxPlaces) {
367                                maxPlaces = places;
368                        }
369                }
370 
371                // Generate a format string corresponding to the places:
372                String formatString = "";
373                for (int i = 0; i < maxPlaces; i++) {
374                        formatString += "0";
375                }
376                return new DecimalFormat(formatString);
377        }
378 
379        /**
380         * Increases the deleted state count.
381         */
382        private void increaseDeletedStateCount() {
383                changeCount++;
384                stateChangeCount++;
385                deletedStateCount++;
386        }
387 
388        /**
389         * Increases the deleted transition count.
390         */
391        private void increaseDeletedTransitionCount() {
392                changeCount++;
393                transitionChangeCount++;
394                deletedTransitionCount++;
395        }
396 
397        /**
398         * Increases the new state count.
399         */
400        private void increaseNewStateCount() {
401                changeCount++;
402                stateChangeCount++;
403                newStateCount++;
404        }
405 
406        /**
407         * Increases the new transition count.
408         */
409        private void increaseNewTransitionCount() {
410                changeCount++;
411                transitionChangeCount++;
412                newTransitionCount++;
413        }
414 
415        /**
416         * Increases the changed state property count.
417         */
418        private void increaseStatePropertyChangeCount() {
419                changeCount++;
420                stateChangeCount++;
421                statePropertyChangeCount++;
422        }
423 
424        /**
425         * Increases the deleted transition count.
426         */
427        private void increaseTransitionPropertyChangeCount() {
428                changeCount++;
429                transitionChangeCount++;
430                transitionPropertyChangeCount++;
431        }
432 
433        /**
434         * Prints the statistics of the compare operation.
435         * 
436         * @param secondChain
437         *            the first Markov chain
438         * @param firstChain
439         *            the second Markov chain
440         */
441        private void printCompareStatistics(final MarkovChain firstChain,
442                        final MarkovChain secondChain) {
443 
444                // Assume that the chains are not so big that Integer.MAX_VALUE is
445                // reached:
446                int numberOfStates1 = firstChain.getStates().size();
447                int numberOfStates2 = secondChain.getStates().size();
448                int numberOfTransitions1 = firstChain.getTransitions().size();
449                int numberOfTransitions2 = secondChain.getTransitions().size();
450 
451                // Collect state statistics:
452                int numberOfChangedStates1 = statePropertyChangeCount;
453                int numberOfDeletedStates1 = deletedStateCount;
454                int numberOfUnchangedStates1 = numberOfStates1 - numberOfChangedStates1
455                                - numberOfDeletedStates1;
456                int numberOfChangedStates2 = statePropertyChangeCount;
457                int numberOfAddedStates2 = newStateCount;
458                int numberOfUnchangedStates2 = numberOfStates2 - numberOfChangedStates2
459                                - numberOfAddedStates2;
460 
461                // Collect transition statistics:
462                int numberOfChangedTransitions1 = transitionPropertyChangeCount;
463                int numberOfDeletedTransitions1 = deletedTransitionCount;
464                int numberOfUnchangedTransitions1 = numberOfTransitions1
465                                - numberOfChangedTransitions1 - numberOfDeletedTransitions1;
466                int numberOfChangedTransitions2 = transitionPropertyChangeCount;
467                int numberOfAddedTransitions2 = newTransitionCount;
468                int numberOfUnchangedTransitions2 = numberOfTransitions2
469                                - numberOfChangedTransitions2 - numberOfAddedTransitions2;
470 
471                // Collect percentages:
472                double percentageOfChangedStates1 = 100.0 * ((double) numberOfChangedStates1 / (double) numberOfStates1);
473                double percentageOfDeletedStates1 = 100.0 * ((double) numberOfDeletedStates1 / (double) numberOfStates1);
474                double percentageOfUnchangedStates1 = 100.0 * ((double) numberOfUnchangedStates1 / (double) numberOfStates1);
475                double percentageOfChangedTransitions1 = 100.0 * ((double) numberOfChangedTransitions1 / (double) numberOfTransitions1);
476                double percentageOfDeletedTransitions1 = 100.0 * ((double) numberOfDeletedTransitions1 / (double) numberOfTransitions1);
477                double percentageOfUnchangedTransitions1 = 100.0 * ((double) numberOfUnchangedTransitions1 / (double) numberOfTransitions1);
478                double percentageOfChangedStates2 = 100.0 * ((double) numberOfChangedStates2 / (double) numberOfStates2);
479                double percentageOfAddedStates2 = 100.0 * ((double) numberOfAddedStates2 / (double) numberOfStates2);
480                double percentageOfUnchangedStates2 = 100.0 * ((double) numberOfUnchangedStates2 / (double) numberOfStates2);
481                double percentageOfChangedTransitions2 = 100.0 * ((double) numberOfChangedTransitions2 / (double) numberOfTransitions2);
482                double percentageOfAddedTransitions2 = 100.0 * ((double) numberOfAddedTransitions2 / (double) numberOfTransitions2);
483                double percentageOfUnchangedTransitions2 = 100.0 * ((double) numberOfUnchangedTransitions2 / (double) numberOfTransitions2);
484 
485                // Derive string formats:
486                ArrayList<Integer> numbers = new ArrayList<Integer>();
487                numbers.add(numberOfStates1);
488                numbers.add(numberOfStates2);
489                numbers.add(numberOfTransitions1);
490                numbers.add(numberOfTransitions2);
491                DecimalFormat df1 = getDecimalFormat(numbers);
492                DecimalFormat df2 = new DecimalFormat("00.00");
493 
494                // Print statistics:
495                logger.info("States chain 1 [" + firstName + "]:");
496                logger.info("- total:     " + df1.format(numberOfStates1));
497                logger.info("- changed:   " + df1.format(numberOfChangedStates1) + " ("
498                                + df2.format(percentageOfChangedStates1) + "%)");
499                logger.info("- deleted:   " + df1.format(numberOfDeletedStates1) + " ("
500                                + df2.format(percentageOfDeletedStates1) + "%)");
501                logger.info("- unchanged: " + df1.format(numberOfUnchangedStates1)
502                                + " (" + df2.format(percentageOfUnchangedStates1) + "%)");
503                logger.info("Transitions chain 1 [" + firstName + "]:");
504                logger.info("- total:     " + df1.format(numberOfTransitions1));
505                logger.info("- changed:   " + df1.format(numberOfChangedTransitions1)
506                                + " (" + df2.format(percentageOfChangedTransitions1) + "%)");
507                logger.info("- deleted:   " + df1.format(numberOfDeletedTransitions1)
508                                + " (" + df2.format(percentageOfDeletedTransitions1) + "%)");
509                logger.info("- unchanged: " + df1.format(numberOfUnchangedTransitions1)
510                                + " (" + df2.format(percentageOfUnchangedTransitions1) + "%)");
511                logger.info("States chain 2 [" + secondName + "]:");
512                logger.info("- total:     " + df1.format(numberOfStates2));
513                logger.info("- changed:   " + df1.format(numberOfChangedStates2) + " ("
514                                + df2.format(percentageOfChangedStates2) + "%)");
515                logger.info("- added:     " + df1.format(numberOfAddedStates2) + " ("
516                                + df2.format(percentageOfAddedStates2) + "%)");
517                logger.info("- unchanged: " + df1.format(numberOfUnchangedStates2)
518                                + " (" + df2.format(percentageOfUnchangedStates2) + "%)");
519                logger.info("Transitions chain 2 [" + secondName + "]:");
520                logger.info("- total:     " + df1.format(numberOfTransitions2));
521                logger.info("- changed:   " + df1.format(numberOfChangedTransitions2)
522                                + " (" + df2.format(percentageOfChangedTransitions2) + "%)");
523                logger.info("- added:     " + df1.format(numberOfAddedTransitions2)
524                                + " (" + df2.format(percentageOfAddedTransitions2) + "%)");
525                logger.info("- unchanged: " + df1.format(numberOfUnchangedTransitions2)
526                                + " (" + df2.format(percentageOfUnchangedTransitions2) + "%)");
527        }
528 
529        /**
530         * Searches a list of labels for a given key.
531         * 
532         * @param labels
533         *            the list of labels
534         * @param key
535         *            the key
536         * @return the label; NULL if no corresponding label has been found.
537         */
538        private Label searchLabelsForKey(final EList<Label> labels, final String key) {
539                for (Label label : labels) {
540                        if (label.getKey().equals(key)) {
541                                return label;
542                        }
543                }
544                return null;
545        }
546 
547        /**
548         * Checks if the labels of two Markov states are equal.
549         * 
550         * It is assumed that each key appears only once in each list of labels
551         * 
552         * @param labels1
553         *            the labels of the first state
554         * @param labels2
555         *            the labels of the second state
556         * @return
557         */
558        private boolean testEquality(final EList<Label> labels1,
559                        final EList<Label> labels2) {
560                if (labels1.size() != labels2.size()) {
561                        return false;
562                }
563                for (int i = 0; i < labels1.size(); i++) {
564                        Label label1 = labels1.get(i);
565                        Label label1_2 = searchLabelsForKey(labels2, label1.getKey());
566                        Label label2 = labels2.get(i);
567                        Label label2_1 = searchLabelsForKey(labels1, label2.getKey());
568                        if ((label1_2 == null) || (label2_1 == null)) {
569                                return false;
570                        }
571                        if (!label1.getValue().equals(label1_2.getValue())
572                                        || !label2.getValue().equals(label2_1.getValue())) {
573                                return false;
574                        }
575                }
576                return true;
577        }
578 
579        /**
580         * Checks two Markov States for having the same identity.
581         * 
582         * The identity is checked through the trace information.
583         * 
584         * @param st1
585         *            the first state
586         * @param st2
587         *            the second state
588         * @return true, if the states are identical; false otherwise
589         */
590        private boolean testIdentity(final State st1, final State st2) {
591                if (st1.getTraces().size() != st2.getTraces().size()) {
592                        return false;
593                }
594                for (int i = 0; i < st1.getTraces().size(); i++) {
595                        if (!st1.getTraces().get(i).equals(st2.getTraces().get(i))) {
596                                return false;
597                        }
598                }
599                return true;
600        }
601 
602        /**
603         * Checks two Markov Transitions for having the same identity.
604         * 
605         * The transitions are considered to have the same identity if they
606         * connected the same states.
607         * 
608         * @param t1
609         *            the first transition
610         * @param t2
611         *            the second transition
612         * @return true, if the transitions are identical; false otherwise
613         */
614        private boolean testIdentity(final Transition t1, final Transition t2) {
615                return testIdentity(t1.getFromState(), t2.getFromState())
616                                && testIdentity(t1.getToState(), t2.getToState());
617        }
618}

[all classes][de.uka.ipd.sdq.reliability.solver.compare]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov