1 /**
2 * Copyright (c) 2012, University of Konstanz, Distributed Systems Group
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of Konstanz nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 package org.perfidix.element;
28
29 import java.util.ArrayList;
30 import java.util.Comparator;
31 import java.util.Hashtable;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Map.Entry;
35 import java.util.Set;
36 import java.util.TreeSet;
37
38 /**
39 * This class represents an arrangement where each method is executed after
40 * another. That means that <br/>
41 * <code>
42 *
43 * @Bench(runs=3) public bench1(){ .. }<br/>
44 * @Bench(runs=2) public bench2(){ .. }<br/>
45 * @Bench(runs=1) public bench3(){ .. }<br/> </code><br/>
46 * results in the following execution order:<br/>
47 * <code>
48 * bench1
49 * bench2
50 * bench3
51 * bench1
52 * bench2
53 * bench1
54 * </code>
55 */
56 public final class SequentialMethodArrangement extends AbstractMethodArrangement {
57
58 /**
59 * Simple Constructor-
60 *
61 * @param elements
62 */
63 protected SequentialMethodArrangement(final List<BenchmarkElement> elements) {
64 super(elements);
65 }
66
67 /** {@inheritDoc} */
68 @Override
69 protected List<BenchmarkElement> arrangeList(final List<BenchmarkElement> elements) {
70 final Map<BenchmarkMethod, ArrayList<BenchmarkElement>> table =
71 new Hashtable<BenchmarkMethod, ArrayList<BenchmarkElement>>();
72 final List<BenchmarkElement> returnVal = new ArrayList<BenchmarkElement>();
73
74 // Having a table
75 for (final BenchmarkElement elem : elements) {
76 if (!table.containsKey(elem.getMeth())) {
77 table.put(elem.getMeth(), new ArrayList<BenchmarkElement>());
78 }
79 table.get(elem.getMeth()).add(elem);
80 }
81
82 // Computing complete number of elements
83 int numberOfElements = 0;
84 for (final BenchmarkMethod meth : table.keySet()) {
85 numberOfElements = numberOfElements + table.get(meth).size();
86 }
87
88 // Defining order to execute, start with the one with the most elements
89 final Set<Entry<BenchmarkMethod, ArrayList<BenchmarkElement>>> compareMethods =
90 new TreeSet<Entry<BenchmarkMethod, ArrayList<BenchmarkElement>>>(new BenchmarkElementComparator());
91 for (final Entry<BenchmarkMethod, ArrayList<BenchmarkElement>> entry : table.entrySet()) {
92 compareMethods.add(entry);
93 }
94
95 final ArrayList<BenchmarkMethod> methods = new ArrayList<BenchmarkMethod>();
96 for (Entry<BenchmarkMethod, ArrayList<BenchmarkElement>> entry : compareMethods) {
97 methods.add(entry.getKey());
98 }
99
100 for (int i = 0; i < numberOfElements; i++) {
101 BenchmarkElement elem = null;
102 int indexPart = 0;
103 while (elem == null) {
104 final int index = (i + indexPart) % methods.size();
105 final BenchmarkMethod methodToInclude = methods.get(index);
106 if (table.containsKey(methodToInclude)) {
107 elem = table.get(methodToInclude).remove(0);
108 if (table.get(methodToInclude).size() == 0) {
109 table.remove(methodToInclude);
110 }
111 }
112 indexPart++;
113 }
114 returnVal.add(elem);
115 }
116 return returnVal;
117 }
118
119 /**
120 * Comparator to compare the different entries according to the size of the
121 * underlaying arraylist
122 *
123 * @author Sebastian Graf, University of Konstanz
124 */
125 class BenchmarkElementComparator implements
126 Comparator<Entry<BenchmarkMethod, ArrayList<BenchmarkElement>>> {
127
128 /** {@inheritDoc} */
129 public int compare(final Entry<BenchmarkMethod, ArrayList<BenchmarkElement>> object1,
130 final Entry<BenchmarkMethod, ArrayList<BenchmarkElement>> object2) {
131 int returnVal = 0;
132 if (object1.getValue().size() > object2.getValue().size()) {
133 returnVal = -1;
134 } else {
135 returnVal = 1;
136 }
137 return returnVal;
138 }
139
140 }
141
142 }