View Javadoc

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   * &#064;Bench(runs=3) public bench1(){ .. }<br/>
44   * &#064;Bench(runs=2) public bench2(){ .. }<br/>
45   * &#064;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 }